void socketAccept(SocketImpl s) throws IOException { int nativefd = checkAndReturnNativeFD(); if (s == null) throw new NullPointerException("socket is null"); int newfd = -1; InetSocketAddress[] isaa = new InetSocketAddress[1]; if (timeout <= 0) { newfd = accept0(nativefd, isaa); } else { configureBlocking(nativefd, false); try { waitForNewConnection(nativefd, timeout); newfd = accept0(nativefd, isaa); if (newfd != -1) { configureBlocking(newfd, true); } } finally { configureBlocking(nativefd, true); } } /* Update (SocketImpl)s' fd */ fdAccess.set(s.fd, newfd); /* Update socketImpls remote port, address and localport */ InetSocketAddress isa = isaa[0]; s.port = isa.getPort(); s.address = isa.getAddress(); s.localport = localport; }
/** * Accepts a connection from a specific host. * * @param s the accepted connection. * @param saddr the socket address of the host we do accept connection from * @exception IOException if an I/O error occurs when accepting the connection. */ protected void acceptFrom(SocketImpl s, InetSocketAddress saddr) throws IOException { if (cmdsock == null) { // Not a Socks ServerSocket. return; } InputStream in = cmdIn; // Sends the "SOCKS BIND" request. socksBind(saddr); in.read(); int i = in.read(); in.read(); SocketException ex = null; int nport; byte[] addr; InetSocketAddress real_end = null; switch (i) { case REQUEST_OK: // success! i = in.read(); switch (i) { case IPV4: addr = new byte[4]; readSocksReply(in, addr); nport = in.read() << 8; nport += in.read(); real_end = new InetSocketAddress(new Inet4Address("", addr), nport); break; case DOMAIN_NAME: int len = in.read(); addr = new byte[len]; readSocksReply(in, addr); nport = in.read() << 8; nport += in.read(); real_end = new InetSocketAddress(new String(addr), nport); break; case IPV6: addr = new byte[16]; readSocksReply(in, addr); nport = in.read() << 8; nport += in.read(); real_end = new InetSocketAddress(new Inet6Address("", addr), nport); break; } break; case GENERAL_FAILURE: ex = new SocketException("SOCKS server general failure"); break; case NOT_ALLOWED: ex = new SocketException("SOCKS: Accept not allowed by ruleset"); break; case NET_UNREACHABLE: ex = new SocketException("SOCKS: Network unreachable"); break; case HOST_UNREACHABLE: ex = new SocketException("SOCKS: Host unreachable"); break; case CONN_REFUSED: ex = new SocketException("SOCKS: Connection refused"); break; case TTL_EXPIRED: ex = new SocketException("SOCKS: TTL expired"); break; case CMD_NOT_SUPPORTED: ex = new SocketException("SOCKS: Command not supported"); break; case ADDR_TYPE_NOT_SUP: ex = new SocketException("SOCKS: address type not supported"); break; } if (ex != null) { cmdIn.close(); cmdOut.close(); cmdsock.close(); cmdsock = null; throw ex; } /** * This is where we have to do some fancy stuff. The datastream from the socket "accepted" by * the proxy will come through the cmdSocket. So we have to swap the socketImpls */ if (s instanceof SocksSocketImpl) { ((SocksSocketImpl) s).external_address = real_end; } if (s instanceof PlainSocketImpl) { ((PlainSocketImpl) s).setInputStream((SocketInputStream) in); } s.fd = cmdsock.getImpl().fd; s.address = cmdsock.getImpl().address; s.port = cmdsock.getImpl().port; s.localport = cmdsock.getImpl().localport; // Need to do that so that the socket won't be closed // when the ServerSocket is closed by the user. // It kinds of detaches the Socket because it is now // used elsewhere. cmdsock = null; }