/** * 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); } }
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; }