1 module socks5d.server;
2 
3 import socks5d.client;
4 import std.socket;
5 import std.experimental.logger;
6 
7 class Server
8 {
9     private:
10         string address;
11         ushort port;
12         string authString;
13         int backlog;
14         Socket socket;
15         Client[] clients;
16         uint clientCounter = 0;
17 
18     public:
19         this(string address, ushort port = 1080, int backlog = 10)
20         {
21             this.address = address;
22             this.port = port;
23             this.backlog = backlog;
24         }
25 
26         void setAuthString(string authString)
27         {
28             this.authString = authString;
29             if (authString.length > 1) {
30                 warningf("Using authentication string: %s", authString);
31             }
32         }
33 
34         final void run()
35         {
36             bindSocket();
37 
38             while (true) {
39                 acceptClient();
40             }
41         }
42 
43     protected:
44         void bindSocket()
45         {
46 
47             socket = new TcpSocket;
48             assert(socket.isAlive);
49             socket.bind(new InternetAddress(address, port));
50             socket.listen(backlog);
51 
52             criticalf("Listening on %s", socket.localAddress().toString());
53         }
54 
55         void acceptClient()
56         {
57             import core.thread : Thread;
58 
59             auto clientSocket = socket.accept();
60             assert(clientSocket.isAlive);
61             assert(socket.isAlive);
62 
63             clientCounter++;
64             new Thread({
65                 auto client = new Client(clientSocket, clientCounter);
66                 client.setAuthString(authString);
67                 clients ~= client;
68                 client.run();
69             }).start();
70         }
71 }