• tcprstat源码分析之tcp数据包分析


    tcprstat是percona用来监测mysql响应时间的。不过对于任何运行在TCP协议上的响应时间,都可以用。本文主要做源码分析,如何使用tcprstat请大家查看博文《tcprstat分析服务的响应速度利器

    tcprstat和tcpdump一样,使用libpcap库进行抓包,然后再通过程序对抓取的tcp包进行分析。
    tcprstat对tcp包分析的大概流程如下:
    process_ip
    1、通过分析来源ip和目标ip,看那个ip是本地ip,来判断是进来的包(请求包)还是出去的包(响应包)。
    2、如果包的数据大小为0,那么就跳过,不再处理。数据大小为0的视为tcp控制包。
    3、如果数据包为进来的包(请求包),则插入一条记录到哈希表。
    4、如果数据包为出去的包(响应包),则用现在的包和之前插入哈希表中的响应包做时间差计算。并把之前的包在哈希表中删除。

    数据包分析的代码在process-packet.c文件中,方法如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    int
    process_ip(pcap_t *dev, const struct ip *ip, struct timeval tv) {
        char src[16], dst[16], *addr;
        int incoming;
        unsigned len;
         
        addr = inet_ntoa(ip->ip_src);
        strncpy(src, addr, 15);
        src[15] = '';
         
        addr = inet_ntoa(ip->ip_dst);
        strncpy(dst, addr, 15);
        dst[15] = '';
         
        if (is_local_address(ip->ip_src))
            incoming = 0;
        else if (is_local_address(ip->ip_dst))
            incoming = 1;
        else
            return 1;
         
        len = htons(ip->ip_len);
         
        switch (ip->ip_p) {
            struct tcphdr *tcp;
            uint16_t sport, dport, lport, rport;
            unsigned datalen;
         
        case IPPROTO_TCP:
            tcp = (struct tcphdr *) ((unsigned char *) ip + sizeof(struct ip));
             
    #if defined(__FAVOR_BSD)
            sport = ntohs(tcp->th_sport);
            dport = ntohs(tcp->th_dport);
            datalen = len - sizeof(struct ip) - tcp->th_off * 4;    // 4 bits offset
    #else
            sport = ntohs(tcp->source);
            dport = ntohs(tcp->dest);
            datalen = len - sizeof(struct ip) - tcp->doff * 4;
    #endif
     
            // Capture only "data" packets, ignore TCP control
            if (datalen == 0)
                break;
     
            if (incoming) {
                lport = dport;
                rport = sport;
                 
                inbound(tv, ip->ip_dst, ip->ip_src, lport, rport);
                 
            }
            else {
                lport = sport;
                rport = dport;
                 
                outbound(tv, ip->ip_src, ip->ip_dst, lport, rport);
                 
            }
     
            break;
             
        default:
            break;
             
        }
         
        return 0;
         
    }

    ps:在这个文件中,process_packet 方法用户获取头信息。

  • 相关阅读:
    Java学习---Java代码编写规范
    移动端与Web端疫情数据展示
    Java实现邮箱验证码
    Java实现短信验证码
    利用Jsoup爬取新冠疫情数据并存至数据库
    echarts全国疫情统计可视化地图(第一阶段)
    构建之法阅读笔记04
    HDU 4628 Pieces(状压DP)题解
    ZOJ 2563 Long Dominoes(状压DP)题解
    POJ 2288 Islands and Bridges(状压DP)题解
  • 原文地址:https://www.cnblogs.com/yuyue2014/p/5439630.html
Copyright © 2020-2023  润新知