diff options
author | Kenny Root <kenny@the-b.org> | 2013-04-11 21:01:32 -0700 |
---|---|---|
committer | Kenny Root <kenny@the-b.org> | 2013-04-11 21:01:32 -0700 |
commit | d8e49ec3f297f9ba0991762eb2cddbc00ed634d2 (patch) | |
tree | aac59c707c980e90202241c7a9c306ab9d278a1c /src/net/sourceforge/jsocks/Socks5DatagramSocket.java | |
parent | 847af5046fb7d2dbcc668cecf81f1726b7c48bd9 (diff) | |
download | connectbot-d8e49ec3f297f9ba0991762eb2cddbc00ed634d2.tar.gz connectbot-d8e49ec3f297f9ba0991762eb2cddbc00ed634d2.tar.bz2 connectbot-d8e49ec3f297f9ba0991762eb2cddbc00ed634d2.zip |
Fix line endings
Diffstat (limited to 'src/net/sourceforge/jsocks/Socks5DatagramSocket.java')
-rw-r--r-- | src/net/sourceforge/jsocks/Socks5DatagramSocket.java | 920 |
1 files changed, 460 insertions, 460 deletions
diff --git a/src/net/sourceforge/jsocks/Socks5DatagramSocket.java b/src/net/sourceforge/jsocks/Socks5DatagramSocket.java index bb73ccd..b847400 100644 --- a/src/net/sourceforge/jsocks/Socks5DatagramSocket.java +++ b/src/net/sourceforge/jsocks/Socks5DatagramSocket.java @@ -1,460 +1,460 @@ -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 + 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(); + } + } +*/ + +} |