1. 程式人生 > >ss-libev 原始碼解析udp篇 (2)

ss-libev 原始碼解析udp篇 (2)

UDP relay的程式碼基本都在udprelay.c中,無論ss-local還是ss-server的程式碼都在一起,使用巨集MODULE_LOCAL,MODULE_REMOTE等區分開。程式碼雖然不是很多,但是由於ss-local和ss-server以及ss-redir,ss-tunnel等夾雜在同一個函式中,不斷有巨集去打斷讀程式碼的思路,並且很多程式碼還是同時被ss-local和ss-server執行到,所以本系列分多篇去逐個分析重要的函式。先從init_udprelay開始。
* init_udprelay函式宣告:

int
init_udprelay(const char *server_host, const
char *server_port, #ifdef MODULE_LOCAL const struct sockaddr *remote_addr, const int remote_addr_len, #ifdef MODULE_TUNNEL const ss_addr_t tunnel_addr, #endif #endif int mtu, crypto_t *crypto, int timeout, const char *iface)

對於ss-local,多出兩個引數,即remote_addr和remote_addr_len。
這個就是要使用的ss-server的地址,通過引數傳進來。而ss-server不需要指定外發地址,因為ss-server外發udp的地址是從ss udp包的addr header裡面讀取到的。
* init_udprelay函式解析: 初始化udp relay,主要是建立server socket (無論ss-local還是ss-server,用於接收來自前端的udp資料,對於ss-local就是接收客戶端的udp資料,對於ss-server,就是接收ss-local傳送過來的udp); 另外還建立了一個server_ctx_t物件,用於存放udp server相關的一些資訊。這個server_ctx儲存了server fd等內容,會在後續方法中使用到,比較重要。

typedef struct server_ctx {
    ev_io io;
    int fd;
    crypto_t *crypto;
    int timeout;
    const char *iface;
    struct cache *conn_cache;
#ifdef MODULE_LOCAL
    const struct sockaddr *remote_addr;
    int remote_addr_len;
#ifdef MODULE_TUNNEL
    ss_addr_t tunnel_addr;
#endif
#endif
#ifdef MODULE_REMOTE
struct ev_loop *loop; #endif } server_ctx_t;

下面列出init_udprelay的重要步驟:
* create_server_socket 建立socket並bind,返回fd
* setnonblocking(serverfd);設為非阻塞
* new_server_ctx(serverfd)建立server_ctx_t物件,然後設定屬性:
* ev_io_init(&ctx->io, server_recv_cb, fd, EV_READ); 設定fd的讀事件回撥為server_recv_cb
* server_ctx->timeout = max(timeout, MIN_UDP_TIMEOUT); 設定timeout至少為MIN_UDP_TIMEOUT即10秒
* server_ctx->conn_cache = conn_cache; 設定cache。cache的建立如下:

struct cache *conn_cache;
    cache_create(&conn_cache, MAX_UDP_CONN_NUM, free_cb);
  • 如果是ss-local,設定remote addr:
#ifdef MODULE_LOCAL
    server_ctx->remote_addr     = remote_addr;
    server_ctx->remote_addr_len = remote_addr_len;
  • ev_io_start(loop, &server_ctx->io); 啟動fd上讀事件的監聽
  • 最後返回建立好的serverfd: 對於ss-local,返回的fd被用於通過socks5 response返回給socks5客戶端,socks5客戶端根據這個fd獲取udp server的埠號(因為將ss作為一個Lib使用時,有可能讓系統動態選擇埠號)。而ss-server是不使用這個返回的fd的。
  • init_udprelay執行完成之後,udp server就開始等待讀取來自前端的udp資料了,即有資料可接收時,server_recv_cb會被呼叫。(注:這兒使用前端是因為在同時討論ss-local和ss-server,對於local前端即客戶端,對於server前端即local,下同)

相關推薦

ss-libev 原始碼解析udp (2)

UDP relay的程式碼基本都在udprelay.c中,無論ss-local還是ss-server的程式碼都在一起,使用巨集MODULE_LOCAL,MODULE_REMOTE等區分開。程式碼雖然不是很多,但是由於ss-local和ss-server以及ss-

ss-libev 原始碼解析local(2):ss_local和socks5客戶端握手

上一篇說到ss-libev建立listen_ctx_t物件用於監聽客戶端連線,呼叫accept_cb處理來自客戶端的新連線,建立server_t物件用於處理和客戶端之間的互動。本篇分析來自客戶端的SOCK5連線的建立以及傳輸資料的過程。 首先,回憶一下使用ne

ss-libev 原始碼解析local(5):ss-local之remote_send_cb

remote_send_cb這個回撥函式的工作是將從客戶端收取來的資料轉發給ss-server。在之前閱讀server_recv_cb程式碼時可以看到,在STAGE_STREAM階段有幾種可能都會開啟remote->fd的寫事件的監聽,從而當有寫事件觸發時

myBatis原始碼解析-快取2

上一章分析了mybatis的原始碼的日誌模組,像我們經常說的mybatis一級快取,二級快取,快取究竟在底層是怎樣實現的。此次開始分析快取模組 1. 原始碼位置,mybatis原始碼包位於org.apache.ibatis.cache下,如圖 2. 先從org.apache.ibatis.cache下的cac

C++解析-外傳(2):函式的異常規格說明

0.目錄 1.異常規格說明 2.unexpected() 函式 3.小結 1.異常規格說明 問題: 如何判斷一個函式是否會丟擲異常,以及丟擲哪些異常? C++提供語法用於宣告函式所丟擲的異常 異常宣告作為函式宣告的修飾符,寫在引數列表後面 異常規格說明的意義: 提示函式

dubbo原始碼解析——概要

這次原始碼解析借鑑《肥朝》前輩的dubbo原始碼解析,進行原始碼學習。總結起來就是先總體,後區域性.也就是先把需要注意的概念先丟擲來,把整體架構圖先畫出來.讓讀者拿著"地圖"跟著我的腳步,並且每一步我都

Multibit原始碼解析學習之---傳送比特幣

/**package org.multibit.viewsystem.swing.action; * Complete the transaction to work out the fee) and then show the send bitcoin confirm dialog.

史上最全Universal-Image-Loader原始碼解析————快取

背景 在我寫下這篇部落格的時候,我還是一名二本學校計算機專業大四的應屆畢業生,自學Android開發快兩年了,這兩年的時間裡面,其實真的是感慨萬千,兩年的時間裡面,Android的很多事情也都見識過了,其實Android對於新手入門在就業方面是相當不友好的事情。都說第一個吃螃蟹的人最

Java原始碼解析(7) —— ClassLoader(2)

ClassLoader原始碼解析續 這一部分是ClassLoader核心部分,載入給定的資料成對應的類物件。 /** * 由虛擬機器呼叫,這是一個private方法,但我在ClassLoader原始碼中並未看到有地方呼叫 * 看名字及原始碼說明,是由虛擬

ceph原始碼解析--osd

Ceph分散式檔案系統的程式碼分析的文章網上是比較少的,本團隊成員對ceph做過詳細的程式碼閱讀,包括mds、osd、client等模組,但是缺少條理清晰的文件總結。暫且先放上OSD的程式碼分析,等後續整理陸續放上其它模組的。 1 OSD的基本結構 主要的類,涉及的執行

gcc 原始碼分析-前端2

2. 對ID及保留字的處理    在c語言中,系統預留了很多關鍵字,也被稱為保留字,比如表示資料型別的int,short,char,控制分支執行的if,then等。    任何關鍵字,本質上也是一個ID,比如它也有長度,對int就是3,對short就是5,也有內容,比如in

Andfix熱修復框架原理及原始碼解析-上

1.不知道如何使用的同學,建議看看我上一篇寫的介紹熱補丁和Andfix的使用,這樣你才有一個大概的框架。通過使用Andfix,其實我們心中會有一個大概的輪廓,它的工作原理,大概就是,所謂的補丁檔

ElementUI 簡要原始碼解析——Basic

Layout 佈局 row 佈局元件中的父元件,用於控制子元件。很簡單的一個佈局標籤,主要通過 justify 和 align 控制子元素的對齊方式,使用 render 函式通過傳入的 tag 屬性控制生成的標籤。 在這裡推薦學習下 render 函式和 JSX 的寫法,因為之後比較複雜的元件都是通過 ren

myBatis原始碼解析-日誌(1)

上半年在進行知識儲備,下半年爭取寫一點好的部落格來記錄自己原始碼之路。在學習原始碼的路上也掌握了一些設計模式,可所謂一舉兩得。本次打算寫Mybatis的原始碼解讀。 準備工作 1. 下載mybatis原始碼 下載地址:https://github.com/mybatis/mybatis-3  2.

myBatis原始碼解析-資料來源(3)

前言:我們使用mybatis時,關於資料來源的配置多使用如c3p0,druid等第三方的資料來源。其實mybatis內建了資料來源的實現,提供了連線資料庫,池的功能。在分析了快取和日誌包的原始碼後,接下來分析mybatis中的資料來源實現。 類圖:mybatis中關於資料來源的原始碼包路徑如下:  

myBatis原始碼解析-反射(4)

前沿 前文分析了mybatis的日誌包,快取包,資料來源包。原始碼實在有點難頂,在分析反射包時,花費了較多時間。廢話不多說,開始原始碼之路。 反射包feflection在mybatis路徑如下:      原始碼解析 1  property包-主要對類的屬性進行操作的工

spring原始碼閱讀(2)-aop之原始碼解析

經過一個aop術語介紹和動態代理的深入講解,我們終於可以來看aop的原始碼了,下面跟著博主一點點剖析spring aop原始碼的實現吧 我們知道spring使用中我們只要做好相關的配置,spring自動幫我們做好了代理的相關工作。 我們從三個方面入手吧 1、配置 2、

Spring原始碼解析(二)——元件註冊2

    import com.ken.service.BookService; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.

jquery 1.7.2原始碼解析(二)構造jquery物件

構造jquery物件 jQuery物件是一個類陣列物件。 一)建構函式jQuery() 建構函式的7種用法:   1.jQuery(selector [, context ]) 傳入字串引數:檢查該字串是選擇器表示式還是HTML程式碼。如果是選擇器表示式,則遍歷文件查詢匹配的DOM元

文章徹底讀懂HashMap之HashMap原始碼解析(下)

put函式原始碼解析 //put函式入口,兩個引數:key和value public V put(K key, V value) { /*下面分析這個函式,注意前3個引數,後面 2個引數這裡不太重要,因為所有的put 操作後面的2個引數預設值都一樣 */