sockssocketimpl.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 823 行 · 第 1/2 页

JAVA
823
字号
		    throw new SocketException("Reply from SOCKS server badly formatted");		nport = ((int)data[0] & 0xff) << 8;		nport += ((int)data[1] & 0xff);		break;	    default:		ex = new SocketException("Reply from SOCKS server contains wrong code");		break;	    }	    break;	case GENERAL_FAILURE:	    ex = new SocketException("SOCKS server general failure");	    break;	case NOT_ALLOWED:	    ex = new SocketException("SOCKS: Connection 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) {	    in.close();	    out.close();	    throw ex;	}	external_address = epoint;    }    private void bindV4(InputStream in, OutputStream out,			InetAddress baddr,			int lport) throws IOException {	super.bind(baddr, lport);	/* NOTE: Can test here for IPV4/IPV6 */	byte[] addr1 = baddr.getAddress();	/* Test for AnyLocal */	InetAddress naddr = baddr;	if (naddr.isAnyLocalAddress()) {	    naddr = cmdsock.getLocalAddress();	    addr1 = naddr.getAddress();	}	out.write(PROTO_VERS4);	out.write(BIND);	out.write((super.getLocalPort() >> 8) & 0xff);	out.write((super.getLocalPort() >> 0) & 0xff);	out.write(addr1);	String userName = (String) java.security.AccessController.doPrivileged(               new sun.security.action.GetPropertyAction("user.name"));	out.write(userName.getBytes());	out.write(0);	out.flush();	byte[] data = new byte[8];	int n = readSocksReply(in, data);	if (n != 8)	    throw new SocketException("Reply from SOCKS server has bad length: " + n);	if (data[0] != 0 && data[0] != 4)	    throw new SocketException("Reply from SOCKS server has bad version");	SocketException ex = null;	switch (data[1]) {	case 90:	    // Success!	    external_address = new InetSocketAddress(baddr, lport);	    break;	case 91:	    ex = new SocketException("SOCKS request rejected");	    break;	case 92:	    ex = new SocketException("SOCKS server couldn't reach destination");	    break;	case 93:	    ex = new SocketException("SOCKS authentication failed");	    break;	default:	    ex = new SocketException("Replay from SOCKS server contains bad status");	    break;	}	if (ex != null) {	    in.close();	    out.close();	    throw ex;	}	    }    /**     * Binds this socket to the specified port number on the specified host.      *     * @param      baddr   the IP address of the remote host.     * @param      lport   the port number.     * @exception  IOException  if an I/O error occurs when binding this socket.     */    protected synchronized void bind(InetAddress baddr, int lport) throws IOException {	if (socket != null) {	    // this is a client socket, not a server socket, don't	    // call the SOCKS proxy for a bind!	    super.bind(baddr, lport);	    return;	}	// Connects to the SOCKS server		try {	    AccessController.doPrivileged(new PrivilegedExceptionAction() {		    public Object run() throws Exception {			cmdsock = new Socket(new PlainSocketImpl());			cmdsock.connect(new InetSocketAddress(server, port));			cmdIn = cmdsock.getInputStream();			cmdOut = cmdsock.getOutputStream();			return null;		    }		});	} catch (Exception e) {	    throw new SocketException(e.getMessage());	}	DataOutputStream out = new DataOutputStream(cmdOut);	InputStream in = cmdIn;	if (useV4) {	    bindV4(in, out, baddr, lport);	    return;	}	out.write(PROTO_VERS);	out.write(2);	out.write(NO_AUTH);	out.write(USER_PASSW);	out.flush();	byte[] data = new byte[2];	int i = readSocksReply(in, data);	if (i != 2 || ((int)data[1]) == NO_METHODS)	    throw new SocketException("SOCKS : No acceptable methods");	if (!authenticate(data[1], in, out)) {	    throw new SocketException("SOCKS : authentication failed");	}	// We're OK. Let's issue the BIND command after we've bound ourself localy	super.bind(baddr, lport);	out.write(PROTO_VERS);	out.write(BIND);	out.write(0);	InetAddress naddr = baddr;	if (naddr.isAnyLocalAddress())	    naddr = cmdsock.getLocalAddress();	byte[] addr1 = naddr.getAddress();	if (naddr.family == InetAddress.IPv4) {	    out.write(IPV4);	    out.write(addr1);	    out.write((super.getLocalPort() >> 8) & 0xff);	    out.write((super.getLocalPort() >> 0) & 0xff);	    out.flush();	} else if (naddr.family == InetAddress.IPv6) {	    /* Test for AnyLocal */	    out.write(IPV6);	    out.write(addr1);	    out.write((super.getLocalPort() >> 8) & 0xff);	    out.write((super.getLocalPort() >> 0) & 0xff);	    out.flush();	} else {	    cmdsock.close();	    throw new SocketException("unsupported address type : " + naddr);	}	data = new byte[4];	i = readSocksReply(in, data);	SocketException ex = null;	int len, nport;	byte[] addr;	switch (data[1]) {	case REQUEST_OK:	    // success!	    InetSocketAddress real_end = null;	    switch(data[3]) {	    case IPV4:		addr = new byte[4];		i = readSocksReply(in, addr);		if (i != 4)		    throw new SocketException("Reply from SOCKS server badly formatted");		data = new byte[2];		i = readSocksReply(in, data);		if (i != 2)		    throw new SocketException("Reply from SOCKS server badly formatted");		nport = ((int)data[0] & 0xff) << 8;		nport += ((int)data[1] & 0xff);		external_address =		    new InetSocketAddress(new Inet4Address("", addr) , nport);		break;	    case DOMAIN_NAME:		len = data[1];		byte[] host = new byte[len];		i = readSocksReply(in, host);		if (i != len)		    throw new SocketException("Reply from SOCKS server badly formatted");		data = new byte[2];		i = readSocksReply(in, data);		if (i != 2)		    throw new SocketException("Reply from SOCKS server badly formatted");		nport = ((int)data[0] & 0xff) << 8;		nport += ((int)data[1] & 0xff);		external_address = new InetSocketAddress(new String(host), nport);		break;	    case IPV6:		len = data[1];		addr = new byte[len];		i = readSocksReply(in, addr);		if (i != len)		    throw new SocketException("Reply from SOCKS server badly formatted");		data = new byte[2];		i = readSocksReply(in, data);		if (i != 2)		    throw new SocketException("Reply from SOCKS server badly formatted");		nport = ((int)data[0] & 0xff) << 8;		nport += ((int)data[1] & 0xff);		external_address = 		    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: Bind 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) {	    in.close();	    out.close();	    cmdsock.close();	    cmdsock = null;	    throw ex;	}	cmdIn = in;	cmdOut = out;    }    /**     * Accepts a connection.      *     * @param      s   the accepted connection.     * @exception  IOException  if an I/O error occurs when accepting the     *               connection.     */    protected void accept(SocketImpl s) throws IOException {	if (cmdsock == null)	    throw new SocketException("Socks channel closed");	InputStream in = cmdIn;	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;    }        /**     * Returns the value of this socket's <code>address</code> field.     *     * @return  the value of this socket's <code>address</code> field.     * @see     java.net.SocketImpl#address     */    protected InetAddress getInetAddress() {	if (external_address != null)	    return external_address.getAddress();	else	    return super.getInetAddress();    }    /**     * Returns the value of this socket's <code>port</code> field.     *     * @return  the value of this socket's <code>port</code> field.     * @see     java.net.SocketImpl#port     */    protected int getPort() {	if (external_address != null)	    return external_address.getPort();	else	    return super.getPort();    }    protected int getLocalPort() {	if (socket != null)	    return super.getLocalPort();	if (external_address != null)	    return external_address.getPort();	else	    return super.getLocalPort();    }    protected void close() throws IOException {	if (cmdsock != null)	    cmdsock.close();	cmdsock = null;	super.close();    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?