source.c 3.03 KB
Newer Older
Juliusz Chroboczek's avatar
Juliusz Chroboczek committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
Copyright (c) 2007 by Juliusz Chroboczek

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

27
#include "babel.h"
Juliusz Chroboczek's avatar
Juliusz Chroboczek committed
28
#include "util.h"
29
#include "source.h"
Juliusz Chroboczek's avatar
Juliusz Chroboczek committed
30

31 32
struct source srcs[MAXSRCS];
int numsrcs = 0;
Juliusz Chroboczek's avatar
Juliusz Chroboczek committed
33

34 35 36
struct source *
find_source(const unsigned char *a, const unsigned char *p, unsigned char plen,
            int create, unsigned short seqno)
Juliusz Chroboczek's avatar
Juliusz Chroboczek committed
37 38
{
    int i;
39
    for(i = 0; i < numsrcs; i++) {
40 41
        /* This should really be a hash table.  For now, check the
           last byte first. */
42
        if(srcs[i].address[15] != a[15])
43
            continue;
44 45 46 47
        if(memcmp(srcs[i].address, a, 16) != 0)
            continue;
        if(source_match(&srcs[i], p, plen))
           return &srcs[i];
Juliusz Chroboczek's avatar
Juliusz Chroboczek committed
48 49 50 51 52
    }

    if(!create)
        return NULL;

53 54
    if(numsrcs >= MAXSRCS) {
        fprintf(stderr, "Too many sources.\n");
55
        return NULL;
Juliusz Chroboczek's avatar
Juliusz Chroboczek committed
56
    }
57 58 59 60 61 62 63
    memcpy(srcs[numsrcs].address, a, 16);
    memcpy(srcs[numsrcs].prefix, p, 16);
    srcs[numsrcs].plen = plen;
    srcs[numsrcs].seqno = seqno;
    srcs[numsrcs].metric = INFINITY;
    srcs[numsrcs].time = now.tv_sec;
    return &srcs[numsrcs++];
Juliusz Chroboczek's avatar
Juliusz Chroboczek committed
64 65
}

66 67
struct source *
find_recent_source(const unsigned char *p, unsigned char plen)
Juliusz Chroboczek's avatar
Juliusz Chroboczek committed
68
{
69 70
    int i;
    struct source *src = NULL;
Juliusz Chroboczek's avatar
Juliusz Chroboczek committed
71

72 73 74 75 76
    for(i = 0; i < numsrcs; i++) {
        if(!source_match(&srcs[i], p, plen))
            continue;
        if(!src || src->time < srcs[i].time)
            src = &srcs[i];
77
    }
78
    return src;
79 80 81
}

int
82 83
source_match(struct source *src,
             const unsigned char *p, unsigned char plen)
84
{
85
    if(src->plen != plen)
86
        return 0;
87
    if(src->prefix[15] != p[15])
88
        return 0;
89
    if(memcmp(src->prefix, p, 16) != 0)
90 91 92 93 94
        return 0;
    return 1;
}

void
95 96
update_source(struct source *src,
              unsigned short seqno, unsigned short metric)
97
{
98 99 100
    if(metric >= INFINITY)
        return;

101 102
    if(src->time < now.tv_sec - 200 ||
       seqno_compare(src->seqno, seqno) < 0 ||
103 104 105
       (src->seqno == seqno && src->metric > metric)) {
        src->seqno = seqno;
        src->metric = metric;
106
    }
107
    src->time = now.tv_sec;
108
}