shadowsocks-libev udp转发原理简介

  1. ss_local作为一个sock5服务器,接收来自socks5客户端的数据包。在ss_local启动后,即创建一个udp socket,并bind到一个端口。该udp socket用于接收所有来自socks5客户端的udp包。
  2. 根据socks5规范,socks5客户端和ss_local建立一个tcp连接进行握手,握手成功后ss_local返回上面创建的udp socket的端口给socks5客户端
  3. socks5客户端将udp包包装成socks5的格式(即原始数据前加上socks5 request header)发送给ss_local

    SOCKS5 UDP包格式

    +—-+——+——+———-+———-+———-+

    |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA |

    +—-+——+——+———-+———-+———-+

    | 2 | 1 | 1 | Variable | 2 | Variable |

    +—-+——+——+———-+———-+———-+

  4. ss_local 从Socks5 UDP包中取出ATYP开始的内容(即ATYP开始的addr header加上DATA),加密后发送到ss_server。根据加密方式不同,加密包的格式也不同,主要分为stream加密和AEAD加密两大类。(注:目前版本已经去掉OTA)

    UDP (before encryption)

    +——+———-+———-+———-+

    | ATYP | DST.ADDR | DST.PORT | DATA |

    +——+———-+———-+———-+

    | 1 | Variable | 2 | Variable |

    +——+———-+———-+———-+

    .

    ATYP可能的取值是1(ipv4地址),3(域名),4(ipv6地址)。

    如果ATYP是3,则DST.ADDR是1字节域名长度+域名文本。

  5. ss_server将包解密后,去除addr header后将DATA发送到addr header指定的目标地址。如果addr是个域名还要先进行DNS解析。ss_server会维护一个包含fd和addr等内容的cache,避免对于重复的域名重复解析。

  6. ss_server接收来自目的地址的返回的udp包,将他加上addr header并加密发送给ss_local
  7. ss_local解密来自ss_server的包,前面添加3字节0,构建成socks5 udp包后发送回客户端

整体流程和几个重要的函数

  1. init_udprelay : 创建udp server socket, 创建server_ctx_t,启动libev io

    读事件监听,准备接收来自客户端的udp包
  2. server_recv_cb: 当ss-local可接收来自客户端的udp数据包时调用,这个函数里面会读取数据包并处理成shadowsocks udp包的格式并加密后发送到ss-server。
  3. server_recv_cb:当ss-server可接收来自ss-local的加密udp数据包时调用。(同一个函数,不过部分内容通过宏区分了)这个函数里面会读取并解密数据包,解析出addr header,将数据部分发送到addr header里面的地址。如果addr是域名则先做域名解析。
  4. remote_recv_cb:当ss-server可接收来自目的服务器的udp包时调用。这个函数里面读取数据包加上addr header后加密然后发送给ss-local
  5. remote_recv_cb: 当ss-local可接收来自ss-server的加密udp数据包时调用。ss-local会读取数据包并解密,验证addr header,并在数据包最前面加上三个字节的0以构成合法的socks5 udp包,然后将之发送回socks5客户端。

ss-libev 源码解析udp篇 (1)的更多相关文章

  1. ss-libev 源码解析udp篇 (4)

    本篇分析remote_recv_cb,这是整个udp转发的反方向,即读取从后端发送过来的数据再发送给前端.对于ss-server,读取到的数据是目标地址的udp服务器发送回来的响应数据,ss-serv ...

  2. ss-libev 源码解析udp篇 (3)

    本篇分析server_recv_cb,这个是udp转发中最重要的函数. server_recv_cb: 当ss-local或ss-server接收到来自前端的udp数据包时调用.这个函数代码比较多,除 ...

  3. ss-libev 源码解析udp篇 (2)

    UDP relay的代码基本都在udprelay.c中,无论ss-local还是ss-server的代码都在一起,使用宏MODULE_LOCAL,MODULE_REMOTE等区分开.代码虽然不是很多, ...

  4. jQuery2.x源码解析(缓存篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 缓存是jQuery中的又一核心设计,jQuery ...

  5. jQuery2.x源码解析(构建篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 笔者阅读了园友艾伦 Aaron的系列博客< ...

  6. jQuery2.x源码解析(设计篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 这一篇笔者主要以设计的角度探索jQuery的源代 ...

  7. jQuery2.x源码解析(回调篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 通过艾伦的博客,我们能看出,jQuery的pro ...

  8. Shiro源码解析-Session篇

    上一篇Shiro源码解析-登录篇中提到了在登录验证成功后有对session的处理,但未详细分析,本文对此部分源码详细分析下. 1. 分析切入点:DefaultSecurityManger的login方 ...

  9. myBatis源码解析-类型转换篇(5)

    前言 开始分析Type包前,说明下使用场景.数据构建语句使用PreparedStatement,需要输入的是jdbc类型,但我们一般写的是java类型.同理,数据库结果集返回的是jdbc类型,而我们需 ...

随机推荐

  1. Objective-C 集成农行支付接口

    部分参考代码: [NANetworkHandler POSTWithURL:APP_ABCPay par:dict isStored:NO success:^(id responseObject, B ...

  2. MR案例:倒排索引

    1.map阶段:将单词和URI组成Key值(如“MapReduce :1.txt”),将词频作为value. 利用MR框架自带的Map端排序,将同一文档的相同单词的词频组成列表,传递给Combine过 ...

  3. validateJarFile jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class

    项目环境 Maven.Tomcat7.0.27.jdk1.8.0_111 报这个错误的原因是项目中依赖 javax.servlet-api 包和Tomcat本身的包冲突了,Tomcat本身也有这个包 ...

  4. ImportError: No module named argparse

    如果有root权限,可以运行: easy_install argparse 如果没有root权限,As a simple solution copy argparse.py from https:// ...

  5. javascript的函数,定义

    函数 function       A               ()          { }函数体开头    函数名    传入的参数     方法 <button onclick=&qu ...

  6. 在centos 6.9下Protocol Buffers数据传输及存储协议的使用(python)

    我们知道Protocol Buffers是Google定义的一种跨语言.跨平台.可扩展的数据传输及存储的协议,因为将字段协议分别放在传输两端,传输数据中只包含数据本身,不需要包含字段说明,所以传输数据 ...

  7. Caffe cpu版本 Linux配置命令及搭建

    Caffee 安装过程 1.安装依赖包 $ sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-de ...

  8. Faster-rcnn 配置方法

    Faster-rcnn 在Linux下的配置方法 感谢@邓学长 建立过程: (下载库的时候要按照库readme 进行操作) opencv 的包下载安装,安装教程 用git命令将这个库下载到本地 fas ...

  9. MySQL MVVC

    什么是MVVC? MVVC (Multi-Version Concurrency Control) (注:与MVCC相对的,是基于锁的并发控制,Lock-Based Concurrency Contr ...

  10. vector的坑——C++primer练习6.33总结

    说来惭愧,一道简单的对vector递归的题目写了一个多小时,最后还是请教了大神才改出来. 首先贴上原代码: void return_vector(vector<int>::iterator ...