zoukankan      html  css  js  c++  java
  • netty系列之:netty对SOCKS协议的支持

    简介

    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/

    最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

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

  • 相关阅读:
    LeetCode 345. Reverse Vowels of a String 题解
    LeetCode 344. Reverse String 题解
    LeetCode 27. Remove Element 题解
    LeetCode 61. Rotate List 题解
    LeetCode 19.Remove Nth Node From End of List 题解
    Android耗电量
    Android 使用adb查看和修改电池信息
    Android AOP AspectJ 插桩
    Flask相关用法
    Monkey日志信息的11种Event percentage
  • 原文地址:https://www.cnblogs.com/flydean/p/15769696.html
Copyright © 2011-2022 走看看