Mercurial > 510Connectbot
comparison src/net/sourceforge/jsocks/UDPRelayServer.java @ 349:205ee2873330
update jsocks to 2011-03-19
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Fri, 01 Aug 2014 11:23:10 -0700 |
parents | 0ce5cc452d02 |
children |
comparison
equal
deleted
inserted
replaced
348:29076621bab0 | 349:205ee2873330 |
---|---|
4 import java.io.*; | 4 import java.io.*; |
5 | 5 |
6 /** | 6 /** |
7 UDP Relay server, used by ProxyServer to perform udp forwarding. | 7 UDP Relay server, used by ProxyServer to perform udp forwarding. |
8 */ | 8 */ |
9 class UDPRelayServer implements Runnable { | 9 class UDPRelayServer implements Runnable{ |
10 | 10 |
11 | 11 |
12 DatagramSocket client_sock; | 12 DatagramSocket client_sock; |
13 DatagramSocket remote_sock; | 13 DatagramSocket remote_sock; |
14 | 14 |
15 Socket controlConnection; | 15 Socket controlConnection; |
16 | 16 |
17 int relayPort; | 17 int relayPort; |
18 InetAddress relayIP; | 18 InetAddress relayIP; |
19 | 19 |
20 Thread pipe_thread1, pipe_thread2; | 20 Thread pipe_thread1,pipe_thread2; |
21 Thread master_thread; | 21 Thread master_thread; |
22 | 22 |
23 ServerAuthenticator auth; | 23 ServerAuthenticator auth; |
24 | 24 |
25 long lastReadTime; | 25 long lastReadTime; |
26 | 26 |
27 static PrintStream log = null; | 27 static PrintStream log = null; |
28 static Proxy proxy = null; | 28 static CProxy proxy = null; |
29 static int datagramSize = 0xFFFF;//64K, a bit more than max udp size | 29 static int datagramSize = 0xFFFF;//64K, a bit more than max udp size |
30 static int iddleTimeout = 180000;//3 minutes | 30 static int iddleTimeout = 180000;//3 minutes |
31 | 31 |
32 | 32 |
33 /** | 33 /** |
41 @param controlConnection Socket which will be closed, before | 41 @param controlConnection Socket which will be closed, before |
42 interrupting the master thread, it is introduced due to a bug | 42 interrupting the master thread, it is introduced due to a bug |
43 in windows JVM which does not throw InterruptedIOException in | 43 in windows JVM which does not throw InterruptedIOException in |
44 threads which block in I/O operation. | 44 threads which block in I/O operation. |
45 */ | 45 */ |
46 public UDPRelayServer(InetAddress clientIP, int clientPort, | 46 public UDPRelayServer(InetAddress clientIP,int clientPort, |
47 Thread master_thread, | 47 Thread master_thread, |
48 Socket controlConnection, | 48 Socket controlConnection, |
49 ServerAuthenticator auth) | 49 ServerAuthenticator auth) |
50 throws IOException { | 50 throws IOException{ |
51 this.master_thread = master_thread; | 51 this.master_thread = master_thread; |
52 this.controlConnection = controlConnection; | 52 this.controlConnection = controlConnection; |
53 this.auth = auth; | 53 this.auth = auth; |
54 client_sock = new Socks5DatagramSocket(true, auth.getUdpEncapsulation(), | 54 |
55 clientIP, clientPort); | 55 client_sock = new Socks5DatagramSocket(true,auth.getUdpEncapsulation(), |
56 relayPort = client_sock.getLocalPort(); | 56 clientIP,clientPort); |
57 relayIP = client_sock.getLocalAddress(); | 57 relayPort = client_sock.getLocalPort(); |
58 | 58 relayIP = client_sock.getLocalAddress(); |
59 if (relayIP.getHostAddress().equals("0.0.0.0")) | 59 |
60 relayIP = InetAddress.getLocalHost(); | 60 if(relayIP.getHostAddress().equals("0.0.0.0")) |
61 | 61 relayIP = InetAddress.getLocalHost(); |
62 if (proxy == null) | 62 |
63 remote_sock = new DatagramSocket(); | 63 if(proxy == null) |
64 else | 64 remote_sock = new DatagramSocket(); |
65 remote_sock = new Socks5DatagramSocket(proxy, 0, null); | 65 else |
66 remote_sock = new Socks5DatagramSocket(proxy,0,null); | |
66 } | 67 } |
67 | 68 |
68 | 69 |
69 //Public methods | 70 //Public methods |
70 ///////////////// | 71 ///////////////// |
71 | 72 |
72 | 73 |
73 /** | 74 /** |
74 Sets the timeout for UDPRelay server.<br> | 75 Sets the timeout for UDPRelay server.<br> |
75 Zero timeout implies infinity.<br> | 76 Zero timeout implies infinity.<br> |
76 Default timeout is 3 minutes. | 77 Default timeout is 3 minutes. |
77 */ | 78 */ |
78 | 79 |
79 static public void setTimeout(int timeout) { | 80 static public void setTimeout(int timeout){ |
80 iddleTimeout = timeout; | 81 iddleTimeout = timeout; |
81 } | 82 } |
82 | 83 |
83 | 84 |
84 /** | 85 /** |
85 Sets the size of the datagrams used in the UDPRelayServer.<br> | 86 Sets the size of the datagrams used in the UDPRelayServer.<br> |
86 Default size is 64K, a bit more than maximum possible size of the | 87 Default size is 64K, a bit more than maximum possible size of the |
87 datagram. | 88 datagram. |
88 */ | 89 */ |
89 static public void setDatagramSize(int size) { | 90 static public void setDatagramSize(int size){ |
90 datagramSize = size; | 91 datagramSize = size; |
91 } | 92 } |
92 | 93 |
93 /** | 94 /** |
94 Port to which client should send datagram for association. | 95 Port to which client should send datagram for association. |
95 */ | 96 */ |
96 public int getRelayPort() { | 97 public int getRelayPort(){ |
97 return relayPort; | 98 return relayPort; |
98 } | 99 } |
99 /** | 100 /** |
100 IP address to which client should send datagrams for association. | 101 IP address to which client should send datagrams for association. |
101 */ | 102 */ |
102 public InetAddress getRelayIP() { | 103 public InetAddress getRelayIP(){ |
103 return relayIP; | 104 return relayIP; |
104 } | 105 } |
105 | 106 |
106 /** | 107 /** |
107 Starts udp relay server. | 108 Starts udp relay server. |
108 Spawns two threads of execution and returns. | 109 Spawns two threads of execution and returns. |
109 */ | 110 */ |
110 public void start() throws IOException { | 111 public void start() throws IOException{ |
111 remote_sock.setSoTimeout(iddleTimeout); | 112 remote_sock.setSoTimeout(iddleTimeout); |
112 client_sock.setSoTimeout(iddleTimeout); | 113 client_sock.setSoTimeout(iddleTimeout); |
113 log("Starting UDP relay server on " + relayIP + ":" + relayPort); | 114 |
114 log("Remote socket " + remote_sock.getLocalAddress() + ":" + | 115 log("Starting UDP relay server on "+relayIP+":"+relayPort); |
115 remote_sock.getLocalPort()); | 116 log("Remote socket "+remote_sock.getLocalAddress()+":"+ |
116 pipe_thread1 = new Thread(this, "pipe1"); | 117 remote_sock.getLocalPort()); |
117 pipe_thread2 = new Thread(this, "pipe2"); | 118 |
118 lastReadTime = System.currentTimeMillis(); | 119 pipe_thread1 = new Thread(this,"pipe1"); |
119 pipe_thread1.start(); | 120 pipe_thread2 = new Thread(this,"pipe2"); |
120 pipe_thread2.start(); | 121 |
122 lastReadTime = System.currentTimeMillis(); | |
123 | |
124 pipe_thread1.start(); | |
125 pipe_thread2.start(); | |
121 } | 126 } |
122 | 127 |
123 /** | 128 /** |
124 Stops Relay server. | 129 Stops Relay server. |
125 <p> | 130 <p> |
126 Does not close control connection, does not interrupt master_thread. | 131 Does not close control connection, does not interrupt master_thread. |
127 */ | 132 */ |
128 | 133 public synchronized void stop(){ |
129 public synchronized void stop() { | 134 master_thread = null; |
130 master_thread = null; | 135 controlConnection = null; |
131 controlConnection = null; | 136 abort(); |
132 abort(); | |
133 } | 137 } |
134 | 138 |
135 //Runnable interface | 139 //Runnable interface |
136 //////////////////// | 140 //////////////////// |
137 public void run() { | 141 public void run(){ |
138 try { | 142 try{ |
139 if (Thread.currentThread().getName().equals("pipe1")) | 143 if(Thread.currentThread().getName().equals("pipe1")) |
140 pipe(remote_sock, client_sock, false); | 144 pipe(remote_sock,client_sock,false); |
141 else | 145 else |
142 pipe(client_sock, remote_sock, true); | 146 pipe(client_sock,remote_sock,true); |
143 } | 147 }catch(IOException ioe){ |
144 catch (IOException ioe) { | 148 }finally{ |
145 } | 149 abort(); |
146 finally { | 150 log("UDP Pipe thread "+Thread.currentThread().getName()+" stopped."); |
147 abort(); | 151 } |
148 log("UDP Pipe thread " + Thread.currentThread().getName() + " stopped."); | 152 |
149 } | |
150 } | 153 } |
151 | 154 |
152 //Private methods | 155 //Private methods |
153 ///////////////// | 156 ///////////////// |
154 | 157 private synchronized void abort(){ |
155 private synchronized void abort() { | 158 if(pipe_thread1 == null) return; |
156 if (pipe_thread1 == null) return; | 159 |
157 | 160 log("Aborting UDP Relay Server"); |
158 log("Aborting UDP Relay Server"); | 161 |
159 remote_sock.close(); | 162 remote_sock.close(); |
160 client_sock.close(); | 163 client_sock.close(); |
161 | 164 |
162 if (controlConnection != null) | 165 if(controlConnection != null) |
163 try { controlConnection.close();} | 166 try{ controlConnection.close();} catch(IOException ioe){} |
164 catch (IOException ioe) {} | 167 |
165 | 168 if(master_thread!=null) master_thread.interrupt(); |
166 if (master_thread != null) master_thread.interrupt(); | 169 |
167 | 170 pipe_thread1.interrupt(); |
168 pipe_thread1.interrupt(); | 171 pipe_thread2.interrupt(); |
169 pipe_thread2.interrupt(); | 172 |
170 pipe_thread1 = null; | 173 pipe_thread1 = null; |
171 } | 174 } |
172 | 175 |
173 | 176 |
174 static private void log(String s) { | 177 static private void log(String s){ |
175 if (log != null) { | 178 if(log != null){ |
176 log.println(s); | 179 log.println(s); |
177 log.flush(); | 180 log.flush(); |
178 } | 181 } |
179 } | 182 } |
180 | 183 |
181 private void pipe(DatagramSocket from, DatagramSocket to, boolean out) | 184 private void pipe(DatagramSocket from,DatagramSocket to,boolean out) |
182 throws IOException { | 185 throws IOException{ |
183 byte[] data = new byte[datagramSize]; | 186 byte[] data = new byte[datagramSize]; |
184 DatagramPacket dp = new DatagramPacket(data, data.length); | 187 DatagramPacket dp = new DatagramPacket(data,data.length); |
185 | 188 |
186 while (true) { | 189 while(true){ |
187 try { | 190 try{ |
188 from.receive(dp); | 191 from.receive(dp); |
189 lastReadTime = System.currentTimeMillis(); | 192 lastReadTime = System.currentTimeMillis(); |
190 | 193 |
191 if (auth.checkRequest(dp, out)) | 194 if(auth.checkRequest(dp,out)) |
192 to.send(dp); | 195 to.send(dp); |
193 } | 196 |
194 catch (UnknownHostException uhe) { | 197 }catch(UnknownHostException uhe){ |
195 log("Dropping datagram for unknown host"); | 198 log("Dropping datagram for unknown host"); |
196 } | 199 }catch(InterruptedIOException iioe){ |
197 catch (InterruptedIOException iioe) { | 200 //log("Interrupted: "+iioe); |
198 //log("Interrupted: "+iioe); | 201 //If we were interrupted by other thread. |
199 //If we were interrupted by other thread. | 202 if(iddleTimeout == 0) return; |
200 if (iddleTimeout == 0) return; | 203 |
201 | 204 //If last datagram was received, long time ago, return. |
202 //If last datagram was received, long time ago, return. | 205 long timeSinceRead = System.currentTimeMillis() - lastReadTime; |
203 long timeSinceRead = System.currentTimeMillis() - lastReadTime; | 206 if(timeSinceRead >= iddleTimeout -100) //-100 for adjustment |
204 | 207 return; |
205 if (timeSinceRead >= iddleTimeout - 100) //-100 for adjustment | 208 } |
206 return; | 209 dp.setLength(data.length); |
207 } | 210 } |
208 | |
209 dp.setLength(data.length); | |
210 } | |
211 } | 211 } |
212 } | 212 } |