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

Reply via email to