42 /** |
42 /** |
43 * SOCKS (V4 & V5) TCP socket implementation (RFC 1928). |
43 * SOCKS (V4 & V5) TCP socket implementation (RFC 1928). |
44 * Note this class should <b>NOT</b> be public. |
44 * Note this class should <b>NOT</b> be public. |
45 */ |
45 */ |
46 |
46 |
47 class SocksSocketImpl extends SocketImpl implements SocksConsts, SocketImpl.DelegatingImpl { |
47 class SocksSocketImpl extends DelegatingSocketImpl implements SocksConsts { |
48 private String server = null; |
48 private String server = null; |
49 private int serverPort = DEFAULT_PORT; |
49 private int serverPort = DEFAULT_PORT; |
50 private InetSocketAddress external_address; |
50 private InetSocketAddress external_address; |
51 private boolean useV4 = false; |
51 private boolean useV4 = false; |
52 private Socket cmdsock = null; |
52 private Socket cmdsock = null; |
53 private InputStream cmdIn = null; |
53 private InputStream cmdIn = null; |
54 private OutputStream cmdOut = null; |
54 private OutputStream cmdOut = null; |
55 private final SocketImpl delegate; |
|
56 |
55 |
57 SocksSocketImpl(SocketImpl delegate) { |
56 SocksSocketImpl(SocketImpl delegate) { |
58 Objects.requireNonNull(delegate); |
57 super(delegate); |
59 this.delegate = delegate; |
|
60 } |
58 } |
61 |
59 |
62 SocksSocketImpl(Proxy proxy, SocketImpl delegate) { |
60 SocksSocketImpl(Proxy proxy, SocketImpl delegate) { |
63 this.delegate = delegate; |
61 super(delegate); |
64 SocketAddress a = proxy.address(); |
62 SocketAddress a = proxy.address(); |
65 if (a instanceof InetSocketAddress) { |
63 if (a instanceof InetSocketAddress) { |
66 InetSocketAddress ad = (InetSocketAddress) a; |
64 InetSocketAddress ad = (InetSocketAddress) a; |
67 // Use getHostString() to avoid reverse lookups |
65 // Use getHostString() to avoid reverse lookups |
68 server = ad.getHostString(); |
66 server = ad.getHostString(); |
80 } |
78 } |
81 |
79 |
82 private synchronized void privilegedConnect(final String host, |
80 private synchronized void privilegedConnect(final String host, |
83 final int port, |
81 final int port, |
84 final int timeout) |
82 final int timeout) |
85 throws IOException |
83 throws IOException |
86 { |
84 { |
87 try { |
85 try { |
88 AccessController.doPrivileged( |
86 AccessController.doPrivileged( |
89 new java.security.PrivilegedExceptionAction<>() { |
87 new java.security.PrivilegedExceptionAction<>() { |
90 public Void run() throws IOException { |
88 public Void run() throws IOException { |
252 throw ex; |
250 throw ex; |
253 } |
251 } |
254 } |
252 } |
255 |
253 |
256 @Override |
254 @Override |
257 protected void create(boolean stream) throws IOException { |
|
258 delegate.create(stream); |
|
259 } |
|
260 |
|
261 @Override |
|
262 protected void connect(String host, int port) throws IOException { |
255 protected void connect(String host, int port) throws IOException { |
263 delegate.connect(host, port); |
256 connect(new InetSocketAddress(host, port), 0); |
264 } |
257 } |
265 |
258 |
266 @Override |
259 @Override |
267 protected void connect(InetAddress address, int port) throws IOException { |
260 protected void connect(InetAddress address, int port) throws IOException { |
268 delegate.connect(address, port); |
261 connect(new InetSocketAddress(address, port), 0); |
269 } |
262 } |
270 |
263 |
271 @Override |
264 @Override |
272 void setSocket(Socket soc) { |
265 void setSocket(Socket soc) { |
273 delegate.socket = soc; |
266 delegate.socket = soc; |
274 super.setSocket(soc); |
267 super.setSocket(soc); |
275 } |
268 } |
276 |
269 |
277 @Override |
270 @Override |
278 void setServerSocket(ServerSocket soc) { |
271 void setServerSocket(ServerSocket soc) { |
279 delegate.serverSocket = soc; |
272 throw new InternalError("should not get here"); |
280 super.setServerSocket(soc); |
|
281 } |
273 } |
282 |
274 |
283 /** |
275 /** |
284 * Connects the Socks Socket to the specified endpoint. It will first |
276 * Connects the Socks Socket to the specified endpoint. It will first |
285 * connect to the SOCKS proxy and negotiate the access. If the proxy |
277 * connect to the SOCKS proxy and negotiate the access. If the proxy |
549 } |
541 } |
550 external_address = epoint; |
542 external_address = epoint; |
551 } |
543 } |
552 |
544 |
553 @Override |
545 @Override |
554 protected void bind(InetAddress host, int port) throws IOException { |
546 protected void listen(int backlog) { |
555 delegate.bind(host, port); |
547 throw new InternalError("should not get here"); |
556 } |
548 } |
557 |
549 |
558 @Override |
550 @Override |
559 protected void listen(int backlog) throws IOException { |
551 protected void accept(SocketImpl s) { |
560 delegate.listen(backlog); |
552 throw new InternalError("should not get here"); |
561 } |
|
562 |
|
563 /** |
|
564 * Accept the connection onto the given SocketImpl |
|
565 * |
|
566 * @param s the accepted connection. |
|
567 * @throws IOException |
|
568 */ |
|
569 @Override |
|
570 protected void accept(SocketImpl s) throws IOException { |
|
571 if (s instanceof SocketImpl.DelegatingImpl) |
|
572 s = ((SocketImpl.DelegatingImpl)s).delegate(); |
|
573 delegate.accept(s); |
|
574 } |
|
575 |
|
576 @Override |
|
577 protected InputStream getInputStream() throws IOException { |
|
578 return delegate.getInputStream(); |
|
579 } |
|
580 |
|
581 @Override |
|
582 protected OutputStream getOutputStream() throws IOException { |
|
583 return delegate.getOutputStream(); |
|
584 } |
|
585 |
|
586 @Override |
|
587 protected int available() throws IOException { |
|
588 return delegate.available(); |
|
589 } |
553 } |
590 |
554 |
591 /** |
555 /** |
592 * Returns the value of this socket's {@code address} field. |
556 * Returns the value of this socket's {@code address} field. |
593 * |
557 * |
600 return external_address.getAddress(); |
564 return external_address.getAddress(); |
601 else |
565 else |
602 return delegate.getInetAddress(); |
566 return delegate.getInetAddress(); |
603 } |
567 } |
604 |
568 |
605 @Override |
|
606 protected void shutdownOutput() throws IOException { |
|
607 delegate.shutdownOutput(); |
|
608 } |
|
609 |
|
610 @Override |
|
611 protected FileDescriptor getFileDescriptor() { |
|
612 return delegate.getFileDescriptor(); |
|
613 } |
|
614 |
|
615 /** |
569 /** |
616 * Returns the value of this socket's {@code port} field. |
570 * Returns the value of this socket's {@code port} field. |
617 * |
571 * |
618 * @return the value of this socket's {@code port} field. |
572 * @return the value of this socket's {@code port} field. |
619 * @see java.net.SocketImpl#port |
573 * @see java.net.SocketImpl#port |
647 private String getUserName() { |
591 private String getUserName() { |
648 return StaticProperty.userName(); |
592 return StaticProperty.userName(); |
649 } |
593 } |
650 |
594 |
651 @Override |
595 @Override |
652 public void setOption(int optID, Object value) throws SocketException { |
|
653 delegate.setOption(optID, value); |
|
654 } |
|
655 |
|
656 @Override |
|
657 public Object getOption(int optID) throws SocketException { |
|
658 return delegate.getOption(optID); |
|
659 } |
|
660 |
|
661 @Override |
|
662 protected boolean supportsUrgentData () { |
|
663 return delegate.supportsUrgentData(); |
|
664 } |
|
665 |
|
666 @Override |
|
667 protected int getLocalPort() { |
|
668 return delegate.getLocalPort(); |
|
669 } |
|
670 |
|
671 @Override |
|
672 protected <T> void setOption(SocketOption<T> name, T value) throws IOException { |
|
673 delegate.setOption(name, value); |
|
674 } |
|
675 |
|
676 @Override |
|
677 protected <T> T getOption(SocketOption<T> name) throws IOException { |
|
678 return delegate.getOption(name); |
|
679 } |
|
680 |
|
681 @Override |
|
682 void reset() throws IOException { |
596 void reset() throws IOException { |
683 delegate.reset(); |
597 delegate.reset(); |
684 } |
598 } |
685 |
|
686 @Override |
|
687 protected Set<SocketOption<?>> supportedOptions() { |
|
688 return delegate.supportedOptions(); |
|
689 } |
|
690 |
|
691 @Override |
|
692 public SocketImpl delegate() { |
|
693 return delegate; |
|
694 } |
|
695 } |
599 } |