예제 #1
0
/**
 * Modify the interval to flush the log file.
 * The log file is flushed every periode.
 *
 * @param argv[0] interval as string, "0" disables flushing
 */
int _dessert_cli_log_interval(struct cli_def* cli, char* command, char* argv[], int argc) {
    if(argc != 1) {
        cli_print(cli, "usage %s INTERVAL\n", command);
        return CLI_ERROR;
    }

    // disable
    if(_dessert_log_flush_periodic) {
        dessert_periodic_del(_dessert_log_flush_periodic);
        _dessert_log_flush_periodic = NULL;
    }

    uint8_t i = (uint8_t) strtoul(argv[0], NULL, 10);

    // enable
    if(i) {
        struct timeval interval;
        interval.tv_sec = i;
        interval.tv_usec = 0;
        struct timeval schedule;
        gettimeofday(&schedule, NULL);
        TIMEVAL_ADD(&schedule, i, 0);

        _dessert_log_flush_periodic = dessert_periodic_add(_dessert_flush_log, NULL, &schedule, &interval);
        cli_print(cli, "log flush interval set to %d seconds\n", i);
        dessert_notice("log flush interval set to %d seconds", i);
    }
    else {
        cli_print(cli, "log flushing disabled\n");
        dessert_notice("log flushing disabled");
    }

    return CLI_OK;
}
void storeDroppedPacket(dessert_msg_t* msg) {
    trappedpacket_t* t;
    u_char* shost = dessert_msg_getl25ether(msg)->ether_shost;

    pkey_t lookup_key;
    memcpy(lookup_key.addr, shost, ETHER_ADDR_LEN);
    lookup_key.seq = msg->u16;

    /*###*/
    pthread_rwlock_wrlock(&packettrap_lock);
    HASH_FIND(hh, trappedpackets, &lookup_key, sizeof(pkey_t), t);
    if(t) {
        // TODO: gossip_10
        t->counter++;
    }
    pthread_rwlock_unlock(&packettrap_lock);
    /*###*/

    if(!t) {
        trappedpacket_t* t = malloc(sizeof(trappedpacket_t));
        if(!t) {
            dessert_crit("could not allocate memory");
            return;
        }

        dessert_msg_t* clone = NULL;
        dessert_msg_clone(&clone, msg, false);
        t->msg = clone;

        memcpy(&(t->key), &lookup_key, sizeof(pkey_t));
        t->counter = 1;
        t->counter2 = 0;
        t->forwarded = 0;

        /*###*/
        pthread_rwlock_wrlock(&packettrap_lock);
        HASH_ADD(hh, trappedpackets, key, sizeof(pkey_t), t);
        pthread_rwlock_unlock(&packettrap_lock);
        /*###*/

        uint32_t sec = timeout.tv_sec;
        uint32_t usec = timeout.tv_usec;
        if(gossip == gossip_7) {
            sec = 0;
            usec = 1000 * (random() % T_MAX_ms);
            while(usec >= 1000000) {
                sec += 1;
                usec -= 1000000;
            }
            dessert_debug("gossip7 random timeout: %ld s, %ld us", sec, usec);
        }
        struct timeval handle_interval;
        gettimeofday(&handle_interval, NULL);
        TIMEVAL_ADD(&handle_interval, sec, usec);
        dessert_periodic_add((dessert_periodiccallback_t *) handleTrappedPacket, t, &handle_interval, NULL);
    }
}
void storeForwardedPacket(dessert_msg_t* msg, uint8_t source) {
    trappedpacket_t* t;
    u_char* shost = dessert_msg_getl25ether(msg)->ether_shost;

    pkey_t lookup_key;
    memcpy(lookup_key.addr, shost, ETHER_ADDR_LEN);
    lookup_key.seq = msg->u16;

    /*###*/
    pthread_rwlock_wrlock(&packettrap_lock);
    HASH_FIND(hh, trappedpackets, &lookup_key, sizeof(pkey_t), t);
    if(t) {
        t->counter++;
    }
    pthread_rwlock_unlock(&packettrap_lock);
    /*###*/

    if(!t) {
        trappedpacket_t* t = malloc(sizeof(trappedpacket_t));
        if(!t) {
            dessert_crit("could not allocate memory");
            return;
        }

        dessert_msg_t* clone = NULL;
        dessert_msg_clone(&clone, msg, false);
        t->msg = clone;

        memcpy(&(t->key), &lookup_key, sizeof(pkey_t));
        if(source) {
            t->counter = 0;
        }
        else {
            t->counter = 1;
        }
        t->counter2 = 0;
        t->forwarded = 1;

        /*###*/
        pthread_rwlock_wrlock(&packettrap_lock);
        HASH_ADD(hh, trappedpackets, key, sizeof(pkey_t), t);
        pthread_rwlock_unlock(&packettrap_lock);
        /*###*/

        uint32_t sec = timeout.tv_sec;
        uint32_t usec = timeout.tv_usec;
        struct timeval handle_interval;
        gettimeofday(&handle_interval, NULL);
        TIMEVAL_ADD(&handle_interval, sec, usec);
        dessert_periodic_add((dessert_periodiccallback_t *) handleTrappedPacket, t, &handle_interval, NULL);
    }
}
예제 #4
0
void
rtsol_timer_update(struct ifinfo *ifinfo)
{
#define MILLION 1000000
#define DADRETRY 10		/* XXX: adhoc */
	long interval;
	struct timeval now;

	bzero(&ifinfo->timer, sizeof(ifinfo->timer));

	switch (ifinfo->state) {
	case IFS_DOWN:
	case IFS_TENTATIVE:
		if (++ifinfo->dadcount > DADRETRY) {
			ifinfo->dadcount = 0;
			ifinfo->timer.tv_sec = PROBE_INTERVAL;
		}
		else
			ifinfo->timer.tv_sec = 1;
		break;
	case IFS_IDLE:
		if (mobile_node) {
			/* XXX should be configurable */ 
			ifinfo->timer.tv_sec = 3;
		}
		else
			ifinfo->timer = tm_max;	/* stop timer(valid?) */
		break;
	case IFS_DELAY:
#ifndef HAVE_ARC4RANDOM
		interval = random() % (MAX_RTR_SOLICITATION_DELAY * MILLION);
#else
		interval = arc4random() % (MAX_RTR_SOLICITATION_DELAY * MILLION);
#endif
		ifinfo->timer.tv_sec = interval / MILLION;
		ifinfo->timer.tv_usec = interval % MILLION;
		break;
	case IFS_PROBE:
		if (ifinfo->probes < MAX_RTR_SOLICITATIONS)
			ifinfo->timer.tv_sec = RTR_SOLICITATION_INTERVAL;
		else {
			/*
			 * After sending MAX_RTR_SOLICITATIONS solicitations,
			 * we're just waiting for possible replies; there
			 * will be no more solicatation.  Thus, we change
			 * the timer value to MAX_RTR_SOLICITATION_DELAY based
			 * on RFC 2461, Section 6.3.7.
			 */
			ifinfo->timer.tv_sec = MAX_RTR_SOLICITATION_DELAY;
		}
		break;
	default:
		warnmsg(LOG_ERR, __func__,
			"illegal interface state(%d) on %s",
			ifinfo->state, ifinfo->ifname);
		return;
	}

	/* reset the timer */
	if (TIMEVAL_EQ(ifinfo->timer, tm_max)) {
		ifinfo->expire = tm_max;
		warnmsg(LOG_DEBUG, __func__,
			"stop timer for %s", ifinfo->ifname);
	}
	else {
		gettimeofday(&now, NULL);
		TIMEVAL_ADD(&now, &ifinfo->timer, &ifinfo->expire);

		if (dflag > 1)
			warnmsg(LOG_DEBUG, __func__,
				"set timer for %s to %d:%d", ifinfo->ifname,
			       (int)ifinfo->timer.tv_sec,
			       (int)ifinfo->timer.tv_usec);
	}

#undef MILLION
}
/** Handles a trapped packet after timeout
 *
 */
