shadowsocks源码解读(二):SS Server工作流程

  • 2016-12-22
  • 9,248

上一节中写到shadowsocks由SS Local和SS Server组成,因为工作原理相似,且SS Server方便调试跟踪,所以以SS Server来分析其中具体流程。

运行ssserver -p 10001 -k pass -m aes-256-cfb,运行SS Server
* 监听本地10001端口,密码pass,加密方式aes-256-cfb

在server.py的main()下设置断点方便调试。

程序一开始先实例化一个TCPRelay类,我们看看TCPRelay在初始化的时候干了什么。

初始化的时候根据配置项新建一个socket并绑定到端口进行监听,之后进入到run_server()函数

再来看看EventLoop初始化干了什么

然后是add_to_loop()函数

在调用self._eventloop.add()函数时,会在EventLoop类中建立一个映射

到这边总结下程序做的工作,初始化一个TCPRelay类监听本地端口,将它加入事件循环,监听socket的可读和错误事件,事件循环中有一个映射,将fd(文件描述符)映射到对应的(socket,handler),以便之后检测到有请求发生的时候,将请求分发给各自的handler处理,事件循环只管监听事件。

接下来进入到核心的loop.run()函数中。

然后事件循环继续监听事件。
继续看handler.handle_event()函数怎么处理请求的。

然后交给TCPRelayHandler处理请求
TCPRelayHandler在初始化的时候会将conn这个socket加入到loop循环中监听可读或者错误事件

if sock == self._server_socket判断当前socket是客户端第一次请求连接还是客户端连接之后发送的请求。
如果是客户端第一次连接,调用TCPRelayHandler,会将新的socket加入事件循环,并且在TCPRelay._fd_to_handlers添加映射,这个等下再讲用途。
如果是客户端在连接之后发来的请求的话,会在self._fd_to_handlers.get()查找handler,也就是客户端第一次连接创建的映射,此时handler是TCPRelayHandler,进入handle_event()函数后,这时候如果请求正常的话会进入到self._on_local_read()函数

之后就是TCPRelayHandler在负责处理数据了。

所以处理的流程大致理清了,我画了一张流程图,更好地理清思路。

总结

shadowsocks原理并不难,主要是程序一直处在EventLoop的循环中,需要在循环里面观察各个模块的运行情况,而且SS Server和SS Local共用同一个TCPRelay,所以就增加了代码的复杂度,只要耐心看下去,摸清楚哪个模块干了些什么事之后就简单了。

链接:https://www.ioiogoo.cn/2016/12/22/shadowsocks源码解读(二):ss-server工作流程/
本站所有文章除特殊说明外均为原创,转载请注明出处!