Ok, So I just stumbled into a "sort of" solution. I have to do a wide-spread test, first, to see if this is really a fix:
I just set my timeout to 1ms using pcap_set_timeout, I then added the following to my callback: void processSingleImage(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { GT_DataOperation *dataOp = (GT_DataOperation *)args; static int count = 0; count++; if (count == rtoDataOp->totalBlockCount) { count = 0; pcap_breakloop(dataOp->handle); } } Basically, I count blocks until I get everything that I need. At that point, I do a breakloop. This seems to eliminate the timeout issue I saw. Now, however, I am concerned that the timeout is going to have to be adjusted to some value that at is "One Size Fits All". Naturally a number that degrades performance for all of my users. I tried a timeout of 0, using pcap_set_timeout. But this ever called my callback. I am curious to know if anyone has any thoughts.. Thanks! bob. On Mar 24, 2013, at 7:51 PM, Robert Monaghan wrote: > Hi Everyone! > > I am using the built in Libpcap library that comes with MacOSX. (MacOSX > 10.8.3) > > I have set up a background GCD dispatch queue, where the libpcap is set up > and waits for packets to arrive on my 10Gig card. > > The code is very trivial, and appears as if it should works well.. > Here is the problem. > > I am using "pcap_loop" to grab a specific number of packets. This is set up > using a snap size of 1504 (To match the packet size from my hardware device.) > The buffer is large, about 1Mb in size. I have the "pcap_loop" code in > "blocking" mode, so that I can wait for all of the packets to finish, before > triggering a semaphore. > > When I start the pcap_loop to do its work, which grabs exactly 1879 packets. > (Precisely the number I am asking for.) I end up with a timeout being called. > (I know this is a timeout, because if I change the timeout value in > "pcap_open_live", the timeout matches the duration that I set.) As a test, I > decide to trim the number of packets used in pcap_loop by 160, and everything > speeds up dramatically! Absolutely no timeouts. Anything less that 159 > packets (determined by trial & error), the time out occurs. > > This isn't the only size, either. > > Now I download another (smaller) set of data, this time I download only 782 > packets. This download starts to timeout, as well! (Even though the 1700 or > so, packet downloaded just fine!) If I trim it by about 97 packet, the > system no longer times out. > > Weird. > > Just for fun, I tried an really large data set, at 3130 packets. As expected > it stalls. But again, trimming about 200 packets removes the stall, and it > moves the data extremely quickly. > > If I use pcap_stats immediately after the pcap_loop, I see that in both fast > and timed out situations, that I don't drop any packets. > The only issue seems to be that the timeout is triggered. > > I am at a loss on this one. I have tried changing the 'snaplen' size, and > altered the timeout, but i can't seem to see where the problem is. > This works if I trim the number of packets read, but slows down dramatically, > if I do the full amount of packets requested. > I have also switched over to pcap_create and the assorted pcap_set commands > to try to noodle with settings. > I have even set different buffersizes with sysctl debug.bpf_bufsize and > maxbufsize. No luck there, either. > > Can anyone make a suggestion? > > Should I ditch the built in MacOSX libpcap and compile the one available from > the tcpdump repository? > > > Attached is the relevant code: > > char filter_exp[] = "ether proto 0x7777"; > > char errbuf[PCAP_ERRBUF_SIZE] = {0}; > int buffersize = (int)(1048576); > //handle = pcap_open_live([ethernetInterface > cStringUsingEncoding:NSASCIIStringEncoding], 65536 * 2, 0, 1000, errbuf); > > handle = pcap_create([ethernetInterface > cStringUsingEncoding:NSASCIIStringEncoding], errbuf); > > if (handle != NULL) { > //pcap_set_promisc(handle, 0); > pcap_set_timeout(handle, 1000); > //pcap_setdirection(handle, PCAP_D_IN); > pcap_set_snaplen(handle, 1504); > pcap_set_buffer_size(handle, buffersize); > //pcap_set_rfmon(handle, 0); > pcap_activate(handle); > > /* compile the filter expression */ > bpf_u_int32 mask = 0xffff0000; > if (pcap_compile(handle, &fp, filter_exp, 1, mask) == -1) { > fprintf(stderr, "Couldn't parse filter %s: %s\n", > filter_exp, pcap_geterr(handle)); > exit(EXIT_FAILURE); > } > > /* apply the compiled filter */ > if (pcap_setfilter(handle, &fp) == -1) { > fprintf(stderr, "Couldn't install filter %s: %s\n", > filter_exp, pcap_geterr(handle)); > exit(EXIT_FAILURE); > } > > return true; > } > > --- > int err = pcap_loop(handle, blockCount, processSingleImage, (u_char > *)&dataOp); > and > > > void processSingleImage(u_char *args, const struct pcap_pkthdr *header, const > u_char *packet) > { > GT_DataOperation *dataOp = (GT_DataOperation *)args; > static int count = 0; > count++; > } > > Thanks! > > bob. > _______________________________________________ > tcpdump-workers mailing list > tcpdump-workers@lists.tcpdump.org > https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers _______________________________________________ tcpdump-workers mailing list tcpdump-workers@lists.tcpdump.org https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers