1 package socks; 2 import java.net.*; 3 import java.io.*; 4 5 34 public class Socks5DatagramSocket extends DatagramSocket{ 35 36 InetAddress relayIP; 37 int relayPort; 38 Socks5Proxy proxy; 39 private boolean server_mode = false; 40 UDPEncapsulation encapsulation; 41 42 43 51 public Socks5DatagramSocket() throws SocksException, 52 IOException{ 53 this(Proxy.defaultProxy,0,null); 54 } 55 63 public Socks5DatagramSocket(int port) throws SocksException, 64 IOException{ 65 this(Proxy.defaultProxy,port,null); 66 } 67 75 public Socks5DatagramSocket(int port,InetAddress ip) throws SocksException, 76 IOException{ 77 this(Proxy.defaultProxy,port,ip); 78 } 79 80 95 public Socks5DatagramSocket(Proxy p,int port,InetAddress ip) 96 throws SocksException, 97 IOException{ 98 super(port,ip); 99 if(p == null) throw new SocksException(Proxy.SOCKS_NO_PROXY); 100 if(!(p instanceof Socks5Proxy)) 101 throw new SocksException(-1,"Datagram Socket needs Proxy version 5"); 102 103 if(p.chainProxy != null) 104 throw new SocksException(Proxy.SOCKS_JUST_ERROR, 105 "Datagram Sockets do not support proxy chaining."); 106 107 proxy =(Socks5Proxy) p.copy(); 108 109 ProxyMessage msg = proxy.udpAssociate(super.getLocalAddress(), 110 super.getLocalPort()); 111 relayIP = msg.ip; 112 if(relayIP.getHostAddress().equals("0.0.0.0")) relayIP = proxy.proxyIP; 113 relayPort = msg.port; 114 115 encapsulation = proxy.udp_encapsulation; 116 117 } 120 121 124 Socks5DatagramSocket(boolean server_mode,UDPEncapsulation encapsulation, 125 InetAddress relayIP,int relayPort) 126 throws IOException{ 127 super(); 128 this.server_mode = server_mode; 129 this.relayIP = relayIP; 130 this.relayPort = relayPort; 131 this.encapsulation = encapsulation; 132 this.proxy = null; 133 } 134 135 148 public void send(DatagramPacket dp) throws IOException{ 149 if(!server_mode && proxy.isDirect(dp.getAddress())){ 151 super.send(dp); 152 return; 154 } 155 156 byte[] head = formHeader(dp.getAddress(),dp.getPort()); 157 byte[] buf = new byte[head.length + dp.getLength()]; 158 byte[] data = dp.getData(); 159 System.arraycopy(head,0,buf,0,head.length); 161 System.arraycopy(data,0,buf,head.length,dp.getLength()); 163 164 if(encapsulation != null) 165 buf = encapsulation.udpEncapsulate(buf,true); 166 167 super.send(new DatagramPacket(buf,buf.length,relayIP,relayPort)); 168 } 169 184 public void send(DatagramPacket dp, String host) throws IOException{ 185 if(proxy.isDirect(host)){ 186 dp.setAddress(InetAddress.getByName(host)); 187 super.send(dp); 188 return; 189 } 190 191 if(((Socks5Proxy)proxy).resolveAddrLocally){ 192 dp.setAddress(InetAddress.getByName(host)); 193 } 194 195 byte[] head = formHeader(host,dp.getPort()); 196 byte[] buf = new byte[head.length + dp.getLength()]; 197 byte[] data = dp.getData(); 198 System.arraycopy(head,0,buf,0,head.length); 200 System.arraycopy(data,0,buf,head.length,dp.getLength()); 202 203 if(encapsulation != null) 204 buf = encapsulation.udpEncapsulate(buf,true); 205 206 super.send(new DatagramPacket(buf,buf.length,relayIP,relayPort)); 207 } 208 209 219 public void receive(DatagramPacket dp) throws IOException{ 220 super.receive(dp); 221 222 if(server_mode){ 223 int init_length = dp.getLength(); 225 int initTimeout = getSoTimeout(); 226 long startTime = System.currentTimeMillis(); 227 228 while(!relayIP.equals(dp.getAddress()) || 229 relayPort != dp.getPort()){ 230 231 dp.setLength(init_length); 233 234 if(initTimeout != 0){ 238 int newTimeout = initTimeout - (int)(System.currentTimeMillis() - 239 startTime); 240 if(newTimeout <= 0) throw new InterruptedIOException( 241 "In Socks5DatagramSocket->receive()"); 242 setSoTimeout(newTimeout); 243 } 244 245 super.receive(dp); 246 } 247 248 if(initTimeout != 0) setSoTimeout(initTimeout); 250 251 }else if(!relayIP.equals(dp.getAddress()) || 252 relayPort != dp.getPort()) 253 return; 256 byte[] data; 257 data = dp.getData(); 258 259 if(encapsulation != null) 260 data = encapsulation.udpEncapsulate(data,false); 261 262 int offset = 0; 265 ByteArrayInputStream bIn = new ByteArrayInputStream(data,offset, 266 dp.getLength()); 267 268 269 ProxyMessage msg = new Socks5Message(bIn); 270 dp.setPort(msg.port); 271 dp.setAddress(msg.getInetAddress()); 272 273 int data_length = bIn.available(); 275 System.arraycopy(data,offset+dp.getLength()-data_length, 277 data,offset,data_length); 278 279 280 dp.setLength(data_length); 281 } 282 283 289 public int getLocalPort(){ 290 if(server_mode) return super.getLocalPort(); 291 return relayPort; 292 } 293 299 public InetAddress getLocalAddress(){ 300 if(server_mode) return super.getLocalAddress(); 301 return relayIP; 302 } 303 304 307 public void close(){ 308 if(!server_mode) proxy.endSession(); 309 super.close(); 310 } 311 312 337 public boolean isProxyAlive(int timeout){ 338 if(server_mode) return false; 339 if(proxy != null){ 340 try{ 341 proxy.proxySocket.setSoTimeout(timeout); 342 343 int eof = proxy.in.read(); 344 if(eof < 0) return false; else return true; 347 }catch(InterruptedIOException iioe){ 348 return true; }catch(IOException ioe){ 350 return false; 351 } 352 } 353 return false; 354 } 355 356 359 360 private byte[] formHeader(InetAddress ip, int port){ 361 Socks5Message request = new Socks5Message(0,ip,port); 362 request.data[0] = 0; 363 return request.data; 364 } 365 366 367 private byte[] formHeader(String host,int port){ 368 Socks5Message request = new Socks5Message(0,host,port); 369 request.data[0] = 0; 370 return request.data; 371 } 372 373 374 486 487 } 488 | Popular Tags |