自己动手写VPN
自己动手写VPN
brew install tuntapsudo cp -pR /usr/local/Cellar/tuntap/20111101/Library/Extensions/tap.kext /Library/Extensions/sudo cp -pR /usr/local/Cellar/tuntap/20111101/Library/Extensions/tun.kext /Library/Extensions/sudo chown -R root:wheel /Library/Extensions/tap.kextsudo chown -R root:wheel /Library/Extensions/tun.kextsudo touch /Library/Extensions/
安装成功后,执行ls /dev|grep tun
会显示dev目录下多了很多tunX设备。
了解TCP协议
协议层面
学过计算机网络的同学都知道TCP/IP协议的OSI模型。和编程相关的主要是这几层:
- 数据链路层。包含目标机器的MAC地址,负责在两台设备之间传递数据包。
- 网络层。包含目标机器的IP地址,负责路由,确定数据包的下一站是哪台设备。
- 传输层。包含端口号,确定数据发给哪个进程。
TCP协议的复杂之处主要在于处理网络的不稳定性,需要在数据包的投递顺序,可靠性,网络拥堵时的拥塞控制,流控制等方面做大量工作。但作为网络上层开发者,这些都是基础设施,只需大概了解基本原理就可以了。
数据包流程
NIC(网卡)接收到数据包后,通过DMA硬件机制直接把数据包写入内存,并适时(NAPI)通知CPU,CPU(经由Linux内核代码)再把数据包拷贝到内核空间。后续用户态程序要访问数据时(socket调用),通过Linux系统调用(如copy_to_user),把数据从内核态拷贝到用户态,整个网络通信过程存在大量系统调用和数据拷贝,影响了Linux TCP/IP协议栈的性能。
但其实这个消耗是可以避免的,为了解决这个问题有两种方式:
- 零拷贝技术(zero copy networking)。通过packet mmap等方式把内核内存映射到用户空间,避免内存拷贝。
- 把整个TCP/IP协议栈放到用户态来实现(kernel bypass)。如cloudflare的方案。
链接
https://community.openvpn.net/openvpn/wiki/BridgingAndRouting
http://backreference.org/2010/03/26/tuntap-interface-tutorial/
http://www.ibm.com/developerworks/cn/linux/l-tuntap/
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/tuntap.txt?id=HEAD
https://sourceforge.net/p/tuntaposx/code/ci/master/tree/tuntap/
https://github.com/gregnietsky/simpletun
https://github.com/clowwindy/ShadowVPN/wiki/Compared-to-Shadowsocks-and-OpenVPN
https://github.com/neilalexander/sigmavpn-android
https://android.googlesource.com/platform/development/+/master/samples/ToyVpn
https://hengyunabc.github.io/something-about-science-surf-the-internet/
http://www.tcpdump.org/pcap.html
https://github.com/kaitoy/pcap4j
https://github.com/kaitoy/pcap4j/blob/v1/www/Packet.md
Multiqueue support in tun/tap https://lwn.net/Articles/459270/
Page-Flip Technology for use within the Linux Networking Stack http://www.landley.net/kdocs/ols/2004/ols2004v2-pages-175-180.pdf
https://github.com/wallnerryan/floodlight/blob/master/src/main/java/net/floodlightcontroller/packet/IPv4.java#L289
https://github.com/andiwand/packetsocket/blob/master/src/at/stefl/packetsocket/pdu/IPv4Packet.java
https://kaitoy.github.io/pcap4j/javadoc/latest/en/org/pcap4j/packet/IpV4Packet.Builder.html
https://gist.github.com/wuhx/0c6712904b080769123f
http://www.cubrid.org/blog/dev-platform/understanding-tcp-ip-network-stack/
https://www.usenix.org/conference/nsdi14/technical-sessions/presentation/jeong
Layer-3 forwarding
http://www.pearsonitcertification.com/articles/article.aspx?p=2434069
Why TCP Over TCP Is A Bad Idea
http://sites.inka.de/bigred/devel/tcp-tcp.html