今天终于把反垃圾邮件加tag设计完。昨天想了一整天出了个demo,今天移植到产品中。
昨天想的有点想吐,到最后时刻大脑已经处于真空状态,似乎一天把脑细胞都用光,坚持着顺着思路,一个个解决关键点问题。最后想通了,脑力也用完了。
好久没有这种入定的感觉,除了午饭,一天基本没有动位置,一个个想,一个个试。除了功能还要考虑如何做性能高,做完一件事容易,做好一件事却很辛苦。
smtp和pop3比较简单,直接在检查出垃圾邮件后找出位置,直接将tag插入skb,做检验和和代理即可。
唯一麻烦点是主题检查和加tag只在当前报文有效,而发送者检查和IP地址检查的时候,需要在流里保存是否需要加tag,做主题检查的时候也要把位置找出来,以备最后加tag用。
imap则要麻烦的多,
1.一个报文里会存在多封邮件,要检查多次,如果多封垃圾邮件,要加多个tag。
2.每封邮件前面的headlen长度,加tag会改变长度,需要修改headlen,像FETCH (...)...BODY[...] {headlen}\r\n...\r\nSubject:...\r\n...。
3.修改长度可能会导致长度进位,也会造成总长度变化。
4.不仅如此,前面的headlen和subject内容还可能会分包,这样遇到headlen的时候就要先缓存下来,在拿到subject后再把它放掉。只可能第一封邮件是分包的。
5.如果多封邮件只有一部分是垃圾邮件,就要根据位置再找他们对应的headlen,而库函数里只有strstr,如果用它来查找headlen,很可能找到的不是他自己的。只好造了一个strrstr根据给出的插入tag的位置,向前查找,则肯定是他自己的headlen,再进行修改。向前找向后找的原理实际是一样的,像fetc在原始串中从前向后找,就是比较f->e->t->c->h,而从后向前则是比较h->c->t->e->f,指针向后倒退,当然要先得知尾端位置,而这个位置在前面可以提供出来,很容易就可以做到。
6.从字符串里把数字取出来相加,判断是否进位后再放回到字符串。用strtol就比sscanf要好,然后再把相加后的值,按字节裸替到skb中, do { i++; ori_val /= 10; } while (ori_val > 0); for (j=i; j>0; j--) { *(s+headlen_idx+j-1) = ('0' + mod_val%10); mod_val /= 10; },这么一搞,如果mod_val还大于零,就说明比原来长,再把长出的一个字节插入skb中即可。
阅读(1244) | 评论(0) | 转发(1) |