Introduction

SOCKS is an excellent network protocol that is mainly used as a proxy. Its two main versions are SOCKS4 and SOCKS5, of which SOCKS5 provides support for authentication. Generally speaking, we can use SSH tools to build a simple SOCKS protocol channel, so for netty, how to provide support for SOCKS? Let's take a look together.

SocksMessage

The first is SocksMessage, which represents the SOCKS message object. SocksMessage is an interface with only one version method that returns SocksVersion.

SocksVersion represents the version number of Socks. In netty, three versions are supported, namely:

    SOCKS4a((byte) 0x04),

    SOCKS5((byte) 0x05),

    UNKNOWN((byte) 0xff);

The corresponding value is the VER field in the SOCKS protocol. Let's take the SOCKS4 protocol as an example, and then review the protocol structure of SOCKS:

meaningVERCMDDSTPORTDSTIPID
number of bytes1124variable

Since there are two versions of SOCKS in netty, there are two implementations of the SocksMessage interface, namely Socks4Message and Socks5Message.

Socks4Message

Socks4Messag inherits from SocksMessage and represents SOCKS4 messages.

In fact, Socks4Messag is a tag interface with nothing in it.

public interface Socks4Message extends SocksMessage {
    // Tag interface
}

For SOCKS4, there are two data request types, CONNECT and BIND, which are defined in Socks4CommandType:

    public static final Socks4CommandType CONNECT = new Socks4CommandType(0x01, "CONNECT");
    public static final Socks4CommandType BIND = new Socks4CommandType(0x02, "BIND");

If there is a request, there will be a response, and there are two corresponding classes, Socks4CommandRequest and Socks4CommandResponse.

For Request, we need request type, USERID, DSTIP and DSTPORT data:

    Socks4CommandType type();

    String userId();

    String dstAddr();

    int dstPort();

For the response, there are four different states, namely SUCCESS, REJECTED_OR_FAILED, IDENTD_UNREACHABLE, IDENTD_AUTH_FAILURE.

    public static final Socks4CommandStatus SUCCESS = new Socks4CommandStatus(0x5a, "SUCCESS");
    public static final Socks4CommandStatus REJECTED_OR_FAILED = new Socks4CommandStatus(0x5b, "REJECTED_OR_FAILED");
    public static final Socks4CommandStatus IDENTD_UNREACHABLE = new Socks4CommandStatus(0x5c, "IDENTD_UNREACHABLE");
    public static final Socks4CommandStatus IDENTD_AUTH_FAILURE = new Socks4CommandStatus(0x5d, "IDENTD_AUTH_FAILURE");

In addition to Socks4CommandStatus, the response request also has two properties, DSTIP and DSTPORT.

    Socks4CommandStatus status();

    String dstAddr();

    int dstPort();

Socks5Message

Similarly, for SOCKS5, there is also a corresponding interface Socks5Message, which is also a Tag interface with nothing in it:

public interface Socks5Message extends SocksMessage {
    // Tag interface
}

For SOCKS5, its request is more complicated than that of SOKCS4. The first request is an initialization request Socks5InitialRequest, which contains a list of acceptable authentications.

This list is represented by Socks5AuthMethod, which contains 4 methods:

    public static final Socks5AuthMethod NO_AUTH = new Socks5AuthMethod(0x00, "NO_AUTH");
    public static final Socks5AuthMethod GSSAPI = new Socks5AuthMethod(0x01, "GSSAPI");
    public static final Socks5AuthMethod PASSWORD = new Socks5AuthMethod(0x02, "PASSWORD");
    public static final Socks5AuthMethod UNACCEPTED = new Socks5AuthMethod(0xff, "UNACCEPTED");

For Socks5InitialRequest, it contains a list of authMethods:

public interface Socks5InitialRequest extends Socks5Message {
    List<Socks5AuthMethod> authMethods();
}

For InitialRequest, there is also Socks5InitialResponse, which contains the Socks5AuthMethod selected by the server, so for Socks5InitialResponse, it only contains one Socks5AuthMethod:

public interface Socks5InitialResponse extends Socks5Message {

    Socks5AuthMethod authMethod();
}

After the client and the server negotiate the selected authentication protocol, the next step is the authentication process. If the username and password mode is used, it corresponds to Socks5PasswordAuthRequest:

public interface Socks5PasswordAuthRequest extends Socks5Message {

    String username();

    String password();
}

There are only two results of password authentication, namely SUCCESS and FAILURE:

    public static final Socks5PasswordAuthStatus SUCCESS = new Socks5PasswordAuthStatus(0x00, "SUCCESS");
    public static final Socks5PasswordAuthStatus FAILURE = new Socks5PasswordAuthStatus(0xFF, "FAILURE");

For Socks5PasswordAuthResponse, it contains an authentication status: Socks5PasswordAuthStatus.

After the authentication is completed, the CommandRequest can be sent next. The corresponding Socks5CommandRequest contains the following properties:

    Socks5CommandType type();

    Socks5AddressType dstAddrType();

    String dstAddr();

    int dstPort();

The corresponding Socks5CommandResponse contains the following properties:

    Socks5CommandStatus status();
    Socks5AddressType bndAddrType();
    String bndAddr();
    int bndPort();

Summarize

The above is the message encapsulation of SOCKS4 and SOCKS5 protocols by netty. Basically objects in netty are consistent with the SOCKS protocol.

This article has been included in http://www.flydean.com/36-netty-socks-support/

The most popular interpretation, the most profound dry goods, the most concise tutorials, and many tricks you don't know are waiting for you to discover!

Welcome to pay attention to my official account: "Program those things", understand technology, understand you better!


flydean
890 声望437 粉丝

欢迎访问我的个人网站:www.flydean.com