dessert_per_result_t handleTrappedPacket(void *data, struct timeval *scheduled, struct timeval *interval) {
    trappedpacket_t* t = (trappedpacket_t*) data;
    uint8_t forwarded = 0;
    switch(gossip) {
        // forward if less than m duplicates received
        case gossip_14:
        case gossip_3:
            if((t->counter)-1 < m) {
                dessert_debug("forwarding msg: src=" MAC ", seq=%d, received %d<%d duplicates",
                              EXPLODE_ARRAY6(t->key.addr), t->msg->u16, t->counter-1, m);
                t->msg->u8 |= DELAYED;
                dessert_meshif_t* iface = NULL;
                logForwarded(t->msg, 0, NULL, iface);
                dessert_meshsend(t->msg, iface);
                forwarded = 1;
            }
            break;
        // send if not all neighbors sent a copy
        case gossip_5:
            if((t->counter) < numNeighbors()) {
                dessert_debug("forwarding msg: src=" MAC ", seq=%d, received %d<%d (=neighbors) duplicates",
                              EXPLODE_ARRAY6(t->key.addr), t->msg->u16, t->counter, numNeighbors());
                t->msg->u8 |= DELAYED;
                dessert_meshif_t* iface = NULL;
                logForwarded(t->msg, 0, NULL, iface);
                dessert_meshsend(t->msg, iface);
                forwarded = 1;
            }
            break;
        // forward if less than m duplicates received with adapted probability
        case gossip_6:
            if((t->counter)-1 < m) {
                float  new_p = (p/(m + 1));
                if(random() < (((long double) new_p)*((long double) RAND_MAX))) {
                    dessert_debug("forwarding msg: src=" MAC ", seq=%d, received %d<%d duplicates and send with probability %f",
                                  EXPLODE_ARRAY6(t->key.addr), t->msg->u16, t->counter-1, m, new_p);
                    t->msg->u8 |= DELAYED;
                    dessert_meshif_t* iface = NULL;
                    logForwarded(t->msg, 0, NULL, iface);
                    dessert_meshsend(t->msg, iface);
                    forwarded = 1;
                }
            }
            break;
        // forward if less than m-1 duplicates received
        case gossip_7:
            if((t->counter-1) <= m) {
                if(random() < (((long double) p)*((long double) RAND_MAX))) {
                    dessert_debug("forwarding msg: src=" MAC ", seq=%d, received %d<=%d duplicates", EXPLODE_ARRAY6(t->key.addr), t->msg->u16, t->counter-1, m);
                    t->msg->u8 |= DELAYED;
                    dessert_meshif_t* iface = NULL;
                    logForwarded(t->msg, 0, NULL, iface);
                    dessert_meshsend(t->msg, iface);
                    forwarded = 1;
                }
            }
            break;
        case gossip_10:
            if(t->forwarded) {
                if((max(0, t->counter) + t->counter2) < m) {
                    t->msg->u8 |= DELAYED;
                    dessert_meshif_t* iface = NULL;
                    logForwarded(t->msg, 0, NULL, iface);
                    dessert_meshsend(t->msg, iface);
                    forwarded = 1;
                }
                // always drop packet after 2nd forwarding chance
            }
            else {
                // like gossip_3
                if(max(0, t->counter - 1) < m) {
                    t->msg->u8 |= DELAYED;
                    dessert_meshif_t* iface = NULL;
                    logForwarded(t->msg, 0, NULL, iface);
                    dessert_meshsend(t->msg, iface);
                    t->forwarded = 1;
                    uint32_t sec = timeout.tv_sec;
                    uint32_t usec = timeout.tv_usec;
                    struct timeval handle_interval;
                    gettimeofday(&handle_interval, NULL);
                    TIMEVAL_ADD(&handle_interval, sec, usec);
                    dessert_periodic_add((dessert_periodiccallback_t *) handleTrappedPacket, t, &handle_interval, NULL);
                    dessert_debug("keeping packet to monitor forwarding of neighbors: src=" MAC ", seq=%d", EXPLODE_ARRAY6(t->key.addr), t->key.seq);
                    return 0; // do not delete msg and give it a second chance
                }
            }
            break;
        case gossip_11: // TODO: remove/replace
            if((t->counter)-1 < m) {
                float new_p = (p+(((1-p)*p)/(m + 1)));
                if(random() < (((long double) new_p)*((long double) RAND_MAX))) {
                    dessert_debug("forwarding msg: src=" MAC ", seq=%d, received %d<%d duplicates, p_new=%f",
                                  EXPLODE_ARRAY6(t->key.addr), t->msg->u16, t->counter-1, m, new_p);
                    t->msg->u8 |= DELAYED;
                    dessert_meshif_t* iface = NULL;
                    logForwarded(t->msg, 0, NULL, iface);
                    dessert_meshsend(t->msg, iface);
                    forwarded = 1;
                }
            }
            break;
        default:
            dessert_warn("unsupported gossip variant");
    }

    if(!forwarded) {
        dessert_debug("packet not forwarded, dropping it now: src=" MAC ", seq=%d", EXPLODE_ARRAY6(t->key.addr), t->key.seq);
    }

    /*###*/
    pthread_rwlock_wrlock(&packettrap_lock);
    HASH_DEL(trappedpackets, t);
    pthread_rwlock_unlock(&packettrap_lock);
    /*###*/

    destroyTrappedPacket(t);

    return 0;
}