Uncategorized

用Range Adaptor,废弃replace_copy_if之类的函数

看看replace_copy_if的一个简单的例子:

std::vector<int> vec;

boost::push_back(rng, std::back_inserter(vec), pred);

对于这种写法,如果使用Range Adaptor的话,则可以写成:

std::vector<int> vec;

boost::push_back(vec, rng | boost::adaptors::replaced_if(pred, new_value));

第二种写法有什么好处呢,

1. 更高效率。因为std::back_inserter有额外的内存分配开销。

2. 更灵活。因为第二种写法可以应用更多的适配器,比如: boost::push_back(vec, rng | boost::adaptors::replaced_if(pred, new_value) | boost::adaptors::reversed);

3. 更安全。因为第二种写法没有用unbounded output iterator。

Be the first to comment - What do you think?  Posted by zausiu - April 15, 2014 at 20:22

Categories: Uncategorized   Tags: ,

抓包程序的一些分享

昨晚同白总和adden提到抓包的问题。因为写过相关的代码,遇到过抓包的各种各样的坑,此文分享一些相关的经验。

 

1. Linux cooked capture

在用tcpdump或wireshark看数据包时,有时会看到数据链路层的的包头称为Linux cooked capture。这不是一个真实的包头,当用tcpdump指定从所有网络介质 -i any 抓包时,所有抓到的包的数据链路层被换成了Linux cooked capture。在wireshark官方网站对Linux cooked capture的解释中: 这是一个在linux上被libpcap抓包库使用的“假协议”(pseudo-protocal),当从“any”设备在抓包,或者本地的数据链路层包头无效时被使用。更多,见http://wiki.wireshark.org/SLL

 

2. IP over IP tunnel

wikipedia的示例图显示IP tunnel上的包的结构是:

但实战中用libpcap库从我们的线上机的IP隧道抓包时,pcap_loop或pcap_dispatch或pcap_next函数返回的数据包只有Inner IP header + IP payload,没有Outer IP headr,也没链路层的头部。多么幸运啊!

 

3. 混乱的RAW_SOCKET,PF_PACKET协议族

这不是工业标准定义的神秘领域,非常之混乱,谨慎进入。如果要写这方面的socket,可供参考。个人经验,用linux原生的socket抓包时,socket()的三的参数如下组合时的神奇效果.

     

        _recv_fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));

        从此socket中读所有的IP包,返回的IP包没有链路层包头,因为第二个参数是SOCK_DGRAM,链路层包头返回时被去掉。第三个参数指定的是IP包。奇怪的是,如果出站的IP包的目的地址不是本机,则出站的IP包不会被抓到。

       

        _recv_fd = socket(AF_PACKET , SOCK_RAW , htons(ETH_P_IP));

        和上一个socket的区别是,这个会返回链路层包头。和上一个socket一样,同样只能装到部分出站的包。

      

            _recv_fd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);

        这行代码只可以读入站的包,抓不到出站的包。

 

            _recv_fd = socket(AF_PACKET , SOCK_RAW , htons(ETH_P_ALL));

        这行代码可以抓到所有出站,入站的包,数据链路层包头也被返回。

 

4. 外网进来的IP包有可能很大。

N多年前一般的路由的MTU只有1K多,意味着4K大小的IP会被切成小IP包。现在的网络环境与几年前确实大大提高。从外网入来的IP包会大过4096,当时写程序时放IP包的buffer大小为4096,觉得应该无压力,结果观察到程序崩溃,后定位到是放IP包的缓冲区溢出。后来改成8192,暂时没问题。

copyright blog.ykyi.net

Be the first to comment - What do you think?  Posted by zausiu - December 26, 2013 at 10:13

Categories: Uncategorized   Tags: ,

CDT调试中的追踪点和断点有什么区别。

追踪点(Tracepoint)被当成断点(breakpoint)的一种,但有两个不同点需要注意:

1. 当一个追踪点在一个调试会话中被创建时,它并不种入到二进制代码中,直到用户显式地开始追踪实验。这意味着,创建/修改/删除追踪点并不影响程序,直到追踪真正开始。

2. 简单的创建一个追踪点并不是非常有价值,因为它默认不会收集任何信息。重要的是,把操作(Actions)添加到Tracepoint,这样tracepoint被触发的时候,前面自定义的Action就大有用处了。

来自CDT官网的原文:

Create Tracepoints

Tracepoints are handled as a type of breakpoint. There are two differences to note:

  1. When a tracepoint is created in a debug session, it is not actually planted in the binary code until the user explicitly starts the tracing experiment. This means that creating/modifying/deleting tracepoints does not affect the program until tracing is actually started.
  2. Simply creating a Tracepoint has very limited value as it won't collect any information by default. It is important to add Actions to the Tracepoint to tell it what to do. This will be explained below.

copyright blog.ykyi.net

Be the first to comment - What do you think?  Posted by zausiu - December 11, 2013 at 10:31

Categories: Uncategorized   Tags: ,

Next Page »