go版本shadowsocks原始碼 終章

2021-10-10 04:02:07 字數 3945 閱讀 7143

本節我們來看一下shadowsocks-server端的原始碼。server端相比local端要簡單不少,其所做的主要工作就是解碼請求並返回結果。

照例我們從main函式開始分析其大致流程。

func

main()

ss.setdebug

(debug)

var err error

config, err = ss.

parseconfig

(configfile)

if err !=

nil config =

&cmdconfig

ss.updateconfig

(config, config)

}else

if config.method ==

""if err = ss.

checkciphermethod

(config.method)

; err !=

nilif err =

unifyportpassword

(config)

; err !=

nilif core >

0for port, password :=

range config.portpassword

}if manageraddr !=

"" conn, err := net.

listenudp

("udp"

, addr)

if err !=

nil log.

printf

("manager listening udp addr %v ...\n"

, manageraddr)

defer conn.

close()

gomanagerdaemon

(conn)

}waitsignal()

}

從以上**中可以看到,server端main函式大體也分成三個部分,第乙個部分負責處理一系列的配置檔案解析,引數校驗等。第二部分處理連線請求。第三部分為對server啟動後進行的實時線上管理進行操作。

flag.

boolvar

(&printver,

"version"

,false

,"print version"

) flag.

strin**ar

(&configfile,

"c",

"config.json"

,"specify config file"

) flag.

strin**ar

(&cmdconfig.password,

"k","",

"password"

) flag.

intvar

(&cmdconfig.serverport,

"p",0,

"server port"

) flag.

intvar

(&cmdconfig.timeout,

"t",

300,

"timeout in seconds"

) flag.

strin**ar

(&cmdconfig.method,

"m","",

"encryption method, default: aes-256-cfb"

) flag.

intvar

(&core,

"core",0

,"maximum number of cpu cores to use, default is determinied by go runtime"

) flag.

boolvar((

*bool)(

&debug)

,"d"

,false

,"print debug message"

) flag.

boolvar((

*bool)(

&sanitizeips)

,"a"

,false

,"anonymize client ip addresses in all output"

) flag.

boolvar

(&udp,

"u",

false

,"udp relay"

) flag.

strin**ar

(&manageraddr,

"manager-address",""

,"shadowsocks manager listening address"

) flag.

parse

()

這一部分個人感覺其實沒什麼,設定專案基本和local端保持一致。其中對於c pu的設定這裡需要提一下,這是對於goroutine的設定,表示對於go邏輯處理器的分配。以及增加對於server執行時的管理設定。

for port, password :=

range config.portpassword

}

正如**1-6行所示,根據配置的情況,server會處理多個埠的請求。由於支援了udp的socks**加入udp判斷,如果設定了udp**,則進行udp的**。

func run(port, password string) 

passwdmanager.add(port, password, ln)

var cipher *ss.cipher

log.printf("server listening port %v ...\n", port)

for

// creating cipher upon first connection.

if cipher == nil

} go handleconnection(ss.newconn(conn, cipher.copy()), port)

}}

run()函式主要負責監聽本地介面等待連線,隨後啟動乙個goroutine 來執行handleconnection()處理到來的連線請求。

server對於請求的處理流程與local幾乎相同,除了記錄的日誌資訊不同。首先獲取請求的目標位址,然後進行連線請求,最後建立兩個pipethenclose進行上行下行資料的傳輸,同時進行對資料的解密操作。整體流程如下:

if manageraddr != "" 

conn, err := net.listenudp("udp", addr)

if err != nil

log.printf("manager listening udp addr %v ...\n", manageraddr)

defer conn.close()

go managerdaemon(conn)

}

對於shadowsocks的管理如果進行了設定,則會使用乙個goroutine執行managerdaemon()進行守護相關埠的監聽,返回shadowsocks的運**況。其中包括其流量連線情況:

for

_, addr :=

range reportconnset

conn.

writetoudp

(res, addr)

}

switch
至此整個shadowsocks的原始碼,大體上就分析完了。由於想基於一種全域性的觀點,所以一些極其細節的**沒有去閱讀,重點其實還是在理解go語言在實際專案中的一些應用。

在main函式的最後,設定了乙個waitsignal()用來等待signal訊號,當捕捉到該訊號後進行updatepasswd等操作,以便於server程式結束前的收尾操作

centos系統shadowsocks搭建

輸入shadowsocks服務密碼 2.輸入ahadowsocks服務埠號 3.選擇假加密方式 如常用的 7 aes 256 cfb 4.最終配置 1.shadowsocks 配置檔案 vim etc shadowsocks.json 單埠 多埠 timeout 300,method aes 256...

go版本gRPC入門

本文通過乙個簡單的示例,了解如何在go中使用grpc。使用命令列安裝 使用以下命令安裝grpc go get google.golang.org grpc 獲取編譯器外掛程式protoc gen go,並將其安裝在 gobin路徑中,預設為 gopath bin。5 必須設定好 path環境變數,協...

Go 各版本特性

最新的go版本1.11版本在go 1.10之後六個月到達。它的大部分變化都在於工具鏈,執行時和庫的實現。與往常一樣,該版本保持了go 1 的相容性承諾。我們希望幾乎所有的go程式都能像以前一樣繼續編譯和執行。最新的go版本1.10版本在go 1.9發布六個月後推出。它的大部分變化都在於工具鏈,執行時...