八月依然有些很狗血的策划案要做,以至于花了两周时间,周五做出来后,连策划自己都觉得配置超多超复杂。。。
这个月比较过瘾的,是下决心做了dns的实验。当时为了防止DNS污染,曾经用Python写过一个DNS代理,通过TCP管道传输解析包,避免墙的干扰,地址在google code。项目原本是通过丢弃最先返回的udp包来实现的,后来改为了TCP查询。不过,当时硬着头皮读的RFC1035,只读懂了TCP的部分,只要将接收到的包体加上长度作为包头,就可以直接丢到TCP管道的另一端,解包也是根据包头解出DNS返回包,送回到查询者即可。
于是,这个月就再重读了一次RFC,实现了一个基本的域名=>dns查询工具,地址在github。真正实现的时候,RFC文档还是很实用的,尤其是里面查询结构的定义,相当清晰。就是在python里不大好处理位,需要自己做与运算。实现时有个问题不是很明白,为什么域名要分成label这样的短字符串来实现,搞的一个域名有可能用了3个字节,只是用来分别标记3个label各自的长度呢?后面有提到域名label的复用机制,但是这个和一个完整字符串是不矛盾的啊。Anyway,这种jump指针的实现的确很巧妙,甚为折服。调试的时候,还初步学会了使用scapy工具,碉堡了。可以输入RFC里面的各种参数来构造一个包,还能打印出包体的字符串表示,通过对比很快知道了自己实现的缺陷所在。最爽的是还能从IP包构建到UDP包,通过 IP包/UDP包 这种表示来表达payload的意思,有空用来写个TCPkill玩玩,哈哈。
另一件,是参与到晓靖的levent项目里。levent在Lua里基本复刻出python的gevent,顺带创建了自己的类机制,还有一些非常实用的库比如struct(跟python的struct相仿)。随手写了两个示例,一个是负责端口转发的portforward,另一个是http代理。写端口转发的时候,竟然有种写golang的感觉,一个lua的coroutine,就好比一个golang的goroutine。针对一个socket起了两个协程,一个负责读,一个负责写,在虚拟机里跑能有2000多的qps,还算不错。对比gevent,gevent一开始能够上3000多,不过越跑越慢,最后完全跑不动了。用的是示例里的echo server,测试用的redis benchmark。http代理的实现,参考了PythonProxy的实现。对于1.0的http协议,只支持了GET,POST等有限几种方法。除了CONNECT方法外,基本都是改写一下头部,丢过去服务器就可以了。CONNECT方法更简单,连接后直接作为管道转发数据,连header都不用改写了。。。
希望接下来的9月顺顺利利啊