这个月主要在搞两件事,其一是:https://github.com/spin6lock/pydnsproxy,其二是一个bt客户端,用来搜索磁力链接,下载种子的,还没搞好。
pydnsproxy在去年的《忙里偷闲的八月》里已经有提及,不过当时居然没发现几个明显的bug。之前是因为Queue的用法不对,初始化的时候,没有赋予有效的长度,导致每次将用完的tcp链接塞进去,都会报队列已满,然后被抛弃掉。也就是说,每一次tcp查询基本都是重新创建链接。这样查询代价会很大,一般到400-500ms了。之前的缓存方式也有问题,没有考虑到Handler类这种用法,每次收到一个请求,handler就会被实例化一次。而上一个版本的实现里,cache是放在handler类上的,依赖于handler的生命周期。现在因为TCP_HANDLE是作为一个方法类来引入,所以没问题了,下一步应该将cache变为模块变量。
除了bug修复,就是给pydnsproxy添加了http dns的解析方式,这种方式的优势,可参考企鹅的【鹅厂网事】全局精确流量调度新思路-HttpDNS服务详解。简单来说,就是抛开原有的dns协议,直接提供一个http接口,给出域名,返回对应ip。额外参数还包括请求ip,可以根据请求ip的不同解析出不同的ip地址。暂时看来,没有受到墙的干扰,可以一用。说到底,其实需要的是一根管道,可以顺利到墙外而不受干扰。具体的解析方式,反倒是其次了。像企鹅这种大公司,维持一条稳定的加密通道毫无问题,于是顺便利用其httpdns来避免投毒污染了。实现的时候,有考虑过tcp连接池的问题,貌似urllib2没有这么高级的功能,只有urllib3才提供PoolManager。但是,实测发现,httpdns的查询也就在20ms附近,虽然比缓存的5ms要慢一点,但完全可以接受,这个值得再观察一下。
bt客户端的实现,组织好KTable,KBucket,KNode,似乎就差不多了。这次重拾python来实现,比之前半途而废的go版本,要顺利多了。遇到的问题有两点,一个是KBucket什么时候分裂,怎么分裂。这个会影响程序长时间运行,所占用的内存大小。另外一个,是跟其他客户端连接时,报文错误的问题,目前倾向于对方的实现有问题,因为其他客户端都能成功应答了。因为还没完成,代码就没有提交。