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. # PHP学习笔记之一

    PHP学习笔记之一 标签(空格分隔): PHP 资料来源:慕课网PHP入门篇.PHP学习手册 一.变量 变量定义 $变量名 = 变量值; $var = "xxx"; 变量类型查看 ...

  2. C语言string.h常用函数总结

    void *memcpy(void *dest, const void *src, size_t n); 从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中. ...

  3. 学Git,用Git ①

    本月开始接触到Git版本管理工具,觉得很有意思,在这里总结一下学习Git的一些心得体会. 要在Mac上完整的使用git进行版本管理,需要熟悉Mac终端操作命令和Git操作命令两种命令,索性两种命令加在 ...

  4. PHP中的strtotime()函数

    参见: http://www.phppan.com/2011/06/php-strtotime/ http://developer.51cto.com/art/201107/275478.htm PH ...

  5. java开发中的诡异事件

    1.Excel中的诡异'\r' 2.springMVC中参数莫名的不匹配 今天在使用springmvc测试一个controller方法一直访问失败,400错误,百思不得其解 先是问同事,然后一起讨论了 ...

  6. 爬虫bs4案例

    案例:使用BeautifuSoup4的爬虫 我们以腾讯社招页面来做演示:http://hr.tencent.com/position.php?&start=10#a 使用BeautifuSou ...

  7. jdk官网历史版本下载&Oracle账号密码

    jdk官网下载地址: https://www.oracle.com/technetwork/java/javase/archive-139210.html 账号密码: 1772885836@qq.co ...

  8. codeforce AIM tech Round 4 div 2 B rectangles

    2017-08-25 15:32:14 writer:pprp 题目: B. Rectangles time limit per test 1 second memory limit per test ...

  9. Extjs的form跨域提交文件时,无法获取返回结果

    form文件表单跨域提交时,无法获取远程服务器的返回结果,form提交代码如下: form.submit({ url:'http://{remoteUrl}/hgisserver/wrds/file' ...

  10. ovn-architecture

    本文翻译自ovs官方手册,有删减 OVN架构 OVN(即Open Virtual Network)是一款支持虚拟网络抽象的软件系统.OVN在OVS现有功能的基础上原生支持虚拟网络抽象,例如虚拟L2,L ...