예제 #1
0
bool network_process_recvq(network_t * network)
{
    probe_t       * probe,
                  * reply;
    packet_t      * packet;
    probe_reply_t * probe_reply;

    // Pop the packet from the queue
    if (!(packet = queue_pop_element(network->recvq, NULL))) {
        goto ERR_PACKET_POP;
    }

    // Transform the reply into a probe_t instance
    if(!(reply = probe_wrap_packet(packet))) {
        goto ERR_PROBE_WRAP_PACKET;
    }
    probe_set_recv_time(reply, get_timestamp());

    if (network->is_verbose) {
        printf("Got reply:\n");
        probe_dump(reply);
    }

    // Find the probe corresponding to this reply
    // The corresponding pointer (if any) is removed from network->probes
    if (!(probe = network_get_matching_probe(network, reply))) {
        goto ERR_PROBE_DISCARDED;
    }

    // Build a pair made of the probe and its corresponding reply
    if (!(probe_reply = probe_reply_create())) {
        goto ERR_PROBE_REPLY_CREATE;
    }

    // We're pass to the upper layer the probe and the reply to the upper layer.
    probe_reply_set_probe(probe_reply, probe);
    probe_reply_set_reply(probe_reply, reply);

    // Notify the instance which has build the probe that we've got the corresponding reply

    // TODO this provokes a double free:
    //pt_throw(NULL, probe->caller, event_create(PROBE_REPLY, probe_reply, NULL, (ELEMENT_FREE) probe_reply_free));
    pt_throw(NULL, probe->caller, event_create(PROBE_REPLY, probe_reply, NULL, NULL));

    // TODO probe_reply_free frees only the reply but probe_reply_deep_free cannot be used as other things may have references to its contents.
    return true;

ERR_PROBE_REPLY_CREATE:
ERR_PROBE_DISCARDED:
    probe_free(reply);
ERR_PROBE_WRAP_PACKET:
    //packet_free(packet); TODO provoke segfault in case of stars
ERR_PACKET_POP:
    return false;
}
void pt_stop_instance(
        struct pt_loop_s     * loop,
        algorithm_instance_t * instance
) {
    // Notify the caller that this instance will be freed
    pt_throw(NULL, instance, event_create(ALGORITHM_TERM, NULL, NULL, NULL));

    // Unregister this instance from the loop
    pt_algorithm_instance_del(loop, instance);

    // Free this instance
    algorithm_instance_free(instance);
}
algorithm_instance_t * pt_add_instance(
    struct pt_loop_s * loop,
    const char       * name,
    void             * options,
    probe_t          * probe_skel
) {
    bool                   probe_allocated = false;
    algorithm_t          * algorithm;
    algorithm_instance_t * instance = NULL;

    if (!(algorithm = algorithm_search(name))) {
        goto ERR_ALGORITHM_NOT_FOUND;
    }
    
    // If the probe skeleton does not exist, create it.
    if (!probe_skel) {
        probe_skel = probe_create();
        probe_allocated = (probe_skel != NULL);
        if (!probe_allocated) goto ERR_PROBE_SKEL;
    }

    // Create a new instance of a running algorithm
    if (!(instance = algorithm_instance_create(loop, algorithm, options, probe_skel))) {
        goto ERR_INSTANCE; 
    }

    // We need to queue a new event for the algorithm: it has been started
    pt_throw(NULL, instance, event_create(ALGORITHM_INIT, NULL, NULL, NULL));

    // Add this algorithms to the list of handled algorithms
    pt_algorithm_instance_add(loop, instance);
    return instance;

ERR_INSTANCE:
ERR_PROBE_SKEL:
    if (probe_allocated) probe_free(probe_skel);
ERR_ALGORITHM_NOT_FOUND:
    return NULL;
}
예제 #4
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;
}