-
Notifications
You must be signed in to change notification settings - Fork 0
/
ForwardServerClientThread.java
162 lines (142 loc) · 6.33 KB
/
ForwardServerClientThread.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/**
* ForwardServerClientThread handles the clients of Nakov Forward Server. It
* connects two sockets and starts the TCP forwarding between given client
* and its assigned server. After the forwarding is failed and the two threads
* are stopped, closes the sockets.
*
*/
/**
* Modifications for IK2206:
* - Server pool removed
* - Two variants - client connects to listening socket or client is already connected
*
* Peter Sjodin, KTH
*/
import java.net.InetAddress;
import java.net.Socket;
import java.net.ServerSocket;
import java.net.SocketException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.CipherInputStream;
public class ForwardServerClientThread extends Thread
{
private ForwardClient mForwardClient = null;
private Socket mClientSocket = null;
private Socket mServerSocket = null;
private ServerSocket mListenSocket = null;
private boolean mBothConnectionsAreAlive = false;
private String mClientHostPort;
private String mServerHostPort;
private int mServerPort;
private String mServerHost;
private SessionEncrypter sessionEncrypter;
private SessionDecrypter sessionDecrypter;
private String flag;
/**
* Creates a client thread for handling clients of NakovForwardServer.
* A client socket should be connected and passed to this constructor.
* A server socket is created later by run() method.
*/
public ForwardServerClientThread(Socket aClientSocket, String serverhost, int serverport, byte[] sessionKey, byte[] sessionIV)
{
flag = "Client";
mClientSocket = aClientSocket;
mServerPort = serverport;
mServerHost = serverhost;
sessionEncrypter = new SessionEncrypter(sessionKey, sessionIV);
sessionDecrypter = new SessionDecrypter(sessionKey, sessionIV);
}
/**
* Creates a client thread for handling clients of NakovForwardServer.
* Wait for client to connect on client listening socket.
* A server socket is created later by run() method.
*/
public ForwardServerClientThread(ServerSocket listensocket, String serverhost, int serverport, byte[] sessionKey, byte[] sessionIV) throws IOException
{
flag = "Server";
mListenSocket = listensocket;
//mServerHost = listensocket.getInetAddress().getHostAddress();
mServerPort = serverport;
mServerHost = serverhost;
sessionEncrypter = new SessionEncrypter(sessionKey, sessionIV);
sessionDecrypter = new SessionDecrypter(sessionKey, sessionIV);
}
public ServerSocket getListenSocket() {
return mListenSocket;
}
/**
* Obtains a destination server socket to some of the servers in the list.
* Starts two threads for forwarding : "client in <--> dest server out" and
* "dest server in <--> client out", waits until one of these threads stop
* due to read/write failure or connection closure. Closes opened connections.
*
* If there is a listen socket, first wait for incoming connection
* on the listen socket.
*/
public void run()
{
try {
// Wait for incoming connection on listen socket, if there is one
if (mListenSocket != null) {
mClientSocket = mListenSocket.accept();
mClientHostPort = mClientSocket.getInetAddress().getHostAddress() + ":" + mClientSocket.getPort();
Logger.log("Accepted from " + mServerPort + " <--> " + mClientHostPort + " started.");
}
else {
mClientHostPort = mClientSocket.getInetAddress().getHostAddress() + ":" + mClientSocket.getPort();
}
try {
mServerSocket = new Socket(mServerHost, mServerPort);
} catch (Exception e) {
System.out.println("Connection failed to " + mServerHost + ":" + mServerPort);
e.printStackTrace();
// Prints what exception has been thrown
System.out.println(e);
}
// Obtain input and output streams of server and client
InputStream clientIn = mClientSocket.getInputStream();
OutputStream clientOut = mClientSocket.getOutputStream();
InputStream serverIn = mServerSocket.getInputStream();
OutputStream serverOut = mServerSocket.getOutputStream();
if(flag.equals("Client")){
clientIn = sessionDecrypter.openCipherInputStream(clientIn);
clientOut = sessionEncrypter.openCipherOutputStream(clientOut);
}
else{
serverIn = sessionDecrypter.openCipherInputStream(serverIn);
serverOut = sessionEncrypter.openCipherOutputStream(serverOut);
}
mServerHostPort = mServerHost + ":" + mServerPort;
Logger.log("TCP Forwarding " + mClientHostPort + " <--> " + mServerHostPort + " started.");
// Start forwarding of socket data between server and client
ForwardThread clientForward = new ForwardThread(this, clientIn, serverOut);
ForwardThread serverForward = new ForwardThread(this, serverIn, clientOut);
mBothConnectionsAreAlive = true;
clientForward.start();
serverForward.start();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* connectionBroken() method is called by forwarding child threads to notify
* this thread (their parent thread) that one of the connections (server or client)
* is broken (a read/write failure occured). This method disconnects both server
* and client sockets causing both threads to stop forwarding.
*/
public synchronized void connectionBroken()
{
if (mBothConnectionsAreAlive) {
// One of the connections is broken. Close the other connection and stop forwarding
// Closing these socket connections will close their input/output streams
// and that way will stop the threads that read from these streams
try { mServerSocket.close(); } catch (IOException e) {}
try { mClientSocket.close(); } catch (IOException e) {}
mBothConnectionsAreAlive = false;
Logger.log("TCP Forwarding " + mClientHostPort + " <--> " + mServerHostPort + " stopped.");
}
}
}