void pt_process_instance(const void * node, VISIT visit, int level)
{
    algorithm_instance_t * instance = *((algorithm_instance_t * const *) node);
    size_t                 i, num_events;
    uint64_t               ret;
    ssize_t                count;
    
    // Save temporarily this algorithm context
    instance->loop->cur_instance = instance;

    // Execute algorithm handler for events of each algorithm
    num_events = dynarray_get_size(instance->events);
    for (i = 0; i < num_events; i++) {
        event_t * event;

        count = read(instance->loop->eventfd_algorithm, &ret, sizeof(ret));
        if (count == -1)
            return;

        event = dynarray_get_ith_element(instance->events, i);
        instance->algorithm->handler(instance->loop, event, &instance->data, instance->probe_skel, instance->options);
    }

    // Restore the algorithm context
    instance->loop->cur_instance = NULL;

    // Flush events queue
    algorithm_instance_clear_events(instance);
}
Ejemplo n.º 2
0
static void network_flying_probes_dump(network_t * network) {
    size_t     i, num_flying_probes = dynarray_get_size(network->probes);
    uint16_t   tag_probe;
    probe_t  * probe;

    printf("\n%u flying probe(s) :\n", (unsigned int)num_flying_probes);
    for (i = 0; i < num_flying_probes; i++) {
        probe = dynarray_get_ith_element(network->probes, i);
        probe_extract_tag(probe, &tag_probe) ?
            printf(" 0x%x", tag_probe):
            printf(" (invalid tag)");
        printf("\n");
    }
}
Ejemplo n.º 3
0
bool network_drop_expired_flying_probe(network_t * network)
{
    // Drop every expired probes
    size_t    i, num_flying_probes = dynarray_get_size(network->probes);
    bool      ret = false;
    probe_t * probe;

    // Is there flying probe(s) ?
    if (num_flying_probes > 0) {

        // Iterate on each expired probes (at least the oldest one has expired)
        for (i = 0 ;i < num_flying_probes; i++) {
            probe = dynarray_get_ith_element(network->probes, i);

            // Some probe may expires very soon and may expire before the next probe timeout
            // update. If so, the timer will be disarmed and libparistraceroute may freeze.
            // To avoid this kind of deadlock, we provoke a probe timeout for each probe
            // expiring in less that EXTRA_DELAY seconds.
            if (network_get_probe_timeout(network, probe) - EXTRA_DELAY > 0) break;

            // This probe has expired, raise a PROBE_TIMEOUT event.
            pt_throw(NULL, probe->caller, event_create(PROBE_TIMEOUT, probe, NULL, NULL)); //(ELEMENT_FREE) probe_free));
        }

        // Delete the i oldest probes, which have expired.
        if (i != 0) {
            dynarray_del_n_elements(network->probes, 0, i, NULL);
        }

        ret = network_update_next_timeout(network);
    } else {
        fprintf(stderr, "network_drop_expired_flying_probe: a probe has expired, but there are no more flying probes!\n");
    }

    return ret;
}
Ejemplo n.º 4
0
static probe_t * network_get_matching_probe(network_t * network, const probe_t * reply)
{

    // Suppose we perform a traceroute measurement thanks to IPv4/UDP packet
    // We encode in the IPv4 checksum the ID of the probe.
    // Then, we should sniff an IPv4/ICMP/IPv4/UDP packet.
    // The ICMP message carries the begining of our probe packet, so we can
    // retrieve the checksum (= our probe ID) of the second IP layer, which
    // corresponds to the 3rd checksum field of our probe.

    uint16_t   tag_probe, tag_reply;
    probe_t  * probe;
    size_t     i, num_flying_probes;

    // XXX
    
    // Fetch the tag from the reply. Its the 3rd checksum field.
    if (!(reply_extract_tag(reply, &tag_reply))) {
        // This is not an IP / ICMP / IP / * reply :(
        if (network->is_verbose) fprintf(stderr, "Can't retrieve tag from reply\n");
        return NULL;
    }

    num_flying_probes = dynarray_get_size(network->probes);
    for (i = 0; i < num_flying_probes; i++) {
        probe = dynarray_get_ith_element(network->probes, i);

        // Reply / probe comparison. In our probe packet, the probe ID
        // is stored in the checksum of the (first) IP layer.
        if (probe_extract_tag(probe, &tag_probe)) {
            if (tag_reply == tag_probe) break;
        }
    }
    
/*
    // XXX BEGIN Harcoded ICMP response (JA 17/07/2014)
    tag_reply = 0; tag_probe = 0; tag_probe++; tag_reply++;

    num_flying_probes = dynarray_get_size(network->probes);
    for (i = 0; i < num_flying_probes; i++) {
        probe = dynarray_get_ith_element(network->probes, i);

        // Reply / probe comparison. In our probe packet, the probe ID
        // is stored in the checksum of the (first) IP layer.
        if (probe_match((const struct probe_s *)probe, (const struct probe_s *)reply))
            break;
    }
    // XXX END Hardcoded ICMP response
*/
    // No match found if we reached the end of the array
    if (i == num_flying_probes) {
        if (network->is_verbose) {
            fprintf(stderr, "network_get_matching_probe: This reply has been discarded: tag = 0x%x.\n", tag_reply);
            network_flying_probes_dump(network);
        }
        return NULL;
    }

    // We delete the corresponding probe

    // TODO: ... but it should be kept, for archive purposes, and to match for duplicates...
    // But we cannot reenable it until we set the probe ID into the
    // checksum, since probes with same flow_id and different TTL have the
    // same checksum

    dynarray_del_ith_element(network->probes, i, NULL);

    // The matching probe is the oldest one and there are other probes, update
    // the timer according to the next unexpired probe timeout.
    if (i == 0) {
        if (!(network_update_next_timeout(network))) {
            fprintf(stderr, "Error while updating timeout\n");
        }
    }

    return probe;
}
Ejemplo n.º 5
0
static probe_t * network_get_oldest_probe(const network_t * network) {
    return dynarray_get_ith_element(network->probes, 0);
}
Ejemplo n.º 6
0
layer_t * probe_get_layer(const probe_t * probe, size_t i) {
    return dynarray_get_ith_element(probe->layers, i);
}