簡體   English   中英

如何在libpcap中檢查數據包可用性

[英]how to check packet availability in libpcap

我使用libpcap捕獲數據包,並且一旦有數據包就需要將其放入FIFO隊列中。 但是FIFO隊列由2個線程共享,一個線程調用pcap_next()並將數據包放入FIFO隊列。 另一個線程從fifo隊列中獲取數據包。 所以我必須將它與互斥鎖聯系起來。 如下所示:

u_char* pkt;
for(;;){
    pkt = pcap_next();
    lock(&mutex);
    some_process(pkt);
    insert(pkt, list);
    unlock(&mutext);
 }

pcap_next()與數據包緩沖區有關,如果緩沖區中沒有數據包,則pcap_next()被阻止。 如果有數據包,則每次調用pcap_next()都會返回1個數據包。

它只能為每個鎖定/解鎖操作對獲取一個數據包,如果數據包到達不頻繁,則可以。 但是,如果數據包到達頻繁,例如在緩沖區中有許多待處理的數據包,那么為一個數據包設置一個鎖定-解鎖操作對會浪費一些資源。

我希望是:在處理並插入數據包之后,我可以立即檢查數據包緩沖區中是否有可用的數據包。 如果有,請繼續處理和插入。 否則,請解鎖互斥鎖並返回循環。

有沒有解決方法?

嘗試諸如

/*
 * XXX - this can fail on some platforms and with some devices,
 * and there may be issues with select() on this.  See the
 * pcap_get_selectable_fd() man page for details.
 */
pcap_fd = pcap_get_selectable_fd(p);
pcap_setnonblock(p);  /* XXX - check for failure */

for (;;) {
    fd_set fdset;
    struct timeval timeout;

    /*
     * Wait for a batch of packets to be available.
     */
    FD_ZERO(&fdset);
    FD_SET(pcap_fd, &fdset);
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    if (select(1, &fdset, NULL, NULL, &timeout) == -1) {
        report an error;
    } else {
        lock(&mutex);
        pcap_dispatch(p, -1, callback, pointer-to-stuff);
        unlock(&mutex);
    }
}

這樣,您可以鎖定互斥鎖,處理整批數據包,然后解鎖互斥鎖。 許多OS捕獲機制會批量分發多個數據包,因此在這種情況下,每批將有一對鎖定/解鎖對。

回調將執行some_process(pkt); insert(pkt, list); 東西。

這是可能的,一旦你有一個批次完成后,下一批將立即提供,所以這並不能達到鎖的絕對最小/解鎖對; 但是,絕對最小值可能會在相當長的一段時間內將另一個線程鎖定,從而使其永遠無法取得任何進展,因此在每個批次周圍鎖定和解鎖可能是最好的。

只需使用pcap_dispatch()或具有非阻塞樣式pcap_next()的select()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM