Exemple #1
0
bool rreqtable_is_redundant(struct aodvv2_packet_data *packet_data)
{
    struct aodvv2_rreq_entry *comparable_rreq;
    timex_t now;
    bool result;

    mutex_lock(&rreqt_mutex);
    comparable_rreq = _get_comparable_rreq(packet_data);

    /* if there is no comparable rreq stored, add one and return false */
    if (comparable_rreq == NULL) {
        _add_rreq(packet_data);
        result = false;
    }
    else {
        int seqnum_comparison = seqnum_cmp(packet_data->origNode.seqnum, comparable_rreq->seqnum);

        /*
         * If two RREQs have the same
         * metric type and OrigNode and Targnode addresses, the information from
         * the one with the older Sequence Number is not needed in the table
         */
        if (seqnum_comparison == -1) {
            result = true;
        }

        if (seqnum_comparison == 1) {
            /* Update RREQ table entry with new seqnum value */
            comparable_rreq->seqnum = packet_data->origNode.seqnum;
        }

        /*
         * in case they have the same Sequence Number, the one with the greater
         * Metric value is not needed
         */
        if (seqnum_comparison == 0) {
            if (comparable_rreq->metric <= packet_data->origNode.metric) {
                result = true;
            }
            /* Update RREQ table entry with new metric value */
            comparable_rreq->metric = packet_data->origNode.metric;
        }

        /* Since we've changed RREQ info, update the timestamp */
        vtimer_now(&now);
        comparable_rreq->timestamp = now;
        result = true;
    }

    mutex_unlock(&rreqt_mutex);
    return result;
}
Exemple #2
0
static enum rfc5444_result _cb_rerr_blocktlv_addresstlvs_okay(struct rfc5444_reader_tlvblock_context *cont)
{
#if ENABLE_DEBUG
    /* cppcheck-suppress unusedVariable as nbuf is needed by VDEBUG. */
    struct netaddr_str nbuf;
#endif
    struct aodvv2_routing_entry_t *unreachable_entry;
    struct rfc5444_reader_tlvblock_entry *tlv;

    VDEBUG("%s()\n", __func__);
    VDEBUG("\tmessage type: %d\n", cont->type);
    VDEBUG("\taddr: %s\n", netaddr_to_string(&nbuf, &cont->addr));

    /* Out of buffer size for more unreachable nodes. We're screwed, basically. */
    if (num_unreachable_nodes == AODVV2_MAX_UNREACHABLE_NODES) {
        return RFC5444_OKAY;
    }

    /* gather packet data */
    packet_data.origNode.addr = cont->addr;

    /* handle this unreachable node's SeqNum TLV */
    /* cppcheck: suppress false positive on non-trivially initialized arrays.
     *           this is a known bug: http://trac.cppcheck.net/ticket/5497 */
    /* cppcheck-suppress arrayIndexOutOfBounds */
    tlv = _rerr_address_consumer_entries[RFC5444_MSGTLV_UNREACHABLE_NODE_SEQNUM].tlv;
    if (tlv) {
        VDEBUG("\ttlv RFC5444_MSGTLV_UNREACHABLE_NODE_SEQNUM: %d\n", *tlv->single_value);
        packet_data.origNode.seqnum = *tlv->single_value;
    }

    /* Check if there is an entry for unreachable node in our routing table */
    unreachable_entry = routingtable_get_entry(&packet_data.origNode.addr, packet_data.metricType);
    if (unreachable_entry) {
        VDEBUG("\t found possibly unreachable entry.\n");

        /* check if route to unreachable node has to be marked as broken and RERR has to be forwarded */
        if (netaddr_cmp(&unreachable_entry->nextHopAddr, &packet_data.sender) == 0
                && (!tlv || seqnum_cmp(unreachable_entry->seqnum, packet_data.origNode.seqnum) == 0)) {
            unreachable_entry->state = ROUTE_STATE_INVALID;
            unreachable_nodes[num_unreachable_nodes].addr = packet_data.origNode.addr;
            unreachable_nodes[num_unreachable_nodes].seqnum = packet_data.origNode.seqnum;
            num_unreachable_nodes++;
        }

        /* remove entry from FIB */
        fib_remove_entry(packet_data.origNode.addr._addr, sizeof(ipv6_addr_t));
    }

    return RFC5444_OKAY;
}
Exemple #3
0
bool routingtable_offers_improvement(struct aodvv2_routing_entry_t *rt_entry,
                                     struct node_data *node_data)
{
    /* (TODO only guaranteed for AODVV2_DEFAULT_METRIC_TYPE!)*/
    bool is_loop_free = node_data->metric <= rt_entry->metric;
    int stale = seqnum_cmp(node_data->seqnum, rt_entry->seqnum);

    if ((stale == 1)                                                 /* New info is more recent and MUST be used */
        || ((stale == 0) && (node_data->metric < rt_entry->metric))  /* New info offers a better route and SHOULD be used */
        || ((stale == 0) && (node_data->metric >= rt_entry->metric)  /* Route is not an improvement, */
                         && (rt_entry->state == ROUTE_STATE_INVALID) /* but repairs an invalid route */
                         && is_loop_free)                             /* and contains no loops */
        ) {
        return true;
    }
    return false;
}