1 7 package java.net; 8 import java.io.IOException ; 9 import java.io.InputStream ; 10 import java.io.OutputStream ; 11 import java.io.BufferedOutputStream ; 12 import java.security.AccessController ; 13 import java.security.PrivilegedExceptionAction ; 14 import java.util.prefs.Preferences ; 15 import sun.net.www.ParseUtil; 16 17 18 23 24 class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { 25 private String server = null; 26 private int port = DEFAULT_PORT; 27 private InetSocketAddress external_address; 28 private boolean useV4 = false; 29 private Socket cmdsock = null; 30 private InputStream cmdIn = null; 31 private OutputStream cmdOut = null; 32 33 SocksSocketImpl() { 34 } 36 37 SocksSocketImpl(String server, int port) { 38 this.server = server; 39 this.port = (port == -1 ? DEFAULT_PORT : port); 40 } 41 42 SocksSocketImpl(Proxy proxy) { 43 SocketAddress a = proxy.address(); 44 if (a instanceof InetSocketAddress ) { 45 InetSocketAddress ad = (InetSocketAddress ) a; 46 server = ad.getHostString(); 48 port = ad.getPort(); 49 } 50 } 51 52 void setV4() { 53 useV4 = true; 54 } 55 56 private synchronized void privilegedConnect(final String host, 57 final int port, 58 final int timeout) 59 throws IOException 60 { 61 try { 62 AccessController.doPrivileged( 63 new java.security.PrivilegedExceptionAction () { 64 public Object run() throws IOException { 65 superConnectServer(host, port, timeout); 66 cmdIn = getInputStream(); 67 cmdOut = getOutputStream(); 68 return null; 69 } 70 }); 71 } catch (java.security.PrivilegedActionException pae) { 72 throw (IOException ) pae.getException(); 73 } 74 } 75 76 private void superConnectServer(String host, int port, 77 int timeout) throws IOException { 78 super.connect(new InetSocketAddress (host, port), timeout); 79 } 80 81 private int readSocksReply(InputStream in, byte[] data) throws IOException { 82 int len = data.length; 83 int received = 0; 84 for (int attempts = 0; received < len && attempts < 3; attempts++) { 85 int count = in.read(data, received, len - received); 86 if (count < 0) 87 throw new SocketException ("Malformed reply from SOCKS server"); 88 received += count; 89 } 90 return received; 91 } 92 93 96 private boolean authenticate(byte method, InputStream in, 97 BufferedOutputStream out) throws IOException { 98 byte[] data = null; 99 int i; 100 if (method == NO_AUTH) 102 return true; 103 110 if (method == USER_PASSW) { 111 String userName; 112 String password = null; 113 final InetAddress addr = InetAddress.getByName(server); 114 PasswordAuthentication pw = (PasswordAuthentication ) 115 java.security.AccessController.doPrivileged( 116 new java.security.PrivilegedAction () { 117 public Object run() { 118 return Authenticator.requestPasswordAuthentication( 119 server, addr, port, "SOCKS5", "SOCKS authentication", null); 120 } 121 }); 122 if (pw != null) { 123 userName = pw.getUserName(); 124 password = new String (pw.getPassword()); 125 } else { 126 final Preferences prefs = Preferences.userRoot().node("/java/net/socks"); 127 try { 128 userName = 129 (String ) AccessController.doPrivileged( 130 new java.security.PrivilegedExceptionAction () { 131 public Object run() throws IOException { 132 return prefs.get("username", null); 133 } 134 }); 135 } catch (java.security.PrivilegedActionException pae) { 136 throw (IOException ) pae.getException(); 137 } 138 139 if (userName != null) { 140 try { 141 password = 142 (String ) AccessController.doPrivileged( 143 new java.security.PrivilegedExceptionAction () { 144 public Object run() throws IOException { 145 return prefs.get("password", null); 146 } 147 }); 148 } catch (java.security.PrivilegedActionException pae) { 149 throw (IOException ) pae.getException(); 150 } 151 } else { 152 userName = 153 (String ) java.security.AccessController.doPrivileged( 154 new sun.security.action.GetPropertyAction("user.name")); 155 } 156 } 157 if (userName == null) 158 return false; 159 out.write(1); 160 out.write(userName.length()); 161 try { 162 out.write(userName.getBytes("ISO-8859-1")); 163 } catch (java.io.UnsupportedEncodingException uee) { 164 assert false; 165 } 166 if (password != null) { 167 out.write(password.length()); 168 try { 169 out.write(password.getBytes("ISO-8859-1")); 170 } catch (java.io.UnsupportedEncodingException uee) { 171 assert false; 172 } 173 } else 174 out.write(0); 175 out.flush(); 176 data = new byte[2]; 177 i = readSocksReply(in, data); 178 if (i != 2 || data[1] != 0) { 179 181 out.close(); 182 in.close(); 183 return false; 184 } 185 186 return true; 187 } 188 193 return false; 243 } 244 245 private void connectV4(InputStream in, OutputStream out, 246 InetSocketAddress endpoint) throws IOException { 247 if (!(endpoint.getAddress() instanceof Inet4Address )) { 248 throw new SocketException ("SOCKS V4 requires IPv4 only addresses"); 249 } 250 out.write(PROTO_VERS4); 251 out.write(CONNECT); 252 out.write((endpoint.getPort() >> 8) & 0xff); 253 out.write((endpoint.getPort() >> 0) & 0xff); 254 out.write(endpoint.getAddress().getAddress()); 255 String userName = (String ) java.security.AccessController.doPrivileged( 256 new sun.security.action.GetPropertyAction("user.name")); 257 try { 258 out.write(userName.getBytes("ISO-8859-1")); 259 } catch (java.io.UnsupportedEncodingException uee) { 260 assert false; 261 } 262 out.write(0); 263 out.flush(); 264 byte[] data = new byte[8]; 265 int n = readSocksReply(in, data); 266 if (n != 8) 267 throw new SocketException ("Reply from SOCKS server has bad length: " + n); 268 if (data[0] != 0 && data[0] != 4) 269 throw new SocketException ("Reply from SOCKS server has bad version"); 270 SocketException ex = null; 271 switch (data[1]) { 272 case 90: 273 external_address = endpoint; 275 break; 276 case 91: 277 ex = new SocketException ("SOCKS request rejected"); 278 break; 279 case 92: 280 ex = new SocketException ("SOCKS server couldn't reach destination"); 281 break; 282 case 93: 283 ex = new SocketException ("SOCKS authentication failed"); 284 break; 285 default: 286 ex = new SocketException ("Reply from SOCKS server contains bad status"); 287 break; 288 } 289 if (ex != null) { 290 in.close(); 291 out.close(); 292 throw ex; 293 } 294 } 295 296 310 protected void connect(SocketAddress endpoint, int timeout) throws IOException { 311 SecurityManager security = System.getSecurityManager(); 312 if (endpoint == null || !(endpoint instanceof InetSocketAddress )) 313 throw new IllegalArgumentException ("Unsupported address type"); 314 InetSocketAddress epoint = (InetSocketAddress ) endpoint; 315 if (security != null) { 316 if (epoint.isUnresolved()) 317 security.checkConnect(epoint.getHostName(), 318 epoint.getPort()); 319 else 320 security.checkConnect(epoint.getAddress().getHostAddress(), 321 epoint.getPort()); 322 } 323 if (server == null) { 324 ProxySelector sel = (ProxySelector ) 328 java.security.AccessController.doPrivileged( 329 new java.security.PrivilegedAction () { 330 public Object run() { 331 return ProxySelector.getDefault(); 332 } 333 }); 334 if (sel == null) { 335 338 super.connect(epoint, timeout); 339 return; 340 } 341 URI uri = null; 342 String host = epoint.getHostString(); 344 if (epoint.getAddress() instanceof Inet6Address && 346 (!host.startsWith("[")) && (host.indexOf(":") >= 0)) { 347 host = "[" + host + "]"; 348 } 349 try { 350 uri = new URI ("socket://" + ParseUtil.encodePath(host) + ":"+ epoint.getPort()); 351 } catch (URISyntaxException e) { 352 assert false : e; 354 } 355 Proxy p = null; 356 IOException savedExc = null; 357 java.util.Iterator <Proxy > iProxy = null; 358 iProxy = sel.select(uri).iterator(); 359 if (iProxy == null || !(iProxy.hasNext())) { 360 super.connect(epoint, timeout); 361 return; 362 } 363 while (iProxy.hasNext()) { 364 p = iProxy.next(); 365 if (p == null || p == Proxy.NO_PROXY) { 366 super.connect(epoint, timeout); 367 return; 368 } 369 if (p.type() != Proxy.Type.SOCKS) 370 throw new SocketException ("Unknown proxy type : " + p.type()); 371 if (!(p.address() instanceof InetSocketAddress )) 372 throw new SocketException ("Unknow address type for proxy: " + p); 373 server = ((InetSocketAddress ) p.address()).getHostString(); 375 port = ((InetSocketAddress ) p.address()).getPort(); 376 377 try { 379 privilegedConnect(server, port, timeout); 380 break; 382 } catch (IOException e) { 383 sel.connectFailed(uri,p.address(),e); 385 server = null; 386 port = -1; 387 savedExc = e; 388 } 390 } 391 392 396 if (server == null) { 397 throw new SocketException ("Can't connect to SOCKS proxy:" 398 + savedExc.getMessage()); 399 } 400 } else { 401 try { 403 privilegedConnect(server, port, timeout); 404 } catch (IOException e) { 405 throw new SocketException (e.getMessage()); 406 } 407 } 408 409 BufferedOutputStream out = new BufferedOutputStream (cmdOut, 512); 411 InputStream in = cmdIn; 412 413 if (useV4) { 414 if (epoint.isUnresolved()) 417 throw new UnknownHostException (epoint.toString()); 418 connectV4(in, out, epoint); 419 return; 420 } 421 422 out.write(PROTO_VERS); 424 out.write(2); 425 out.write(NO_AUTH); 426 out.write(USER_PASSW); 427 out.flush(); 428 byte[] data = new byte[2]; 429 int i = readSocksReply(in, data); 430 if (i != 2 || ((int)data[0]) != PROTO_VERS) { 431 if (epoint.isUnresolved()) 436 throw new UnknownHostException (epoint.toString()); 437 connectV4(in, out, epoint); 438 return; 439 } 440 if (((int)data[1]) == NO_METHODS) 441 throw new SocketException ("SOCKS : No acceptable methods"); 442 if (!authenticate(data[1], in, out)) { 443 throw new SocketException ("SOCKS : authentication failed"); 444 } 445 out.write(PROTO_VERS); 446 out.write(CONNECT); 447 out.write(0); 448 449 if (epoint.isUnresolved()) { 450 out.write(DOMAIN_NAME); 451 out.write(epoint.getHostName().length()); 452 try { 453 out.write(epoint.getHostName().getBytes("ISO-8859-1")); 454 } catch (java.io.UnsupportedEncodingException uee) { 455 assert false; 456 } 457 out.write((epoint.getPort() >> 8) & 0xff); 458 out.write((epoint.getPort() >> 0) & 0xff); 459 } else if (epoint.getAddress() instanceof Inet6Address ) { 460 out.write(IPV6); 461 out.write(epoint.getAddress().getAddress()); 462 out.write((epoint.getPort() >> 8) & 0xff); 463 out.write((epoint.getPort() >> 0) & 0xff); 464 } else { 465 out.write(IPV4); 466 out.write(epoint.getAddress().getAddress()); 467 out.write((epoint.getPort() >> 8) & 0xff); 468 out.write((epoint.getPort() >> 0) & 0xff); 469 } 470 out.flush(); 471 data = new byte[4]; 472 i = readSocksReply(in, data); 473 if (i != 4) 474 throw new SocketException ("Reply from SOCKS server has bad length"); 475 SocketException ex = null; 476 int nport, len; 477 byte[] addr; 478 switch (data[1]) { 479 case REQUEST_OK: 480 switch(data[3]) { 482 case IPV4: 483 addr = new byte[4]; 484 i = readSocksReply(in, addr); 485 if (i != 4) 486 throw new SocketException ("Reply from SOCKS server badly formatted"); 487 data = new byte[2]; 488 i = readSocksReply(in, data); 489 if (i != 2) 490 throw new SocketException ("Reply from SOCKS server badly formatted"); 491 nport = ((int)data[0] & 0xff) << 8; 492 nport += ((int)data[1] & 0xff); 493 break; 494 case DOMAIN_NAME: 495 len = data[1]; 496 byte[] host = new byte[len]; 497 i = readSocksReply(in, host); 498 if (i != len) 499 throw new SocketException ("Reply from SOCKS server badly formatted"); 500 data = new byte[2]; 501 i = readSocksReply(in, data); 502 if (i != 2) 503 throw new SocketException ("Reply from SOCKS server badly formatted"); 504 nport = ((int)data[0] & 0xff) << 8; 505 nport += ((int)data[1] & 0xff); 506 break; 507 case IPV6: 508 len = data[1]; 509 addr = new byte[len]; 510 i = readSocksReply(in, addr); 511 if (i != len) 512 throw new SocketException ("Reply from SOCKS server badly formatted"); 513 data = new byte[2]; 514 i = readSocksReply(in, data); 515 if (i != 2) 516 throw new SocketException ("Reply from SOCKS server badly formatted"); 517 nport = ((int)data[0] & 0xff) << 8; 518 nport += ((int)data[1] & 0xff); 519 break; 520 default: 521 ex = new SocketException ("Reply from SOCKS server contains wrong code"); 522 break; 523 } 524 break; 525 case GENERAL_FAILURE: 526 ex = new SocketException ("SOCKS server general failure"); 527 break; 528 case NOT_ALLOWED: 529 ex = new SocketException ("SOCKS: Connection not allowed by ruleset"); 530 break; 531 case NET_UNREACHABLE: 532 ex = new SocketException ("SOCKS: Network unreachable"); 533 break; 534 case HOST_UNREACHABLE: 535 ex = new SocketException ("SOCKS: Host unreachable"); 536 break; 537 case CONN_REFUSED: 538 ex = new SocketException ("SOCKS: Connection refused"); 539 break; 540 case TTL_EXPIRED: 541 ex = new SocketException ("SOCKS: TTL expired"); 542 break; 543 case CMD_NOT_SUPPORTED: 544 ex = new SocketException ("SOCKS: Command not supported"); 545 break; 546 case ADDR_TYPE_NOT_SUP: 547 ex = new SocketException ("SOCKS: address type not supported"); 548 break; 549 } 550 if (ex != null) { 551 in.close(); 552 out.close(); 553 throw ex; 554 } 555 external_address = epoint; 556 } 557 558 private void bindV4(InputStream in, OutputStream out, 559 InetAddress baddr, 560 int lport) throws IOException { 561 if (!(baddr instanceof Inet4Address )) { 562 throw new SocketException ("SOCKS V4 requires IPv4 only addresses"); 563 } 564 super.bind(baddr, lport); 565 byte[] addr1 = baddr.getAddress(); 566 567 InetAddress naddr = baddr; 568 if (naddr.isAnyLocalAddress()) { 569 naddr = cmdsock.getLocalAddress(); 570 addr1 = naddr.getAddress(); 571 } 572 out.write(PROTO_VERS4); 573 out.write(BIND); 574 out.write((super.getLocalPort() >> 8) & 0xff); 575 out.write((super.getLocalPort() >> 0) & 0xff); 576 out.write(addr1); 577 String userName = (String ) java.security.AccessController.doPrivileged( 578 new sun.security.action.GetPropertyAction("user.name")); 579 try { 580 out.write(userName.getBytes("ISO-8859-1")); 581 } catch (java.io.UnsupportedEncodingException uee) { 582 assert false; 583 } 584 out.write(0); 585 out.flush(); 586 byte[] data = new byte[8]; 587 int n = readSocksReply(in, data); 588 if (n != 8) 589 throw new SocketException ("Reply from SOCKS server has bad length: " + n); 590 if (data[0] != 0 && data[0] != 4) 591 throw new SocketException ("Reply from SOCKS server has bad version"); 592 SocketException ex = null; 593 switch (data[1]) { 594 case 90: 595 external_address = new InetSocketAddress (baddr, lport); 597 break; 598 case 91: 599 ex = new SocketException ("SOCKS request rejected"); 600 break; 601 case 92: 602 ex = new SocketException ("SOCKS server couldn't reach destination"); 603 break; 604 case 93: 605 ex = new SocketException ("SOCKS authentication failed"); 606 break; 607 default: 608 ex = new SocketException ("Reply from SOCKS server contains bad status"); 609 break; 610 } 611 if (ex != null) { 612 in.close(); 613 out.close(); 614 throw ex; 615 } 616 617 } 618 619 627 protected synchronized void socksBind(InetSocketAddress saddr) throws IOException { 628 if (socket != null) { 629 return; 632 } 633 634 636 if (server == null) { 637 ProxySelector sel = (ProxySelector ) 641 java.security.AccessController.doPrivileged( 642 new java.security.PrivilegedAction () { 643 public Object run() { 644 return ProxySelector.getDefault(); 645 } 646 }); 647 if (sel == null) { 648 651 return; 652 } 653 URI uri = null; 654 String host = saddr.getHostString(); 656 if (saddr.getAddress() instanceof Inet6Address && 658 (!host.startsWith("[")) && (host.indexOf(":") >= 0)) { 659 host = "[" + host + "]"; 660 } 661 try { 662 uri = new URI ("serversocket://" + ParseUtil.encodePath(host) + ":"+ saddr.getPort()); 663 } catch (URISyntaxException e) { 664 assert false : e; 666 } 667 Proxy p = null; 668 Exception savedExc = null; 669 java.util.Iterator <Proxy > iProxy = null; 670 iProxy = sel.select(uri).iterator(); 671 if (iProxy == null || !(iProxy.hasNext())) { 672 return; 673 } 674 while (iProxy.hasNext()) { 675 p = iProxy.next(); 676 if (p == null || p == Proxy.NO_PROXY) { 677 return; 678 } 679 if (p.type() != Proxy.Type.SOCKS) 680 throw new SocketException ("Unknown proxy type : " + p.type()); 681 if (!(p.address() instanceof InetSocketAddress )) 682 throw new SocketException ("Unknow address type for proxy: " + p); 683 server = ((InetSocketAddress ) p.address()).getHostString(); 685 port = ((InetSocketAddress ) p.address()).getPort(); 686 687 try { 689 AccessController.doPrivileged(new PrivilegedExceptionAction () { 690 public Object run() throws Exception { 691 cmdsock = new Socket (new PlainSocketImpl ()); 692 cmdsock.connect(new InetSocketAddress (server, port)); 693 cmdIn = cmdsock.getInputStream(); 694 cmdOut = cmdsock.getOutputStream(); 695 return null; 696 } 697 }); 698 } catch (Exception e) { 699 sel.connectFailed(uri,p.address(),new SocketException (e.getMessage())); 701 server = null; 702 port = -1; 703 cmdsock = null; 704 savedExc = e; 705 } 707 } 708 709 713 if (server == null || cmdsock == null) { 714 throw new SocketException ("Can't connect to SOCKS proxy:" 715 + savedExc.getMessage()); 716 } 717 } else { 718 try { 719 AccessController.doPrivileged(new PrivilegedExceptionAction () { 720 public Object run() throws Exception { 721 cmdsock = new Socket (new PlainSocketImpl ()); 722 cmdsock.connect(new InetSocketAddress (server, port)); 723 cmdIn = cmdsock.getInputStream(); 724 cmdOut = cmdsock.getOutputStream(); 725 return null; 726 } 727 }); 728 } catch (Exception e) { 729 throw new SocketException (e.getMessage()); 730 } 731 } 732 BufferedOutputStream out = new BufferedOutputStream (cmdOut, 512); 733 InputStream in = cmdIn; 734 if (useV4) { 735 bindV4(in, out, saddr.getAddress(), saddr.getPort()); 736 return; 737 } 738 out.write(PROTO_VERS); 739 out.write(2); 740 out.write(NO_AUTH); 741 out.write(USER_PASSW); 742 out.flush(); 743 byte[] data = new byte[2]; 744 int i = readSocksReply(in, data); 745 if (i != 2 || ((int)data[0]) != PROTO_VERS) { 746 bindV4(in, out, saddr.getAddress(), saddr.getPort()); 749 return; 750 } 751 if (((int)data[1]) == NO_METHODS) 752 throw new SocketException ("SOCKS : No acceptable methods"); 753 if (!authenticate(data[1], in, out)) { 754 throw new SocketException ("SOCKS : authentication failed"); 755 } 756 out.write(PROTO_VERS); 758 out.write(BIND); 759 out.write(0); 760 int lport = saddr.getPort(); 761 if (saddr.isUnresolved()) { 762 out.write(DOMAIN_NAME); 763 out.write(saddr.getHostName().length()); 764 try { 765 out.write(saddr.getHostName().getBytes("ISO-8859-1")); 766 } catch (java.io.UnsupportedEncodingException uee) { 767 assert false; 768 } 769 out.write((lport >> 8) & 0xff); 770 out.write((lport >> 0) & 0xff); 771 } else if (saddr.getAddress() instanceof Inet4Address ) { 772 byte[] addr1 = saddr.getAddress().getAddress(); 773 out.write(IPV4); 774 out.write(addr1); 775 out.write((lport >> 8) & 0xff); 776 out.write((lport >> 0) & 0xff); 777 out.flush(); 778 } else if (saddr.getAddress() instanceof Inet6Address ) { 779 byte[] addr1 = saddr.getAddress().getAddress(); 780 out.write(IPV6); 781 out.write(addr1); 782 out.write((lport >> 8) & 0xff); 783 out.write((lport >> 0) & 0xff); 784 out.flush(); 785 } else { 786 cmdsock.close(); 787 throw new SocketException ("unsupported address type : " + saddr); 788 } 789 data = new byte[4]; 790 i = readSocksReply(in, data); 791 SocketException ex = null; 792 int len, nport; 793 byte[] addr; 794 switch (data[1]) { 795 case REQUEST_OK: 796 InetSocketAddress real_end = null; 798 switch(data[3]) { 799 case IPV4: 800 addr = new byte[4]; 801 i = readSocksReply(in, addr); 802 if (i != 4) 803 throw new SocketException ("Reply from SOCKS server badly formatted"); 804 data = new byte[2]; 805 i = readSocksReply(in, data); 806 if (i != 2) 807 throw new SocketException ("Reply from SOCKS server badly formatted"); 808 nport = ((int)data[0] & 0xff) << 8; 809 nport += ((int)data[1] & 0xff); 810 external_address = 811 new InetSocketAddress (new Inet4Address ("", addr) , nport); 812 break; 813 case DOMAIN_NAME: 814 len = data[1]; 815 byte[] host = new byte[len]; 816 i = readSocksReply(in, host); 817 if (i != len) 818 throw new SocketException ("Reply from SOCKS server badly formatted"); 819 data = new byte[2]; 820 i = readSocksReply(in, data); 821 if (i != 2) 822 throw new SocketException ("Reply from SOCKS server badly formatted"); 823 nport = ((int)data[0] & 0xff) << 8; 824 nport += ((int)data[1] & 0xff); 825 external_address = new InetSocketAddress (new String (host), nport); 826 break; 827 case IPV6: 828 len = data[1]; 829 addr = new byte[len]; 830 i = readSocksReply(in, addr); 831 if (i != len) 832 throw new SocketException ("Reply from SOCKS server badly formatted"); 833 data = new byte[2]; 834 i = readSocksReply(in, data); 835 if (i != 2) 836 throw new SocketException ("Reply from SOCKS server badly formatted"); 837 nport = ((int)data[0] & 0xff) << 8; 838 nport += ((int)data[1] & 0xff); 839 external_address = 840 new InetSocketAddress (new Inet6Address ("", addr), nport); 841 break; 842 } 843 break; 844 case GENERAL_FAILURE: 845 ex = new SocketException ("SOCKS server general failure"); 846 break; 847 case NOT_ALLOWED: 848 ex = new SocketException ("SOCKS: Bind not allowed by ruleset"); 849 break; 850 case NET_UNREACHABLE: 851 ex = new SocketException ("SOCKS: Network unreachable"); 852 break; 853 case HOST_UNREACHABLE: 854 ex = new SocketException ("SOCKS: Host unreachable"); 855 break; 856 case CONN_REFUSED: 857 ex = new SocketException ("SOCKS: Connection refused"); 858 break; 859 case TTL_EXPIRED: 860 ex = new SocketException ("SOCKS: TTL expired"); 861 break; 862 case CMD_NOT_SUPPORTED: 863 ex = new SocketException ("SOCKS: Command not supported"); 864 break; 865 case ADDR_TYPE_NOT_SUP: 866 ex = new SocketException ("SOCKS: address type not supported"); 867 break; 868 } 869 if (ex != null) { 870 in.close(); 871 out.close(); 872 cmdsock.close(); 873 cmdsock = null; 874 throw ex; 875 } 876 cmdIn = in; 877 cmdOut = out; 878 } 879 880 889 protected void acceptFrom(SocketImpl s, InetSocketAddress saddr) throws IOException { 890 if (cmdsock == null) { 891 return; 893 } 894 InputStream in = cmdIn; 895 socksBind(saddr); 897 in.read(); 898 int i = in.read(); 899 in.read(); 900 SocketException ex = null; 901 int nport; 902 byte[] addr; 903 InetSocketAddress real_end = null; 904 switch (i) { 905 case REQUEST_OK: 906 i = in.read(); 908 switch(i) { 909 case IPV4: 910 addr = new byte[4]; 911 readSocksReply(in, addr); 912 nport = in.read() << 8; 913 nport += in.read(); 914 real_end = 915 new InetSocketAddress (new Inet4Address ("", addr) , nport); 916 break; 917 case DOMAIN_NAME: 918 int len = in.read(); 919 addr = new byte[len]; 920 readSocksReply(in, addr); 921 nport = in.read() << 8; 922 nport += in.read(); 923 real_end = new InetSocketAddress (new String (addr), nport); 924 break; 925 case IPV6: 926 addr = new byte[16]; 927 readSocksReply(in, addr); 928 nport = in.read() << 8; 929 nport += in.read(); 930 real_end = 931 new InetSocketAddress (new Inet6Address ("", addr), nport); 932 break; 933 } 934 break; 935 case GENERAL_FAILURE: 936 ex = new SocketException ("SOCKS server general failure"); 937 break; 938 case NOT_ALLOWED: 939 ex = new SocketException ("SOCKS: Accept not allowed by ruleset"); 940 break; 941 case NET_UNREACHABLE: 942 ex = new SocketException ("SOCKS: Network unreachable"); 943 break; 944 case HOST_UNREACHABLE: 945 ex = new SocketException ("SOCKS: Host unreachable"); 946 break; 947 case CONN_REFUSED: 948 ex = new SocketException ("SOCKS: Connection refused"); 949 break; 950 case TTL_EXPIRED: 951 ex = new SocketException ("SOCKS: TTL expired"); 952 break; 953 case CMD_NOT_SUPPORTED: 954 ex = new SocketException ("SOCKS: Command not supported"); 955 break; 956 case ADDR_TYPE_NOT_SUP: 957 ex = new SocketException ("SOCKS: address type not supported"); 958 break; 959 } 960 if (ex != null) { 961 cmdIn.close(); 962 cmdOut.close(); 963 cmdsock.close(); 964 cmdsock = null; 965 throw ex; 966 } 967 968 973 if (s instanceof SocksSocketImpl ) { 974 ((SocksSocketImpl )s).external_address = real_end; 975 } 976 if (s instanceof PlainSocketImpl ) { 977 ((PlainSocketImpl )s).setInputStream((SocketInputStream ) in); 978 } 979 s.fd = cmdsock.getImpl().fd; 980 s.address = cmdsock.getImpl().address; 981 s.port = cmdsock.getImpl().port; 982 s.localport = cmdsock.getImpl().localport; 983 cmdsock = null; 988 } 989 990 991 997 protected InetAddress getInetAddress() { 998 if (external_address != null) 999 return external_address.getAddress(); 1000 else 1001 return super.getInetAddress(); 1002 } 1003 1004 1010 protected int getPort() { 1011 if (external_address != null) 1012 return external_address.getPort(); 1013 else 1014 return super.getPort(); 1015 } 1016 1017 protected int getLocalPort() { 1018 if (socket != null) 1019 return super.getLocalPort(); 1020 if (external_address != null) 1021 return external_address.getPort(); 1022 else 1023 return super.getLocalPort(); 1024 } 1025 1026 protected void close() throws IOException { 1027 if (cmdsock != null) 1028 cmdsock.close(); 1029 cmdsock = null; 1030 super.close(); 1031 } 1032 1033} 1034 | Popular Tags |