一种实现无级变速代理的好方法

之前工作中遇到了一个TCP代理前后端不匹配的情形,导致连接总是超时断开,完全不可用,解决办法很简单,要么加大前端网络的带宽,要么对后端快速网络限速(TC限速,缩小MTU,缩小TCP接收窗口均可)。之所以要这么复杂是因为代理程序实现得不好,后来看了stunnel的代码,发现stunnel的方式反而更好,虽然它只是一个超级轻量级的代理。
       stunnel的代码被认为非常适合学习之用,在大的系统上还是不能登入大雅之堂,然而正是因为它的简单,才更能让人理解本质。我个人倾向于按照需求自己先想一套解决方案,然后再去和标准的已经有的实现去对照,stunnel的无极变速实现对我而言十分巧妙,也符合个人的喜好,因此就不再自己实现一套了,再说相对于Netfilter之类的,搞TCP代理实在是为难老夫了...于是直接拿来!
       将stunnel的实现当成自己的了,这种行为真实的无耻,哪怕是加一行注释也罢啊。不甘心中我也就在到处找寻更好的方式,突然就想到了多年前还是个书生时的读核经验,那时也是看代码,分析代码,挑刺儿,较真儿,往坑里掉...那时没有现在这么愤青,虽然挺悲哀,但是毕竟也是那么过来的啊。看过splice系统调用,详细分析了它的实现,当时也觉得自己看懂了,由于splice是新的调用,我竟然拿它和老式的sendfile做了好一番比较,太悲哀了...如今突然就冒出来了,为什么不试试sendfile呢?
       锅里面炖着肉,自己写着代码,一个代理程序很快就完成了,没有调用传统的poll->recv/send,而是直接poll->sendfile!程序异常简洁,没有任何定义的buffer,直接用sendfile将后端TCP来的数据写到前端的TCP中,代码少于100行!数据根本就无需进入程序,直接在内核中就被转走了,用户态程序只是简单的用poll获知有数据来了,此时就用NULL pos调用一次sendfile,内核自动的维护ppos的前移,真是太帅了。翻开几年前的分析,发现sendfile的实现就是stunnel缓冲区维护方式的内核版本,或者反过来说,stunnel的缓冲区维护方式是sendfile的用户态版本,只是几年前,我还不知道什么是stunnel,那时,啃那些无用的代码,看了很多无用的书,最终才发现,书上得来终觉浅,笔不敌剑!以下的亮点:
if (!ppos)
        ppos = &in_file->f_pos;
事隔多年了,还是亮点!
       sendfile,tee,splice,stunnel,是简单的真理就在众生面前呢,还是英雄所见略同?

你可能感兴趣的:(一种实现无级变速代理的好方法)