Mam program, który wysyła zestaw pakietów TCP SYN do hosta (przy użyciu nieprzetworzonych gniazd) i używa libpcap
(z filtrem) w celu uzyskania odpowiedzi. Próbuję zaimplementować to w asynchronicznej strukturze we/wy, ale wydaje się, że brakuje niektórych odpowiedzi (mianowicie pierwszych pakietów z serii, gdy zajmuje ona mniej niż 100 microseconds
między TCP SYN a odpowiedzią). Uchwyt pcap jest ustawiony tak:Asynchroniczna libpcap: utrata pakietów?
pcap_t* pcap = pcap_open_live(NULL, -1, false, -1, errorBuffer);
pcap_setnonblock(pcap, true, errorBuffer);
Następnie dodaję filtr (zawartej na strunie filterExpression):
struct bpf_program filter;
pcap_compile(pcap, &filter, filterExpression.c_str(), false, 0);
pcap_setfilter(pcap, &filter);
pcap_freecode(&filter);
A na pętli, po wysłaniu każdego pakietu, używam wybierz wiedzieć jeśli mogę odczytać z libpcap:
int pcapFd = pcap_get_selectable_fd(pcap);
fd_set fdRead;
FD_ZERO(&fdRead);
FD_SET(pcapFd, &fdRead);
select(pcapFd + 1, &fdRead, NULL, NULL, &selectTimeout);
i przeczytać:
if (FD_ISSET(pcapFd, &fdRead)) {
struct pcap_pkthdr* pktHeader;
const u_char* pktData;
if (pcap_next_ex(pcap, &pktHeader, &pktData) > 0) {
// Process received response.
}
else {
// Nothing to receive (or error).
}
}
Jak już wcześniej wspomniałem, niektóre pakiety są pomijane (wchodząc w "nic do odbioru"). Wiem, że te pakiety istnieją, ponieważ mogę je przechwytywać synchronicznie (używając tcpdump
lub wątku z uruchomioną pcap_loop
). Czy brakuje tu jakiegoś szczegółu? Czy to jest problem z libpcap
?
Może się zdarzyć, że wysyłasz zbyt wiele żądań zbyt szybko, a serwer wysyła odpowiedzi szybciej, niż można sobie z nimi poradzić, co powoduje przeciążenie bufora sieciowego systemu operacyjnego i upuszczenie pakietów. Możliwe też, że gniazdo odbiornika nie zostanie skonfigurowane na czas, aby obsłużyć początkowe odpowiedzi. Czy możesz zweryfikować, że wszystkie odpowiedzi, które przyjmujesz, faktycznie się tam dostają? Todo to uruchom tcpdump na tym samym interfejsie co aplikacja jednocześnie.Jeśli zobaczysz wszystkie pakiety, których oczekujesz w tcpdump, a nie w twojej aplikacji, możesz mieć jeden z powyższych problemów. – ryanbwork
Już to zrobiłem (tcpdump na boku, ale także pcap_loop inny wątek) i wszystkie pakiety tam były. Dlatego nie sądzę, żebym wysyłał odpowiedzi zbyt szybko. Jak mogę sprawdzić, czy moje gniazdo odbiornika (tj. Libpcap) nie jest jeszcze skonfigurowane? Miałoby to sens, ponieważ utracone odpowiedzi są zawsze pierwszym lub dwoma. –
Nawet jeśli zobaczysz pakiety w tcpdump, mogą one zostać usunięte przez system operacyjny, jeśli twoja aplikacja nie będzie w stanie obsłużyć stawki, z jaką są odbierane. Jeśli twoja aplikacja zaczyna się po wysłaniu odpowiedzi, spróbuj dodać znaczne opóźnienie przed wysłaniem początkowej odpowiedzi z serwera; jeśli pomyślnie otrzymasz wszystkie odpowiedzi, znajdziesz swój problem. – ryanbwork