/**
  * Request a SOCKS connection to the application server given. If the request fails to complete
  * successfully, an exception is thrown.
  */
 private void socksRequestConnection(
     InetAddress applicationServerAddress, int applicationServerPort) throws IOException {
   socksSendRequest(
       Socks4Message.COMMAND_CONNECT, applicationServerAddress, applicationServerPort);
   Socks4Message reply = socksReadReply();
   if (reply.getCommandOrResult() != Socks4Message.RETURN_SUCCESS) {
     throw new IOException(reply.getErrorString(reply.getCommandOrResult()));
   }
 }
 /** Read a SOCKS V4 reply. */
 private Socks4Message socksReadReply() throws IOException {
   Socks4Message reply = new Socks4Message();
   int bytesRead = 0;
   while (bytesRead < Socks4Message.REPLY_LENGTH) {
     int count =
         getInputStream()
             .read(reply.getBytes(), bytesRead, Socks4Message.REPLY_LENGTH - bytesRead);
     if (-1 == count) {
       break;
     }
     bytesRead += count;
   }
   if (Socks4Message.REPLY_LENGTH != bytesRead) {
     throw new SocketException(Msg.getString("KA011")); // $NON-NLS-1$
   }
   return reply;
 }
  /** Bind using a SOCKS server. */
  private void socksBind() throws IOException {
    try {
      netImpl.connect(fd, trafficClass, socksGetServerAddress(), socksGetServerPort());
    } catch (Exception e) {
      throw new IOException(Msg.getString("K003f", e)); // $NON-NLS-1$
    }

    // There must be a connection to an application host for the bind to
    // work.
    if (lastConnectedAddress == null) {
      throw new SocketException(Msg.getString("K0040")); // $NON-NLS-1$
    }

    // Use the last connected address and port in the bind request.
    socksSendRequest(Socks4Message.COMMAND_BIND, lastConnectedAddress, lastConnectedPort);
    Socks4Message reply = socksReadReply();

    if (reply.getCommandOrResult() != Socks4Message.RETURN_SUCCESS) {
      throw new IOException(reply.getErrorString(reply.getCommandOrResult()));
    }

    // A peculiarity of socks 4 - if the address returned is 0, use the
    // original socks server address.
    if (reply.getIP() == 0) {
      address = socksGetServerAddress();
    } else {
      // IPv6 support not yet required as
      // currently the Socks4Message.getIP() only returns int,
      // so only works with IPv4 4byte addresses
      byte[] replyBytes = new byte[4];
      NetUtil.intToBytes(reply.getIP(), replyBytes, 0);
      address = InetAddress.getByAddress(replyBytes);
    }
    localport = reply.getPort();
  }
  /** Send a SOCKS V4 request. */
  private void socksSendRequest(int command, InetAddress address, int port) throws IOException {
    Socks4Message request = new Socks4Message();
    request.setCommandOrResult(command);
    request.setPort(port);
    request.setIP(address.getAddress());
    request.setUserId("default"); // $NON-NLS-1$

    getOutputStream().write(request.getBytes(), 0, request.getLength());
  }
 /** Perform an accept for a SOCKS bind. */
 public void socksAccept() throws IOException {
   Socks4Message reply = socksReadReply();
   if (reply.getCommandOrResult() != Socks4Message.RETURN_SUCCESS) {
     throw new IOException(reply.getErrorString(reply.getCommandOrResult()));
   }
 }