private void doConnect(InetSocketAddress addr) throws IOException { dest = new Socket(); try { dest.connect(addr, 10000); } catch (SocketTimeoutException ex) { sendError(HOST_UNREACHABLE); return; } catch (ConnectException cex) { sendError(CONN_REFUSED); return; } // Success InetAddress iadd = addr.getAddress(); if (iadd instanceof Inet4Address) { out.write(PROTO_VERS); out.write(REQUEST_OK); out.write(0); out.write(IPV4); out.write(iadd.getAddress()); } else if (iadd instanceof Inet6Address) { out.write(PROTO_VERS); out.write(REQUEST_OK); out.write(0); out.write(IPV6); out.write(iadd.getAddress()); } else { sendError(GENERAL_FAILURE); return; } out.write((addr.getPort() >> 8) & 0xff); out.write((addr.getPort() >> 0) & 0xff); out.flush(); InputStream in2 = dest.getInputStream(); OutputStream out2 = dest.getOutputStream(); Tunnel tunnel = new Tunnel(in2, out); tunnel.start(); int b = 0; do { // Note that the socket might be closed from another thread (the tunnel) try { b = in.read(); if (b == -1) { in.close(); out2.close(); return; } out2.write(b); } catch (IOException ioe) { } } while (!client.isClosed()); }
private void doBind(InetSocketAddress addr) throws IOException { ServerSocket svr = new ServerSocket(); svr.bind(null); InetSocketAddress bad = (InetSocketAddress) svr.getLocalSocketAddress(); out.write(PROTO_VERS); out.write(REQUEST_OK); out.write(0); out.write(IPV4); out.write(bad.getAddress().getAddress()); out.write((bad.getPort() >> 8) & 0xff); out.write((bad.getPort() & 0xff)); out.flush(); dest = svr.accept(); bad = (InetSocketAddress) dest.getRemoteSocketAddress(); out.write(PROTO_VERS); out.write(REQUEST_OK); out.write(0); out.write(IPV4); out.write(bad.getAddress().getAddress()); out.write((bad.getPort() >> 8) & 0xff); out.write((bad.getPort() & 0xff)); out.flush(); InputStream in2 = dest.getInputStream(); OutputStream out2 = dest.getOutputStream(); Tunnel tunnel = new Tunnel(in2, out); tunnel.start(); int b = 0; do { // Note that the socket might be close from another thread (the tunnel) try { b = in.read(); if (b == -1) { in.close(); out2.close(); return; } out2.write(b); } catch (IOException ioe) { } } while (!client.isClosed()); }
private void getRequestV4() throws IOException { int ver = in.read(); int cmd = in.read(); if (ver == -1 || cmd == -1) { // EOF in.close(); out.close(); return; } if (ver != 0 && ver != 4) { out.write(PROTO_VERS4); out.write(91); // Bad Request out.write(0); out.write(0); out.write(0); out.write(0); out.write(0); out.write(0); out.write(0); out.flush(); purge(); out.close(); in.close(); return; } if (cmd == CONNECT) { int port = ((in.read() & 0xff) << 8); port += (in.read() & 0xff); byte[] buf = new byte[4]; readBuf(in, buf); InetAddress addr = InetAddress.getByAddress(buf); // We don't use the username... int c; do { c = (in.read() & 0xff); } while (c != 0); boolean ok = true; try { dest = new Socket(addr, port); } catch (IOException e) { ok = false; } if (!ok) { out.write(PROTO_VERS4); out.write(91); out.write(0); out.write(0); out.write(buf); out.flush(); purge(); out.close(); in.close(); return; } out.write(PROTO_VERS4); out.write(90); // Success out.write((port >> 8) & 0xff); out.write(port & 0xff); out.write(buf); out.flush(); InputStream in2 = dest.getInputStream(); OutputStream out2 = dest.getOutputStream(); Tunnel tunnel = new Tunnel(in2, out); tunnel.start(); int b = 0; do { try { b = in.read(); if (b == -1) { in.close(); out2.close(); return; } out2.write(b); } catch (IOException ex) { } } while (!client.isClosed()); } }