关于java:netty系列之netty对SOCKS协议的支持

10次阅读

共计 3464 个字符,预计需要花费 9 分钟才能阅读完成。

简介

SOCKS 是一个优良的网络协议,次要被用来做代理,它的两个次要版本是 SOCKS4 和 SOCKS5,其中 SOCKS5 提供了对认证的反对。通常来说咱们应用 SSH 工具能够构建简略的 SOCKS 协定通道,那么对于 netty 来说,是怎么提供对 SOCKS 的反对呢?一起来看看吧。

SocksMessage

首先是代表 SOCKS 音讯对象的 SocksMessage。SocksMessage 是一个接口,它外面只有一个返回 SocksVersion 的 version 办法。

SocksVersion 示意的是 Socks 的版本号。在 netty 中,反对三个版本,别离是:

    SOCKS4a((byte) 0x04),

    SOCKS5((byte) 0x05),

    UNKNOWN((byte) 0xff);

其对应的数值是 SOCKS 协定中的 VER 字段,咱们以 SOCKS4 协定为例,再温习一下 SOCKS 的协定构造:

含意 VER CMD DSTPORT DSTIP ID
字节个数 1 1 2 4 可变

既然 netty 中 SOCKS 有两个版本,绝对于的 SocksMessage 接口就有两个实现,别离是 Socks4Message 和 Socks5Message。

Socks4Message

Socks4Messag 继承自 SocksMessage,示意的是 SOCKS4 的音讯。

事实上,Socks4Messag 是一个 tag interface,它外面什么内容都没有。

public interface Socks4Message extends SocksMessage {// Tag interface}

对于 SOCKS4 来说,有两种数据申请类型,别离是 CONNECT 和 BIND,这两种申请类型被定义在 Socks4CommandType 中:

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

有申请就有响应,对应的有两个类,别离是 Socks4CommandRequest 和 Socks4CommandResponse。

对于 Request 来说,咱们须要申请类型,USERID,DSTIP 和 DSTPORT 这几个数据:

    Socks4CommandType type();

    String userId();

    String dstAddr();

    int dstPort();

对于响应来说,有四个不同的状态,别离是 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");

除了 Socks4CommandStatus 之外,响应申请还有 DSTIP 和 DSTPORT 两个属性。

    Socks4CommandStatus status();

    String dstAddr();

    int dstPort();

Socks5Message

同样的,对于 SOCKS5 来说,也有一个对应的接口 Socks5Message,这个接口也是一个 Tag interface,它外面什么都没有:

public interface Socks5Message extends SocksMessage {// Tag interface}

对于 SOCKS5 来说,它的申请要比 SOKCS4 要简单,首先的申请是一个初始化申请 Socks5InitialRequest,该申请蕴含了能够承受的认证列表。

这个列表用 Socks5AuthMethod 来示意,它蕴含 4 个办法:

    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");

对于 Socks5InitialRequest 来说,它蕴含了一个 authMethods 的列表:

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

对于 InitialRequest 来说,对应的也有 Socks5InitialResponse,它蕴含了服务端抉择的 Socks5AuthMethod,所以对 Socks5InitialResponse 来说,它外面只蕴含了一个 Socks5AuthMethod:

public interface Socks5InitialResponse extends Socks5Message {Socks5AuthMethod authMethod();
}

客户端和服务器端协商好抉择的认证协定之后,接下来就是认证的过程,如果应用的是用户名明码的模式,则对应的是 Socks5PasswordAuthRequest:

public interface Socks5PasswordAuthRequest extends Socks5Message {String username();

    String password();}

password 认证的后果只有两种后果,别离是 SUCCESS 和 FAILURE:

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

对于 Socks5PasswordAuthResponse 来说,它蕴含了一个认证的 status:Socks5PasswordAuthStatus。

认证结束之后,接下来就能够发送 CommandRequest 了。对应的 Socks5CommandRequest 蕴含上面几个属性:

    Socks5CommandType type();

    Socks5AddressType dstAddrType();

    String dstAddr();

    int dstPort();

对应的 Socks5CommandResponse 蕴含上面的属性:

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

总结

以上就是 netty 对 SOCKS4 和 SOCKS5 协定的音讯封装。基本上 netty 中的对象是和 SOCKS 协定统一的。

本文已收录于 http://www.flydean.com/36-netty-socks-support/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」, 懂技术,更懂你!

正文完
 0