PageRenderTime 30ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/azureus-4.7.0.2/com/aelitis/net/udp/uc/impl/PRUDPPacketHandlerSocks.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 547 lines | 366 code | 158 blank | 23 comment | 31 complexity | 377aa245ec0cfbb5c984f97fb1be140c MD5 | raw file
  1. /*
  2. * Created on Jun 8, 2010
  3. * Created by Paul Gardner
  4. *
  5. * Copyright 2010 Vuze, Inc. All rights reserved.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; version 2 of the License only.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  19. */
  20. package com.aelitis.net.udp.uc.impl;
  21. import java.io.BufferedOutputStream;
  22. import java.io.ByteArrayInputStream;
  23. import java.io.ByteArrayOutputStream;
  24. import java.io.DataInputStream;
  25. import java.io.DataOutputStream;
  26. import java.io.IOException;
  27. import java.net.DatagramPacket;
  28. import java.net.InetAddress;
  29. import java.net.InetSocketAddress;
  30. import java.net.PasswordAuthentication;
  31. import java.net.Proxy;
  32. import java.net.Socket;
  33. import org.gudy.azureus2.core3.config.COConfigurationManager;
  34. import org.gudy.azureus2.core3.config.ParameterListener;
  35. import org.gudy.azureus2.core3.util.Debug;
  36. import org.gudy.azureus2.core3.util.HostNameToIPResolver;
  37. import com.aelitis.azureus.core.proxy.AEProxyFactory;
  38. import com.aelitis.net.udp.uc.PRUDPPacket;
  39. import com.aelitis.net.udp.uc.PRUDPPacketHandler;
  40. import com.aelitis.net.udp.uc.PRUDPPacketHandlerException;
  41. import com.aelitis.net.udp.uc.PRUDPPacketHandlerStats;
  42. import com.aelitis.net.udp.uc.PRUDPPacketReceiver;
  43. import com.aelitis.net.udp.uc.PRUDPPrimordialHandler;
  44. import com.aelitis.net.udp.uc.PRUDPRequestHandler;
  45. public class
  46. PRUDPPacketHandlerSocks
  47. implements PRUDPPacketHandler, PRUDPPacketHandlerImpl.PacketTransformer
  48. {
  49. private static String socks_host;
  50. private static int socks_port;
  51. private static String socks_user;
  52. private static String socks_password;
  53. static{
  54. COConfigurationManager.addAndFireParameterListeners(
  55. new String[]{
  56. "Proxy.Host",
  57. "Proxy.Port",
  58. "Proxy.Username",
  59. "Proxy.Password",
  60. },
  61. new ParameterListener()
  62. {
  63. public void
  64. parameterChanged(
  65. String parameter_name )
  66. {
  67. socks_host = COConfigurationManager.getStringParameter("Proxy.Host").trim();
  68. socks_port = Integer.parseInt(COConfigurationManager.getStringParameter("Proxy.Port").trim());
  69. socks_user = COConfigurationManager.getStringParameter("Proxy.Username").trim();
  70. socks_password = COConfigurationManager.getStringParameter("Proxy.Password").trim();
  71. if ( socks_user.equalsIgnoreCase("<none>")){
  72. socks_user = "";
  73. }
  74. }
  75. });
  76. }
  77. final private InetSocketAddress target;
  78. private Socket control_socket;
  79. private InetSocketAddress relay;
  80. private PRUDPPacketHandler delegate;
  81. private byte[] packet_out_header;
  82. protected
  83. PRUDPPacketHandlerSocks(
  84. InetSocketAddress _target )
  85. throws PRUDPPacketHandlerException
  86. {
  87. target = _target;
  88. boolean ok = false;
  89. try{
  90. delegate = new PRUDPPacketHandlerImpl( 0, null, this );
  91. control_socket = new Socket( Proxy.NO_PROXY );
  92. control_socket.connect( new InetSocketAddress( socks_host, socks_port ));
  93. DataOutputStream dos = new DataOutputStream( new BufferedOutputStream( control_socket.getOutputStream(), 256 ));
  94. DataInputStream dis = new DataInputStream( control_socket.getInputStream());
  95. dos.writeByte( (byte)5 ); // socks 5
  96. dos.writeByte( (byte)2 ); // 2 methods
  97. dos.writeByte( (byte)0 ); // no auth
  98. dos.writeByte( (byte)2 ); // user/pw
  99. dos.flush();
  100. dis.readByte(); // version byte
  101. byte method = dis.readByte();
  102. if ( method != 0 && method != 2 ){
  103. throw new IOException( "SOCKS 5: no valid method [" + method + "]" );
  104. }
  105. // auth
  106. if ( method == 2 ) {
  107. dos.writeByte( (byte)1 ); // user/pw version
  108. dos.writeByte( (byte)socks_user.length() ); // user length
  109. dos.write( socks_user.getBytes() );
  110. dos.writeByte( (byte)socks_password.length() ); // password length
  111. dos.write( socks_password.getBytes() );
  112. dos.flush();
  113. dis.readByte(); // version byte
  114. byte status = dis.readByte();
  115. if ( status != 0 ){
  116. throw( new IOException( "SOCKS 5: authentication fails [status=" +status+ "]" ));
  117. }
  118. }
  119. String mapped_ip;
  120. if ( target.isUnresolved() || target.getAddress() == null ){
  121. // deal with long "hostnames" that we get for, e.g., I2P destinations
  122. mapped_ip = AEProxyFactory.getAddressMapper().internalise( target.getHostName() );
  123. }else{
  124. mapped_ip = target.getAddress().getHostName();
  125. }
  126. dos.writeByte( (byte)5 ); // version
  127. dos.writeByte( (byte)3 ); // udp associate
  128. dos.writeByte( (byte)0 ); // reserved
  129. dos.writeByte((byte)1);
  130. dos.write( new byte[4] );
  131. dos.writeShort( (short)delegate.getPort()); // port
  132. dos.flush();
  133. dis.readByte(); // ver
  134. byte reply = dis.readByte();
  135. if ( reply != 0 ){
  136. throw( new IOException( "SOCKS 5: udp association fails [reply=" +reply+ "]" ));
  137. }
  138. dis.readByte(); // reserved
  139. InetAddress relay_address;
  140. byte atype = dis.readByte();
  141. if ( atype == 1 ){
  142. byte[] bytes = new byte[4];
  143. dis.readFully( bytes );
  144. relay_address = InetAddress.getByAddress( bytes );
  145. }else if ( atype == 3 ){
  146. byte len = dis.readByte();
  147. byte[] bytes = new byte[(int)len&0xff ];
  148. dis.readFully( bytes );
  149. relay_address = InetAddress.getByName( new String( bytes ));
  150. }else{
  151. byte[] bytes = new byte[16];
  152. dis.readFully( bytes );
  153. relay_address = InetAddress.getByAddress( bytes );
  154. }
  155. int relay_port = ((dis.readByte()<<8)&0xff00) | (dis.readByte() & 0x00ff );
  156. if ( relay_address.isAnyLocalAddress()){
  157. relay_address = control_socket.getInetAddress();
  158. }
  159. relay = new InetSocketAddress( relay_address, relay_port );
  160. // use the maped ip for dns resolution so we don't leak the
  161. // actual address if this is a secure one (e.g. I2P one)
  162. ByteArrayOutputStream baos_temp = new ByteArrayOutputStream();
  163. DataOutputStream dos_temp = new DataOutputStream( baos_temp );
  164. dos_temp.writeByte(0); // resv
  165. dos_temp.writeByte(0); // resv
  166. dos_temp.writeByte(0); // frag (none)
  167. try {
  168. byte[] ip_bytes = HostNameToIPResolver.syncResolve( mapped_ip ).getAddress();
  169. dos_temp.writeByte( ip_bytes.length==4?(byte)1:(byte)4 );
  170. dos_temp.write( ip_bytes );
  171. }catch( Throwable e ){
  172. dos_temp.writeByte( (byte)3 ); // address type = domain name
  173. dos_temp.writeByte( (byte)mapped_ip.length() ); // address type = domain name
  174. dos_temp.write( mapped_ip.getBytes() );
  175. }
  176. dos_temp.writeShort( (short)target.getPort() ); // port
  177. dos_temp.flush();
  178. packet_out_header = baos_temp.toByteArray();
  179. ok = true;
  180. Thread.sleep(1000);
  181. }catch( Throwable e ){
  182. throw( new PRUDPPacketHandlerException( "socks setup failed: " + Debug.getNestedExceptionMessage(e), e));
  183. }finally{
  184. if ( !ok ){
  185. try{
  186. control_socket.close();
  187. }catch( Throwable e ){
  188. Debug.out( e );
  189. }finally{
  190. control_socket = null;
  191. }
  192. if ( delegate != null ){
  193. try{
  194. delegate.destroy();
  195. }finally{
  196. delegate = null;
  197. }
  198. }
  199. }
  200. }
  201. }
  202. public void
  203. transformSend(
  204. DatagramPacket packet )
  205. {
  206. byte[] data = packet.getData();
  207. int data_len = packet.getLength();
  208. byte[] new_data = new byte[data_len+packet_out_header.length];
  209. System.arraycopy( packet_out_header, 0, new_data, 0, packet_out_header.length );
  210. System.arraycopy( data, 0, new_data, packet_out_header.length, data_len);
  211. packet.setData( new_data );
  212. }
  213. public void
  214. transformReceive(
  215. DatagramPacket packet )
  216. {
  217. byte[] data = packet.getData();
  218. int data_len = packet.getLength();
  219. DataInputStream dis = new DataInputStream( new ByteArrayInputStream( data, 0, data_len ));
  220. try{
  221. dis.readByte(); // res
  222. dis.readByte(); // res
  223. dis.readByte(); // assume no frag
  224. byte atype = dis.readByte();
  225. int encap_len = 4;
  226. if ( atype == 1 ){
  227. encap_len += 4;
  228. }else if ( atype == 3 ){
  229. encap_len += 1 + (dis.readByte()&0xff);
  230. }else{
  231. encap_len += 16;
  232. }
  233. encap_len += 2; // port
  234. byte[] new_data = new byte[data_len-encap_len];
  235. System.arraycopy( data, encap_len, new_data, 0, data_len - encap_len );
  236. packet.setData( new_data );
  237. }catch( IOException e ){
  238. Debug.out( e );
  239. }
  240. }
  241. private void
  242. checkAddress(
  243. InetSocketAddress destination )
  244. throws PRUDPPacketHandlerException
  245. {
  246. if ( !destination.equals( target )){
  247. throw( new PRUDPPacketHandlerException( "Destination mismatch" ));
  248. }
  249. }
  250. public void
  251. sendAndReceive(
  252. PRUDPPacket request_packet,
  253. InetSocketAddress destination_address,
  254. PRUDPPacketReceiver receiver,
  255. long timeout,
  256. int priority )
  257. throws PRUDPPacketHandlerException
  258. {
  259. checkAddress( destination_address );
  260. delegate.sendAndReceive( request_packet, relay, receiver, timeout, priority );
  261. }
  262. public PRUDPPacket
  263. sendAndReceive(
  264. PasswordAuthentication auth,
  265. PRUDPPacket request_packet,
  266. InetSocketAddress destination_address )
  267. throws PRUDPPacketHandlerException
  268. {
  269. checkAddress( destination_address );
  270. return( delegate.sendAndReceive( auth, request_packet, relay));
  271. }
  272. public PRUDPPacket
  273. sendAndReceive(
  274. PasswordAuthentication auth,
  275. PRUDPPacket request_packet,
  276. InetSocketAddress destination_address,
  277. long timeout_millis )
  278. throws PRUDPPacketHandlerException
  279. {
  280. checkAddress( destination_address );
  281. return( delegate.sendAndReceive(auth, request_packet, relay, timeout_millis ));
  282. }
  283. public PRUDPPacket
  284. sendAndReceive(
  285. PasswordAuthentication auth,
  286. PRUDPPacket request_packet,
  287. InetSocketAddress destination_address,
  288. long timeout_millis,
  289. int priority )
  290. throws PRUDPPacketHandlerException
  291. {
  292. checkAddress( destination_address );
  293. return( delegate.sendAndReceive(auth, request_packet, relay, timeout_millis, priority ));
  294. }
  295. public void
  296. send(
  297. PRUDPPacket request_packet,
  298. InetSocketAddress destination_address )
  299. throws PRUDPPacketHandlerException
  300. {
  301. checkAddress( destination_address );
  302. delegate.send( request_packet, relay );
  303. }
  304. public PRUDPRequestHandler
  305. getRequestHandler()
  306. {
  307. return( delegate.getRequestHandler());
  308. }
  309. public void
  310. setRequestHandler(
  311. PRUDPRequestHandler request_handler )
  312. {
  313. delegate.setRequestHandler( request_handler );
  314. }
  315. public void
  316. primordialSend(
  317. byte[] data,
  318. InetSocketAddress target )
  319. throws PRUDPPacketHandlerException
  320. {
  321. throw( new PRUDPPacketHandlerException( "not imp" ));
  322. }
  323. public void
  324. addPrimordialHandler(
  325. PRUDPPrimordialHandler handler )
  326. {
  327. }
  328. public void
  329. removePrimordialHandler(
  330. PRUDPPrimordialHandler handler )
  331. {
  332. }
  333. public int
  334. getPort()
  335. {
  336. return( delegate.getPort());
  337. }
  338. public void
  339. setDelays(
  340. int send_delay,
  341. int receive_delay,
  342. int queued_request_timeout )
  343. {
  344. delegate.setDelays(send_delay, receive_delay, queued_request_timeout);
  345. }
  346. public void
  347. setExplicitBindAddress(
  348. InetAddress address )
  349. {
  350. delegate.setExplicitBindAddress( address );
  351. }
  352. public PRUDPPacketHandlerStats
  353. getStats()
  354. {
  355. return( delegate.getStats());
  356. }
  357. public PRUDPPacketHandler
  358. openSession(
  359. InetSocketAddress target )
  360. throws PRUDPPacketHandlerException
  361. {
  362. throw( new PRUDPPacketHandlerException( "not supported" ));
  363. }
  364. public void
  365. closeSession()
  366. throws PRUDPPacketHandlerException
  367. {
  368. if ( control_socket != null ){
  369. try{
  370. control_socket.close();
  371. control_socket = null;
  372. }catch( Throwable e ){
  373. Debug.out( e );
  374. }
  375. }
  376. if ( delegate != null ){
  377. delegate.destroy();
  378. }
  379. }
  380. public void
  381. destroy()
  382. {
  383. try{
  384. closeSession();
  385. }catch( Throwable e ){
  386. Debug.out( e );
  387. }
  388. }
  389. }