OpenVPN在help中列举了push-peer-info选项,可是man手册中却没有,google之,发现了以下的帖子以及回复:
Subject:how to use --push-peer-info under 2.2-RC2?
Flow:
I'm testing out 2.2-RC2 under Linux - installed on both client and server (--help shows it's there too). I have add "push-peer-info" to the client, and have up/down
scripts on the server that include a printenv line to capture environment variables. However, I'm not seeing any new vars showing up.
So can someone tell me where does that detail show up on the server?
Subject:how to use --push-peer-info under 2.2-RC2?
Flow:
AFAIK (and AFAICT from looking at the sources) the 'push-peer-info' option is not complete yet. The *client* side works, but the server never extracts the right UV_*
variables which are pushed out by the client to the server.
November last year I asked the -devel list what this option is supposed to do ; the result of that discussion was that "this is a work in progress" :-/
根据这个帖子,是否可以说OpenVPN对于push-peer-info的实现是个半吊子实现呢?实际上确实有点这个意思。可是这么做并没有什么不妥,永远不要指望开源代码能做到完美实现你的任意需求,人家开发者没有义务这么做。代码在自己手上,如果你看懂了逻辑,自己修改一下使之符合自己的需求便是了。唯一的问题就是将来有一天,他们实现了你现在通过修改代码实现的功能,你还要花一些时间来合并自己的实现和新版本的实现,有时候你要丢弃你的所有修改。
key_method_2_write中无条件的调用了push_peer_info,而key_method_2_read有条件的读取了这个peer-info,先是一个if判断:
if (session->opt->auth_user_pass_verify_script
|| plugin_defined (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY)
|| man_def_auth == KMDA_DEF)
在该if分支中又有一个宏:
#ifdef MANAGEMENT_DEF_AUTH
/* get peer info from control channel */
free (multi->peer_info);
multi->peer_info = read_string_alloc (buf);
…
#endif
也就是说,只有进入上述if分支,并且在定义了MANAGEMENT_DEF_AUTH宏的情况下,客户端发送的peer-info才会被读取并且赋值给只有在MANAGEMENT_DEF_AUTH被定义时才有的multi_instance的字段peer_info。
这种处理的不对称性其实是有原因的,因为发送端无论如何都发送信息总是不会错的,接收端若需要可以接收,若不需要可以不接收或者接收后丢弃之,因此发送端就无条 件发送,而接收端则是根据策略有条件接收。这本身并没有什么错。
然而在使用上这个in progress的实现让人误解不浅,一个小小的选项,让人费心伤神,实在不值得。好在可以修改并重新编译它的代码,这是使用开源框架最好的地方。
OpenVPN作为一款开源的可定制的,功能超强大且配置简单的VPN,其学习曲线看似平缓,然而要挖掘其深层次的功能,你不得不多花一些时间来研究它,首先你要理解 IP网络的方方面面,且要理解以太网的种种,然后花些时间研究一下它的源码,事实上,研究源码是最后的工作,如果连原理都不懂,研究源码很容易进入死胡同的。
作为一个阶段性的小结,我对OpenVPN进行了一次总结,除了其SSL,PKI,虚拟网卡等显著优势之外,OpenVPN的高级路由技术还有很多细节可挖掘,此外在实现细节上,使用OpenSSL的BIO来读写控制数据也是亮点,使用BIO很容易实现OpenVPN的协议封装,它使得数据可以被写入任意位置而不仅仅写入到内核的文件描述符所指示的内核缓冲区,要知道数据一旦进入了内核,你就不可再控制它了,如果想再封装它,只有两个办法,一个办法是编写内核模块,另一个方法就是把它再次引出来…其中Netfilter以及分层文件系统驱动是前者的典型例子,而虚拟网卡技术是后者的典型例子,说白了关于框架的种种就是这样,原理很简单,只要理解了你就最好实现它,而实现它就完全属于另一个领域了,那就是编程技术,要写出可读性强的代码,要写出可维护的代码,要写出可扩展的代码,你需要权衡使用什么数据结构,需要考虑使用什么算法,需要在时间复杂度和空间复杂度中二选一或者兼而有之,保持两全不能其美的平衡,需要足够OO又不过度设计,需要尽可能利用已有的稳定的实现而不是重新造轮子。