文章

顯示從 六月, 2021 起發佈的文章

純用戶態的DN42節點(尚未完成,心路歷程)

圖片
起因是有一台免費docker小雞,給的權限有夠小。沒有tun/tap,沒有wireguard。但是我想讓它運作成一台dn42節點。 理想中的這隻程式,對外維持許多wireguard session,沒別的東西了。 對內則是維護一個network stack,wg解包出來丟進stack,經過BGP daemon+routing以後跑去另一個wireguard。在這之中完全沒有kernel的參與 我在想,路由這些東西都在kernel實現,就沒有在userspace實現的版本嗎? 我查了查,許多用戶態的network stack還不少。但是有一個吸引了我的注意: fd.io/VPP。 因為linux kernel網卡驅動模型的特性,每個packet都是一個CPU中斷,注定快不起來。所以有人搞了個DPDK,讓網卡封包直接跑去userspace,就不會有那麼多中斷。不過這樣就要有用戶態的封包處理程式。於是就有了fd.io/VPP 不過以上都不是重點,我會看上fd.io/VPP是因為它有個神奇的操作,利用LD_PRELOAD,劫持掉普通應用程式的socket, bind, getsockname, if_nametoindex, sendmsg, recvmsg等等syscall,redirect去VPP裡面的network stack。這樣就可以不用patch,直接運作就能讓任意程式加入自己的網路,而不是用kernel提供的網路的。聽說這個技巧叫做kernel bypass。這正是我需要的,bypass掉那該死的kernel VPP是為了性能而誕生,但我這裡完全不是為了這個。 VPP的正常用法,是搭配下層搭配DPDK,上層劫持socket api,讓普通讀程式可以連入DPDK網路 但是我只是想要他的用戶態網路堆疊的處理能力,再用memif把流量送到wireguard-go。讓這台沒權限的docker裡面的任意app加入dn42網路 後來有群友推薦,可以嘗試gvisor。他是用ptrace來達到kernel bypass的效果。雖然我這台docker VPS有開放ptrace權限,不過普通的docker預設是不開放的。 在弄的時候果然還是希望成品能盡量支援多一點的地方,所以有ld_preload實現地會被我優先考慮。目前我看到有ld_preload實現的只有2個,VPP和NUS