dessert_cb_result_t lsr_sys2mesh(dessert_msg_t *msg, uint32_t len, dessert_msg_proc_t *proc, dessert_sysif_t *sysif, dessert_frameid_t id) { struct ether_header* l25h = dessert_msg_getl25ether(msg); msg->ttl = LSR_TTL_MAX; if(proc->lflags.l25_multicast) { msg->u16 = htons(lsr_db_broadcast_get_seq_nr()); memcpy(msg->l2h.ether_dhost, ether_broadcast, ETH_ALEN); dessert_result_t result = lsr_send_randomized(msg); if(result != DESSERT_OK) { dessert_crit("error while trying to send multicast"); } } else { msg->u16 = htons(lsr_db_unicast_get_seq_nr()); dessert_meshif_t *out_iface; mac_addr next_hop; dessert_result_t result = lsr_db_get_next_hop(l25h->ether_dhost, &next_hop, &out_iface); if(result == DESSERT_OK) { memcpy(msg->l2h.ether_dhost, next_hop, ETH_ALEN); dessert_result_t result = lsr_send(msg, out_iface); if(result != DESSERT_OK) { dessert_crit("error while trying to send unicast"); } } else { dessert_info("no route to dest " MAC, EXPLODE_ARRAY6(l25h->ether_dhost)); } } return DESSERT_MSG_DROP; }
int aodv_metric_do(metric_t* metric, uint8_t last_hop[ETH_ALEN], dessert_meshif_t* iface) { switch(metric_type) { case AODV_METRIC_HOP_COUNT: { (*metric)++; break; } case AODV_METRIC_RSSI: { struct avg_node_result sample = dessert_rssi_avg(last_hop, iface); uint8_t interval = hf_rssi2interval(sample.avg_rssi); dessert_trace("incomming rssi_metric=%" AODV_PRI_METRIC ", add %" PRIu8 " (rssi=%" PRId8 ") for the last hop " MAC, (*metric), interval, sample.avg_rssi, EXPLODE_ARRAY6(last_hop)); (*metric) += interval; break; } case AODV_METRIC_ETX: { dessert_crit("AODV_METRIC_ETX -> not implemented! -> using AODV_METRIC_HOP_COUNT as fallback"); (*metric)++; /* HOP_COUNT */ break; } case AODV_METRIC_ETT: { dessert_crit("AODV_METRIC_ETT -> not implemented! -> using AODV_METRIC_HOP_COUNT as fallback"); (*metric)++; /* HOP_COUNT */ break; } default: { dessert_crit("unknown metric=%" PRIu8 " -> using HOP_COUNT as fallback", metric_type); (*metric)++; /* HOP_COUNT */ return false; } } return true; }
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); } }
int aodv_metric_do(metric_t* metric, mac_addr last_hop, dessert_meshif_t* iface, struct timeval* timestamp) { switch(metric_type) { case AODV_METRIC_HOP_COUNT: { (*metric)++; break; } #ifndef ANDROID case AODV_METRIC_RSSI: { struct avg_node_result sample = dessert_rssi_avg(last_hop, iface); metric_t interval = hf_rssi2interval(sample.avg_rssi); dessert_trace("incoming rssi_metric=%" AODV_PRI_METRIC ", add %" PRIu8 " (rssi=%" PRId8 ") for the last hop " MAC, (*metric), interval, sample.avg_rssi, EXPLODE_ARRAY6(last_hop)); *metric += interval; break; } #endif case AODV_METRIC_ETX_ADD: { metric_t link_etx_add = AODV_MAX_METRIC; if(aodv_db_pdr_get_etx_add(last_hop, &link_etx_add, timestamp)) { dessert_debug("Old metricval %" AODV_PRI_METRIC " ETX_ADD rcvd =%" PRIu16 " for this hop " MAC, (*metric), link_etx_add, EXPLODE_ARRAY6(last_hop)); } else { dessert_debug("Old metricval %" AODV_PRI_METRIC " ETX_ADD for hop " MAC " failed", *metric, EXPLODE_ARRAY6(last_hop)); } /**prevent overflow*/ if(AODV_MAX_METRIC - link_etx_add > *metric) { *metric += link_etx_add; } else { *metric = AODV_MAX_METRIC; } dessert_debug("New metric value =%" AODV_PRI_METRIC " for hop " MAC, *metric, EXPLODE_ARRAY6(last_hop)); break; } case AODV_METRIC_ETX_MUL: { metric_t link_etx_mul = 0; if(aodv_db_pdr_get_etx_mul(last_hop, &link_etx_mul, timestamp) == true) { dessert_debug("Old metricval %" AODV_PRI_METRIC " ETX_MUL rcvd =%" PRIu16 " for this hop " MAC, (*metric), link_etx_mul, EXPLODE_ARRAY6(last_hop)); uintmax_t result = (*metric) * (uintmax_t)link_etx_mul; result /= (AODV_MAX_METRIC/32); (*metric) = (metric_t) result; } else { dessert_debug("Old metricval %" AODV_PRI_METRIC " ETX_MUL for hop " MAC " failed", (*metric), EXPLODE_ARRAY6(last_hop)); (*metric) = 0; } dessert_debug("New metric value =%" AODV_PRI_METRIC " for hop " MAC, (*metric), EXPLODE_ARRAY6(last_hop)); break; } case AODV_METRIC_PDR: { uint16_t link_pdr = 0; if(aodv_db_pdr_get_pdr(last_hop, &link_pdr, timestamp) == true){ dessert_debug("Old metricval %" AODV_PRI_METRIC " PDR rcvd =%" PRIu16 " for this hop " MAC, (*metric), link_pdr, EXPLODE_ARRAY6(last_hop)); uint32_t result = (*metric) * (uint32_t)link_pdr; result = result / AODV_MAX_METRIC; (*metric) = (metric_t) result; } else { dessert_debug("Old metricval %" AODV_PRI_METRIC " PDR for hop " MAC " failed", (*metric), EXPLODE_ARRAY6(last_hop)); (*metric) = 0; } dessert_debug("New metric value =%" AODV_PRI_METRIC " for hop " MAC, (*metric), EXPLODE_ARRAY6(last_hop)); break; } case AODV_METRIC_RFC: { break; } default: { dessert_crit("unknown metric set -> using AODV_METRIC_RFC as fallback"); return false; } } return true; }
dessert_cb_result_t lsr_unhandled(dessert_msg_t* msg, uint32_t len, dessert_msg_proc_t *proc, dessert_meshif_t *iface, dessert_frameid_t id) { dessert_crit("unhandled packet"); return DESSERT_MSG_DROP; }
/** Check if this packet is a duplicate * * Registers the sequence number as received if it is the first copy of the packet. * All subsequent received copies (duplicates) are dropped and the packet count is * increased, if the first copy is still in the packet trap. * * Looping packets sent by this host are also dropped. * The hop count value in the corresponding extension is incremented. */ int checkSeq(dessert_msg_t* msg, size_t len, dessert_msg_proc_t *proc, dessert_meshif_t *iface, dessert_frameid_t id) { if(/*proc->lflags & DESSERT_RX_FLAG_L2_SRC ||*/ proc->lflags & DESSERT_RX_FLAG_L25_SRC) { // TODO gossip_10 dessert_debug("dropped looping packet from myself"); return DESSERT_MSG_DROP; } seqlog_t* s = NULL; u_char* shost = dessert_msg_getl25ether(msg)->ether_shost; /*###*/ pthread_rwlock_rdlock(&seqlog_lock); HASH_FIND(hh, seqlog, shost, ETHER_ADDR_LEN, s); pthread_rwlock_unlock(&seqlog_lock); /*###*/ bool seq2_duplicate = false; if(s) { /*###*/ pthread_rwlock_wrlock(&seqlog_lock); uint8_t dup = isDuplicate(s, msg->u16); if(!dup) { insertSeq(s, msg->u16); #ifndef ANDROID seq2_duplicate = gossip13_rx_packet(s, msg, false); #endif pthread_rwlock_unlock(&seqlog_lock); /*###*/ } else { pthread_rwlock_unlock(&seqlog_lock); /*###*/ if(!(msg->u8 & HELLO)) { // HELLOs are never trapped trappedpacket_t* t; 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); /*###*/ } return DESSERT_MSG_DROP; } } else { s = malloc(sizeof(seqlog_t)); if(!s) { dessert_crit("could not allocate memory"); return DESSERT_MSG_KEEP; } uint16_t i = 0; for(i=0; i<LOG_SIZE; i++) { s->seqs[i] = msg->u16; } s->next_seq = 1; #ifndef ANDROID // what the other node tells me gossip13_new_history(&(s->rx_history), false); // does not require observation initialization gossip13_new_history(&(s->tx_history), false); // does not require observation initialization gossip13_new_history(&(s->total_tx_history), false); // does not require observation initialization gossip13_new_history_mean(&(s->hops_history), false); // does not require observation initialization gossip13_new_history(&(s->nodes_history), false); // does not require observation initialization gossip13_new_history_mean(&(s->mean_dist_history), false); // does not require observation initialization gossip13_new_history_mean(&(s->eccentricity_history), false); // does not require observation initialization // what I know about the other node gossip13_new_history(&(s->observed_history), true); gossip13_new_observation(&(s->observed_history->observations)); gossip13_new_history_mean(&(s->my_hops_history), true); gossip13_new_observation_mean(&(s->my_hops_history->observations)); #endif s->tau = 0; memcpy(s->addr, shost, ETHER_ADDR_LEN); dessert_debug("registering seq=%d for src=" MAC " (previously unknown host)", msg->u16, EXPLODE_ARRAY6(shost)); #ifndef ANDROID seq2_duplicate = gossip13_rx_packet(s, msg, true); #endif /*###*/ pthread_rwlock_wrlock(&seqlog_lock); HASH_ADD(hh, seqlog, addr, ETHER_ADDR_LEN, s); pthread_rwlock_unlock(&seqlog_lock); /*###*/ } #ifndef ANDROID if(seq2_duplicate && gossip13_drop_seq2_duplicates && (proc->lflags & DESSERT_RX_FLAG_L25_DST || proc->lflags & DESSERT_RX_FLAG_L25_BROADCAST)) { return DESSERT_MSG_DROP; } #endif dessert_ext_t* ext = NULL; if(dessert_msg_getext(msg, &ext, EXT_HOPS, 0)) { gossip_ext_hops_t* h = (gossip_ext_hops_t*) ext->data; h->hops++; } return DESSERT_MSG_KEEP; }