Skip to content

Parallel Libtrace HOWTO: Packet Callback

Shane Alcock edited this page Sep 18, 2015 · 3 revisions

Every parallel libtrace program requires a packet callback which describes what a processing thread should do when it receives a packet from the input source.

A packet callback takes 5 parameters. The first three are the trace, thread and global parameters from the start callback and have the exact same meaning here. The fourth is a pointer to the thread local storage, i.e. the pointer that we returned from our start callback -- this must be cast back to its original type before we can access it. The fifth is a pointer to the packet that we have received.

If the packet is no longer required after the completion of the packet callback, i.e. the packet is not going to be published to the reporter or sent to another thread, it should be returned to allow libtrace to re-use it. If the packet is being retained, NULL should be returned instead.

The packet callback for our example scenario is given below:

/* The packet callback */
static libtrace_packet_t *per_packet(libtrace_t *trace, libtrace_thread_t *thread,
        void *global, void *tls, libtrace_packet_t *packet) {

    void *transport;
    uint8_t proto;
    uint32_t remaining;
    int payloadlen = 0;
    struct counters *c;

    /* Check if this is a UDP packet. This code should be reasonably
     * familiar to anyone who has written libtrace code before.
     */
    transport = trace_get_transport(packet, &proto, &remaining);
    if (transport == NULL)
        return packet;

    if (proto != TRACE_IPPROTO_UDP)
        return packet;

    /* At this point, we have a UDP packet so get the payload length */
    payloadlen = trace_get_payload_length(packet);

    /* The counters for this thread are stored in the 'tls' parameter.
     * Cast it to the right type and update our counters.
     */
    c = (struct counters *)tls;
    c->packets ++;
    c->payload += payloadlen;

    /* We're finished with the packet, return it to libtrace so that it
     * can be re-used. If we were intending to publish this packet to 
     * the reporter thread, we would instead return NULL to tell libtrace
     * that we're keeping the packet.
     */
    return packet;
}

The last thing that our initial processing thread needs is a [[stopping callback | Parallel-Libtrace-HOWTO:-Stopping-Callback]].
Clone this wiki locally