예제 #1
0
    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());
    }
예제 #2
0
    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());
    }
예제 #3
0
    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());
      }
    }