还记得以下这张图吗?我暂且叫它版本号1:
起初,我一直以为画完这幅图就已经证明自己对OpenVPN非常精通了,后来我慢慢知道我错了,于是,我画出以下这幅图的时候,事实证明我当初的理解是多么肤浅!以下这幅图我称为版本号2:
版本号1的出现是在2012年,那说明我对原生的OpenVPN已经有了比較深刻的理解,可是在经历了2012的后半年,2013年的整年,2014年的上半年,我一直在等待OpenVPN的更新升级,这期间我也一直在关注硬件和网络技术的进展,OpenVPN落后了,谁也没有提到过这一点,等到了2014年的农历年前后,我认为我该做点什么了。就这样,出现了版本号2。假设说之前的文章展示的都是设想,那么有了这副版本号2之后,它就是一个实际的实现了,尽管是最简的实现。眼下还有非常多TODO:
1.眼下每个multi_instance仅仅能由一个线程的multi_context处理。
当初我希望的是全部的线程都能处理全部的multi_instance,可是由于如此一来锁开销太大,仅仅有作罢。事实上OpenVPN的原生架构非常难实现多线程扩展,由于每个multi_instance都有一个buff,每个context也有一个buff,每个multi_context的全部instance共享一个buff,这些buff被复制来复制去,非常难实现细粒度的锁,由于你非常难定义什么是一个不可打断的事务。
2.眼下的多队列TUN驱动在返回包队列分发的实现有些粗糙。
3.TUN驱动模块和OpenVPN之间的耦合度太高,不利于分别扩展升级。
4.线程间的信号分发机制太粗糙。
5.假设OpenVPN的某个线程从tun收到一个广播包,分发效率太低。
6.client无法实现多进程打开同一个虚拟网卡,而仅仅能捆绑多个虚拟网卡。
...
以上这些都是须要慢慢完好的。我希望自己不会就此作罢,也希望和高手们进一步交流。
在实现的过程中,遇到过无数的问题,和起初设计的时候想象的根本不一样,非常多细节都没有考虑到。比方tap的ARP广播分发问题,当时我认为随便分发到一个线程就可以,后来发生了无数次的段错误,assert失败...最终发现,即使是ARP也没有什么特殊的,仅仅要解析出ARP的内容中的sip和dip就可以,将它和IP报文相同对待...
还是那句话,假设你能画一张图把一个技术展示明确,那么你绝对掌握了这项技术,假设你绘图的过程中,突然不知道怎么画了,那么这点就是你的技术盲点。不要抱怨不会用绘图软件,纸笔侍奉,手绘就可以。手绘图更能让你的精力集中在图本身而不是绘图软件怎么用,由于你用你的脑子驱使你的手,借助笔的硬度和铅,墨水等在纸上留下痕迹,你的大脑全然起100%的作用,反之你用绘图软件的话,你必须通过电脑的CPU芯片,即你必须想办法告诉CPU怎样展示你脑子里想象的图像,而CPU却并不如纸和笔那样做你的奴隶,反之,你要迎合它的规则...说了这么多,事实上我想说的是,版本号1的最初版就是我手绘的,例如以下图所看到的:
最后,不要索要代码,代码通过邮件,QQ分发是一种不正规且不优雅的传播方式,这是Linus的观点,我非常认同。假设你感兴趣,你一定能找到或者写出想要的代码,或者说,你或许能帮到我。