source: 3thparty/jmessenger/src/nu/fw/jeti/plugins/filetransfer/socks5/jsocks/UDPRelayServer.java @ 3952

Revision 3952, 5.8 KB checked in by alexandrecorreia, 13 years ago (diff)

Ticket #1710 - Adicao do codigo fonte java do componente jmessenger(jabberit_messenger)

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