Mercurial > 510Connectbot
diff src/net/sourceforge/jsocks/Socks5DatagramSocket.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 |
line wrap: on
line diff
--- a/src/net/sourceforge/jsocks/Socks5DatagramSocket.java Fri Aug 01 10:25:44 2014 -0700 +++ b/src/net/sourceforge/jsocks/Socks5DatagramSocket.java Fri Aug 01 11:23:10 2014 -0700 @@ -1,462 +1,487 @@ -package net.sourceforge.jsocks; -import java.net.*; -import java.io.*; - -/** - Datagram socket to interract through the firewall.<BR> - Can be used same way as the normal DatagramSocket. One should - be carefull though with the datagram sizes used, as additional data - is present in both incomming and outgoing datagrams. - <p> - SOCKS5 protocol allows to send host address as either: - <ul> - <li> IPV4, normal 4 byte address. (10 bytes header size) - <li> IPV6, version 6 ip address (not supported by Java as for now). - 22 bytes header size. - <li> Host name,(7+length of the host name bytes header size). - </ul> - As with other Socks equivalents, direct addresses are handled - transparently, that is data will be send directly when required - by the proxy settings. - <p> - <b>NOTE:</b><br> - Unlike other SOCKS Sockets, it <b>does not</b> support proxy chaining, - and will throw an exception if proxy has a chain proxy attached. The - reason for that is not my laziness, but rather the restrictions of - the SOCKSv5 protocol. Basicaly SOCKSv5 proxy server, needs to know from - which host:port datagrams will be send for association, and returns address - to which datagrams should be send by the client, but it does not - inform client from which host:port it is going to send datagrams, in fact - there is even no guarantee they will be send at all and from the same address - each time. - - */ -public class Socks5DatagramSocket extends DatagramSocket { - - InetAddress relayIP; - int relayPort; - Socks5Proxy proxy; - private boolean server_mode = false; - UDPEncapsulation encapsulation; - - - /** - Construct Datagram socket for communication over SOCKS5 proxy - server. This constructor uses default proxy, the one set with - Proxy.setDefaultProxy() method. If default proxy is not set or - it is set to version4 proxy, which does not support datagram - forwarding, throws SocksException. - - */ - public Socks5DatagramSocket() throws SocksException, - IOException { - this(Proxy.defaultProxy, 0, null); - } - /** - Construct Datagram socket for communication over SOCKS5 proxy - server. And binds it to the specified local port. - This constructor uses default proxy, the one set with - Proxy.setDefaultProxy() method. If default proxy is not set or - it is set to version4 proxy, which does not support datagram - forwarding, throws SocksException. - */ - public Socks5DatagramSocket(int port) throws SocksException, - IOException { - this(Proxy.defaultProxy, port, null); - } - /** - Construct Datagram socket for communication over SOCKS5 proxy - server. And binds it to the specified local port and address. - This constructor uses default proxy, the one set with - Proxy.setDefaultProxy() method. If default proxy is not set or - it is set to version4 proxy, which does not support datagram - forwarding, throws SocksException. - */ - public Socks5DatagramSocket(int port, InetAddress ip) throws SocksException, - IOException { - this(Proxy.defaultProxy, port, ip); - } - - /** - Constructs datagram socket for communication over specified proxy. - And binds it to the given local address and port. Address of null - and port of 0, signify any availabale port/address. - Might throw SocksException, if: - <ol> - <li> Given version of proxy does not support UDP_ASSOCIATE. - <li> Proxy can't be reached. - <li> Authorization fails. - <li> Proxy does not want to perform udp forwarding, for any reason. - </ol> - Might throw IOException if binding dtagram socket to given address/port - fails. - See java.net.DatagramSocket for more details. - */ - public Socks5DatagramSocket(Proxy p, int port, InetAddress ip) - throws SocksException, - IOException { - super(port, ip); - - if (p == null) throw new SocksException(Proxy.SOCKS_NO_PROXY); - - if (!(p instanceof Socks5Proxy)) - throw new SocksException(-1, "Datagram Socket needs Proxy version 5"); - - if (p.chainProxy != null) - throw new SocksException(Proxy.SOCKS_JUST_ERROR, - "Datagram Sockets do not support proxy chaining."); - - proxy = (Socks5Proxy) p.copy(); - ProxyMessage msg = proxy.udpAssociate(super.getLocalAddress(), - super.getLocalPort()); - relayIP = msg.ip; - - if (relayIP.getHostAddress().equals("0.0.0.0")) relayIP = proxy.proxyIP; - - relayPort = msg.port; - encapsulation = proxy.udp_encapsulation; - //debug("Datagram Socket:"+getLocalAddress()+":"+getLocalPort()+"\n"); - //debug("Socks5Datagram: "+relayIP+":"+relayPort+"\n"); - } - - /** - Used by UDPRelayServer. - */ - Socks5DatagramSocket(boolean server_mode, UDPEncapsulation encapsulation, - InetAddress relayIP, int relayPort) - throws IOException { - super(); - this.server_mode = server_mode; - this.relayIP = relayIP; - this.relayPort = relayPort; - this.encapsulation = encapsulation; - this.proxy = null; - } - - /** - Sends the Datagram either through the proxy or directly depending - on current proxy settings and destination address. <BR> - - <B> NOTE: </B> DatagramPacket size should be at least 10 bytes less - than the systems limit. - - <P> - See documentation on java.net.DatagramSocket - for full details on how to use this method. - @param dp Datagram to send. - @throws IOException If error happens with I/O. - */ - public void send(DatagramPacket dp) throws IOException { - //If the host should be accessed directly, send it as is. - if (!server_mode) { - super.send(dp); - //debug("Sending directly:"); - return; - } - - byte[] head = formHeader(dp.getAddress(), dp.getPort()); - byte[] buf = new byte[head.length + dp.getLength()]; - byte[] data = dp.getData(); - //Merge head and data - System.arraycopy(head, 0, buf, 0, head.length); - //System.arraycopy(data,dp.getOffset(),buf,head.length,dp.getLength()); - System.arraycopy(data, 0, buf, head.length, dp.getLength()); - - if (encapsulation != null) - buf = encapsulation.udpEncapsulate(buf, true); - - super.send(new DatagramPacket(buf, buf.length, relayIP, relayPort)); - } - /** - This method allows to send datagram packets with address type DOMAINNAME. - SOCKS5 allows to specify host as names rather than ip addresses.Using - this method one can send udp datagrams through the proxy, without having - to know the ip address of the destination host. - <p> - If proxy specified for that socket has an option resolveAddrLocally set - to true host will be resolved, and the datagram will be send with address - type IPV4, if resolve fails, UnknownHostException is thrown. - @param dp Datagram to send, it should contain valid port and data - @param host Host name to which datagram should be send. - @throws IOException If error happens with I/O, or the host can't be - resolved when proxy settings say that hosts should be resolved locally. - @see Socks5Proxy#resolveAddrLocally(boolean) - */ - public void send(DatagramPacket dp, String host) throws IOException { - dp.setAddress(InetAddress.getByName(host)); - super.send(dp); - } - - /** - * Receives udp packet. If packet have arrived from the proxy relay server, - * it is processed and address and port of the packet are set to the - * address and port of sending host.<BR> - * If the packet arrived from anywhere else it is not changed.<br> - * <B> NOTE: </B> DatagramPacket size should be at least 10 bytes bigger - * than the largest packet you expect (this is for IPV4 addresses). - * For hostnames and IPV6 it is even more. - @param dp Datagram in which all relevent information will be copied. - */ - public void receive(DatagramPacket dp) throws IOException { - super.receive(dp); - - if (server_mode) { - //Drop all datagrams not from relayIP/relayPort - int init_length = dp.getLength(); - int initTimeout = getSoTimeout(); - long startTime = System.currentTimeMillis(); - - while (!relayIP.equals(dp.getAddress()) || - relayPort != dp.getPort()) { - //Restore datagram size - dp.setLength(init_length); - - //If there is a non-infinit timeout on this socket - //Make sure that it happens no matter how often unexpected - //packets arrive. - if (initTimeout != 0) { - int newTimeout = initTimeout - (int)(System.currentTimeMillis() - - startTime); - - if (newTimeout <= 0) throw new InterruptedIOException( - "In Socks5DatagramSocket->receive()"); - - setSoTimeout(newTimeout); - } - - super.receive(dp); - } - - //Restore timeout settings - if (initTimeout != 0) setSoTimeout(initTimeout); - } - else if (!relayIP.equals(dp.getAddress()) || - relayPort != dp.getPort()) - return; // Recieved direct packet - - //If the datagram is not from the relay server, return it it as is. - byte[] data; - data = dp.getData(); - - if (encapsulation != null) - data = encapsulation.udpEncapsulate(data, false); - - int offset = 0; //Java 1.1 - //int offset = dp.getOffset(); //Java 1.2 - ByteArrayInputStream bIn = new ByteArrayInputStream(data, offset, - dp.getLength()); - ProxyMessage msg = new Socks5Message(bIn); - dp.setPort(msg.port); - dp.setAddress(msg.getInetAddress()); - //what wasn't read by the Message is the data - int data_length = bIn.available(); - //Shift data to the left - System.arraycopy(data, offset + dp.getLength() - data_length, - data, offset, data_length); - dp.setLength(data_length); - } - - /** - * Returns port assigned by the proxy, to which datagrams are relayed. - * It is not the same port to which other party should send datagrams. - @return Port assigned by socks server to which datagrams are send - for association. - */ - public int getLocalPort() { - if (server_mode) return super.getLocalPort(); - - return relayPort; - } - /** - * Address assigned by the proxy, to which datagrams are send for relay. - * It is not necesseraly the same address, to which other party should send - * datagrams. - @return Address to which datagrams are send for association. - */ - public InetAddress getLocalAddress() { - if (server_mode) return super.getLocalAddress(); - - return relayIP; - } - - /** - * Closes datagram socket, and proxy connection. - */ - public void close() { - if (!server_mode) proxy.endSession(); - - super.close(); - } - - /** - This method checks wether proxy still runs udp forwarding service - for this socket. - <p> - This methods checks wether the primary connection to proxy server - is active. If it is, chances are that proxy continues to forward - datagrams being send from this socket. If it was closed, most likely - datagrams are no longer being forwarded by the server. - <p> - Proxy might decide to stop forwarding datagrams, in which case it - should close primary connection. This method allows to check, wether - this have been done. - <p> - You can specify timeout for which we should be checking EOF condition - on the primary connection. Timeout is in milliseconds. Specifying 0 as - timeout implies infinity, in which case method will block, until - connection to proxy is closed or an error happens, and then return false. - <p> - One possible scenario is to call isProxyactive(0) in separate thread, - and once it returned notify other threads about this event. - - @param timeout For how long this method should block, before returning. - @return true if connection to proxy is active, false if eof or error - condition have been encountered on the connection. - */ - public boolean isProxyAlive(int timeout) { - if (server_mode) return false; - - if (proxy != null) { - try { - proxy.proxySocket.setSoTimeout(timeout); - int eof = proxy.in.read(); - - if (eof < 0) return false; // EOF encountered. - else return true; // This really should not happen - } - catch (InterruptedIOException iioe) { - return true; // read timed out. - } - catch (IOException ioe) { - return false; - } - } - - return false; - } - -//PRIVATE METHODS -////////////////// - - - private byte[] formHeader(InetAddress ip, int port) { - Socks5Message request = new Socks5Message(0, ip, port); - request.data[0] = 0; - return request.data; - } - - - /*====================================================================== - - //Mainly Test functions - ////////////////////// - - private String bytes2String(byte[] b){ - String s=""; - char[] hex_digit = { '0','1','2','3','4','5','6','7','8','9', - 'A','B','C','D','E','F'}; - for(int i=0;i<b.length;++i){ - int i1 = (b[i] & 0xF0) >> 4; - int i2 = b[i] & 0xF; - s+=hex_digit[i1]; - s+=hex_digit[i2]; - s+=" "; - } - return s; - } - private static final void debug(String s){ - if(DEBUG) - System.out.print(s); - } - - private static final boolean DEBUG = true; - - - public static void usage(){ - System.err.print( - "Usage: java Socks.SocksDatagramSocket host port [socksHost socksPort]\n"); - } - - static final int defaultProxyPort = 1080; //Default Port - static final String defaultProxyHost = "www-proxy"; //Default proxy - - public static void main(String args[]){ - int port; - String host; - int proxyPort; - String proxyHost; - InetAddress ip; - - if(args.length > 1 && args.length < 5){ - try{ - - host = args[0]; - port = Integer.parseInt(args[1]); - - proxyPort =(args.length > 3)? Integer.parseInt(args[3]) - : defaultProxyPort; - - host = args[0]; - ip = InetAddress.getByName(host); - - proxyHost =(args.length > 2)? args[2] - : defaultProxyHost; - - Proxy.setDefaultProxy(proxyHost,proxyPort); - Proxy p = Proxy.getDefaultProxy(); - p.addDirect("lux"); - - - DatagramSocket ds = new Socks5DatagramSocket(); - - - BufferedReader in = new BufferedReader( - new InputStreamReader(System.in)); - String s; - - System.out.print("Enter line:"); - s = in.readLine(); - - while(s != null){ - byte[] data = (s+"\r\n").getBytes(); - DatagramPacket dp = new DatagramPacket(data,0,data.length, - ip,port); - System.out.println("Sending to: "+ip+":"+port); - ds.send(dp); - dp = new DatagramPacket(new byte[1024],1024); - - System.out.println("Trying to recieve on port:"+ - ds.getLocalPort()); - ds.receive(dp); - System.out.print("Recieved:\n"+ - "From:"+dp.getAddress()+":"+dp.getPort()+ - "\n\n"+ - new String(dp.getData(),dp.getOffset(),dp.getLength())+"\n" - ); - System.out.print("Enter line:"); - s = in.readLine(); - - } - ds.close(); - System.exit(1); - - }catch(SocksException s_ex){ - System.err.println("SocksException:"+s_ex); - s_ex.printStackTrace(); - System.exit(1); - }catch(IOException io_ex){ - io_ex.printStackTrace(); - System.exit(1); - }catch(NumberFormatException num_ex){ - usage(); - num_ex.printStackTrace(); - System.exit(1); - } - - }else{ - usage(); - } - } - */ - -} +package net.sourceforge.jsocks; +import java.net.*; +import java.io.*; + +/** + Datagram socket to interract through the firewall.<BR> + Can be used same way as the normal DatagramSocket. One should + be carefull though with the datagram sizes used, as additional data + is present in both incomming and outgoing datagrams. + <p> + SOCKS5 protocol allows to send host address as either: + <ul> + <li> IPV4, normal 4 byte address. (10 bytes header size) + <li> IPV6, version 6 ip address (not supported by Java as for now). + 22 bytes header size. + <li> Host name,(7+length of the host name bytes header size). + </ul> + As with other Socks equivalents, direct addresses are handled + transparently, that is data will be send directly when required + by the proxy settings. + <p> + <b>NOTE:</b><br> + Unlike other SOCKS Sockets, it <b>does not</b> support proxy chaining, + and will throw an exception if proxy has a chain proxy attached. The + reason for that is not my laziness, but rather the restrictions of + the SOCKSv5 protocol. Basicaly SOCKSv5 proxy server, needs to know from + which host:port datagrams will be send for association, and returns address + to which datagrams should be send by the client, but it does not + inform client from which host:port it is going to send datagrams, in fact + there is even no guarantee they will be send at all and from the same address + each time. + + */ +public class Socks5DatagramSocket extends DatagramSocket{ + + InetAddress relayIP; + int relayPort; + Socks5Proxy proxy; + private boolean server_mode = false; + UDPEncapsulation encapsulation; + + + /** + Construct Datagram socket for communication over SOCKS5 proxy + server. This constructor uses default proxy, the one set with + CProxy.setDefaultProxy() method. If default proxy is not set or + it is set to version4 proxy, which does not support datagram + forwarding, throws SocksException. + + */ + public Socks5DatagramSocket() throws SocksException, + IOException{ + this(CProxy.defaultProxy,0,null); + } + /** + Construct Datagram socket for communication over SOCKS5 proxy + server. And binds it to the specified local port. + This constructor uses default proxy, the one set with + CProxy.setDefaultProxy() method. If default proxy is not set or + it is set to version4 proxy, which does not support datagram + forwarding, throws SocksException. + */ + public Socks5DatagramSocket(int port) throws SocksException, + IOException{ + this(CProxy.defaultProxy,port,null); + } + /** + Construct Datagram socket for communication over SOCKS5 proxy + server. And binds it to the specified local port and address. + This constructor uses default proxy, the one set with + CProxy.setDefaultProxy() method. If default proxy is not set or + it is set to version4 proxy, which does not support datagram + forwarding, throws SocksException. + */ + public Socks5DatagramSocket(int port,InetAddress ip) throws SocksException, + IOException{ + this(CProxy.defaultProxy,port,ip); + } + + /** + Constructs datagram socket for communication over specified proxy. + And binds it to the given local address and port. Address of null + and port of 0, signify any availabale port/address. + Might throw SocksException, if: + <ol> + <li> Given version of proxy does not support UDP_ASSOCIATE. + <li> CProxy can't be reached. + <li> Authorization fails. + <li> CProxy does not want to perform udp forwarding, for any reason. + </ol> + Might throw IOException if binding dtagram socket to given address/port + fails. + See java.net.DatagramSocket for more details. + */ + public Socks5DatagramSocket(CProxy p,int port,InetAddress ip) + throws SocksException, + IOException{ + super(port,ip); + if(p == null) throw new SocksException(CProxy.SOCKS_NO_PROXY); + if(!(p instanceof Socks5Proxy)) + throw new SocksException(-1,"Datagram Socket needs Proxy version 5"); + + if(p.chainProxy != null) + throw new SocksException(CProxy.SOCKS_JUST_ERROR, + "Datagram Sockets do not support proxy chaining."); + + proxy =(Socks5Proxy) p.copy(); + + ProxyMessage msg = proxy.udpAssociate(super.getLocalAddress(), + super.getLocalPort()); + relayIP = msg.ip; + if(relayIP.getHostAddress().equals("0.0.0.0")) relayIP = proxy.proxyIP; + relayPort = msg.port; + + encapsulation = proxy.udp_encapsulation; + + //debug("Datagram Socket:"+getLocalAddress()+":"+getLocalPort()+"\n"); + //debug("Socks5Datagram: "+relayIP+":"+relayPort+"\n"); + } + + /** + Used by UDPRelayServer. + */ + Socks5DatagramSocket(boolean server_mode,UDPEncapsulation encapsulation, + InetAddress relayIP,int relayPort) + throws IOException{ + super(); + this.server_mode = server_mode; + this.relayIP = relayIP; + this.relayPort = relayPort; + this.encapsulation = encapsulation; + this.proxy = null; + } + + /** + Sends the Datagram either through the proxy or directly depending + on current proxy settings and destination address. <BR> + + <B> NOTE: </B> DatagramPacket size should be at least 10 bytes less + than the systems limit. + + <P> + See documentation on java.net.DatagramSocket + for full details on how to use this method. + @param dp Datagram to send. + @throws IOException If error happens with I/O. + */ + public void send(DatagramPacket dp) throws IOException{ + //If the host should be accessed directly, send it as is. + if(!server_mode && proxy.isDirect(dp.getAddress())){ + super.send(dp); + //debug("Sending directly:"); + return; + } + + byte[] head = formHeader(dp.getAddress(),dp.getPort()); + byte[] buf = new byte[head.length + dp.getLength()]; + byte[] data = dp.getData(); + //Merge head and data + System.arraycopy(head,0,buf,0,head.length); + //System.arraycopy(data,dp.getOffset(),buf,head.length,dp.getLength()); + System.arraycopy(data,0,buf,head.length,dp.getLength()); + + if(encapsulation != null) + buf = encapsulation.udpEncapsulate(buf,true); + + super.send(new DatagramPacket(buf,buf.length,relayIP,relayPort)); + } + /** + This method allows to send datagram packets with address type DOMAINNAME. + SOCKS5 allows to specify host as names rather than ip addresses.Using + this method one can send udp datagrams through the proxy, without having + to know the ip address of the destination host. + <p> + If proxy specified for that socket has an option resolveAddrLocally set + to true host will be resolved, and the datagram will be send with address + type IPV4, if resolve fails, UnknownHostException is thrown. + @param dp Datagram to send, it should contain valid port and data + @param host Host name to which datagram should be send. + @throws IOException If error happens with I/O, or the host can't be + resolved when proxy settings say that hosts should be resolved locally. + @see Socks5Proxy#resolveAddrLocally(boolean) + */ + public void send(DatagramPacket dp, String host) throws IOException{ + if(proxy.isDirect(host)){ + dp.setAddress(InetAddress.getByName(host)); + super.send(dp); + return; + } + + if(((Socks5Proxy)proxy).resolveAddrLocally){ + dp.setAddress(InetAddress.getByName(host)); + } + + byte[] head = formHeader(host,dp.getPort()); + byte[] buf = new byte[head.length + dp.getLength()]; + byte[] data = dp.getData(); + //Merge head and data + System.arraycopy(head,0,buf,0,head.length); + //System.arraycopy(data,dp.getOffset(),buf,head.length,dp.getLength()); + System.arraycopy(data,0,buf,head.length,dp.getLength()); + + if(encapsulation != null) + buf = encapsulation.udpEncapsulate(buf,true); + + super.send(new DatagramPacket(buf,buf.length,relayIP,relayPort)); + } + + /** + * Receives udp packet. If packet have arrived from the proxy relay server, + * it is processed and address and port of the packet are set to the + * address and port of sending host.<BR> + * If the packet arrived from anywhere else it is not changed.<br> + * <B> NOTE: </B> DatagramPacket size should be at least 10 bytes bigger + * than the largest packet you expect (this is for IPV4 addresses). + * For hostnames and IPV6 it is even more. + @param dp Datagram in which all relevent information will be copied. + */ + public void receive(DatagramPacket dp) throws IOException{ + super.receive(dp); + + if(server_mode){ + //Drop all datagrams not from relayIP/relayPort + int init_length = dp.getLength(); + int initTimeout = getSoTimeout(); + long startTime = System.currentTimeMillis(); + + while(!relayIP.equals(dp.getAddress()) || + relayPort != dp.getPort()){ + + //Restore datagram size + dp.setLength(init_length); + + //If there is a non-infinit timeout on this socket + //Make sure that it happens no matter how often unexpected + //packets arrive. + if(initTimeout != 0){ + int newTimeout = initTimeout - (int)(System.currentTimeMillis() - + startTime); + if(newTimeout <= 0) throw new InterruptedIOException( + "In Socks5DatagramSocket->receive()"); + setSoTimeout(newTimeout); + } + + super.receive(dp); + } + + //Restore timeout settings + if(initTimeout != 0) setSoTimeout(initTimeout); + + }else if(!relayIP.equals(dp.getAddress()) || + relayPort != dp.getPort()) + return; // Recieved direct packet + //If the datagram is not from the relay server, return it it as is. + + byte[] data; + data = dp.getData(); + + if(encapsulation != null) + data = encapsulation.udpEncapsulate(data,false); + + int offset = 0; //Java 1.1 + //int offset = dp.getOffset(); //Java 1.2 + + ByteArrayInputStream bIn = new ByteArrayInputStream(data,offset, + dp.getLength()); + + + ProxyMessage msg = new Socks5Message(bIn); + dp.setPort(msg.port); + dp.setAddress(msg.getInetAddress()); + + //what wasn't read by the Message is the data + int data_length = bIn.available(); + //Shift data to the left + System.arraycopy(data,offset+dp.getLength()-data_length, + data,offset,data_length); + + + dp.setLength(data_length); + } + + /** + * Returns port assigned by the proxy, to which datagrams are relayed. + * It is not the same port to which other party should send datagrams. + @return Port assigned by socks server to which datagrams are send + for association. + */ + public int getLocalPort(){ + if(server_mode) return super.getLocalPort(); + return relayPort; + } + /** + * Address assigned by the proxy, to which datagrams are send for relay. + * It is not necesseraly the same address, to which other party should send + * datagrams. + @return Address to which datagrams are send for association. + */ + public InetAddress getLocalAddress(){ + if(server_mode) return super.getLocalAddress(); + return relayIP; + } + + /** + * Closes datagram socket, and proxy connection. + */ + public void close(){ + if(!server_mode) proxy.endSession(); + super.close(); + } + + /** + This method checks wether proxy still runs udp forwarding service + for this socket. + <p> + This methods checks wether the primary connection to proxy server + is active. If it is, chances are that proxy continues to forward + datagrams being send from this socket. If it was closed, most likely + datagrams are no longer being forwarded by the server. + <p> + CProxy might decide to stop forwarding datagrams, in which case it + should close primary connection. This method allows to check, wether + this have been done. + <p> + You can specify timeout for which we should be checking EOF condition + on the primary connection. Timeout is in milliseconds. Specifying 0 as + timeout implies infinity, in which case method will block, until + connection to proxy is closed or an error happens, and then return false. + <p> + One possible scenario is to call isProxyactive(0) in separate thread, + and once it returned notify other threads about this event. + + @param timeout For how long this method should block, before returning. + @return true if connection to proxy is active, false if eof or error + condition have been encountered on the connection. + */ + public boolean isProxyAlive(int timeout){ + if(server_mode) return false; + if(proxy != null){ + try{ + proxy.proxySocket.setSoTimeout(timeout); + + int eof = proxy.in.read(); + if(eof < 0) return false; // EOF encountered. + else return true; // This really should not happen + + }catch(InterruptedIOException iioe){ + return true; // read timed out. + }catch(IOException ioe){ + return false; + } + } + return false; + } + +//PRIVATE METHODS +////////////////// + + + private byte[] formHeader(InetAddress ip, int port){ + Socks5Message request = new Socks5Message(0,ip,port); + request.data[0] = 0; + return request.data; + } + + + private byte[] formHeader(String host,int port){ + Socks5Message request = new Socks5Message(0,host,port); + request.data[0] = 0; + return request.data; + } + + +/*====================================================================== + +//Mainly Test functions +////////////////////// + + private String bytes2String(byte[] b){ + String s=""; + char[] hex_digit = { '0','1','2','3','4','5','6','7','8','9', + 'A','B','C','D','E','F'}; + for(int i=0;i<b.length;++i){ + int i1 = (b[i] & 0xF0) >> 4; + int i2 = b[i] & 0xF; + s+=hex_digit[i1]; + s+=hex_digit[i2]; + s+=" "; + } + return s; + } + private static final void debug(String s){ + if(DEBUG) + System.out.print(s); + } + + private static final boolean DEBUG = true; + + + public static void usage(){ + System.err.print( + "Usage: java Socks.SocksDatagramSocket host port [socksHost socksPort]\n"); + } + + static final int defaultProxyPort = 1080; //Default Port + static final String defaultProxyHost = "www-proxy"; //Default proxy + + public static void main(String args[]){ + int port; + String host; + int proxyPort; + String proxyHost; + InetAddress ip; + + if(args.length > 1 && args.length < 5){ + try{ + + host = args[0]; + port = Integer.parseInt(args[1]); + + proxyPort =(args.length > 3)? Integer.parseInt(args[3]) + : defaultProxyPort; + + host = args[0]; + ip = InetAddress.getByName(host); + + proxyHost =(args.length > 2)? args[2] + : defaultProxyHost; + + CProxy.setDefaultProxy(proxyHost,proxyPort); + CProxy p = CProxy.getDefaultProxy(); + p.addDirect("lux"); + + + DatagramSocket ds = new Socks5DatagramSocket(); + + + BufferedReader in = new BufferedReader( + new InputStreamReader(System.in)); + String s; + + System.out.print("Enter line:"); + s = in.readLine(); + + while(s != null){ + byte[] data = (s+"\r\n").getBytes(); + DatagramPacket dp = new DatagramPacket(data,0,data.length, + ip,port); + System.out.println("Sending to: "+ip+":"+port); + ds.send(dp); + dp = new DatagramPacket(new byte[1024],1024); + + System.out.println("Trying to recieve on port:"+ + ds.getLocalPort()); + ds.receive(dp); + System.out.print("Recieved:\n"+ + "From:"+dp.getAddress()+":"+dp.getPort()+ + "\n\n"+ + new String(dp.getData(),dp.getOffset(),dp.getLength())+"\n" + ); + System.out.print("Enter line:"); + s = in.readLine(); + + } + ds.close(); + System.exit(1); + + }catch(SocksException s_ex){ + System.err.println("SocksException:"+s_ex); + s_ex.printStackTrace(); + System.exit(1); + }catch(IOException io_ex){ + io_ex.printStackTrace(); + System.exit(1); + }catch(NumberFormatException num_ex){ + usage(); + num_ex.printStackTrace(); + System.exit(1); + } + + }else{ + usage(); + } + } +*/ + +}