自己动手写VPN  

JerryXia 发表于 , 阅读 (0)
02 June 2016

自己动手写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模型。和编程相关的主要是这几层:

  1. 数据链路层。包含目标机器的MAC地址,负责在两台设备之间传递数据包。
  2. 网络层。包含目标机器的IP地址,负责路由,确定数据包的下一站是哪台设备。
  3. 传输层。包含端口号,确定数据发给哪个进程。

TCP协议的复杂之处主要在于处理网络的不稳定性,需要在数据包的投递顺序,可靠性,网络拥堵时的拥塞控制,流控制等方面做大量工作。但作为网络上层开发者,这些都是基础设施,只需大概了解基本原理就可以了。

数据包流程

NIC(网卡)接收到数据包后,通过DMA硬件机制直接把数据包写入内存,并适时(NAPI)通知CPU,CPU(经由Linux内核代码)再把数据包拷贝到内核空间。后续用户态程序要访问数据时(socket调用),通过Linux系统调用(如copy_to_user),把数据从内核态拷贝到用户态,整个网络通信过程存在大量系统调用和数据拷贝,影响了Linux TCP/IP协议栈的性能。

但其实这个消耗是可以避免的,为了解决这个问题有两种方式:

  1. 零拷贝技术(zero copy networking)。通过packet mmap等方式把内核内存映射到用户空间,避免内存拷贝。
  2. 把整个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