Annotation of embedaddon/quagga/babeld/source.c, revision 1.1.1.1

1.1       misho       1: /*  
                      2:  *  This file is free software: you may copy, redistribute and/or modify it  
                      3:  *  under the terms of the GNU General Public License as published by the  
                      4:  *  Free Software Foundation, either version 2 of the License, or (at your  
                      5:  *  option) any later version.  
                      6:  *  
                      7:  *  This file is distributed in the hope that it will be useful, but  
                      8:  *  WITHOUT ANY WARRANTY; without even the implied warranty of  
                      9:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  
                     10:  *  General Public License for more details.  
                     11:  *  
                     12:  *  You should have received a copy of the GNU General Public License  
                     13:  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  
                     14:  *  
                     15:  * This file incorporates work covered by the following copyright and  
                     16:  * permission notice:  
                     17:  *  
                     18: Copyright (c) 2007, 2008 by Juliusz Chroboczek
                     19: 
                     20: Permission is hereby granted, free of charge, to any person obtaining a copy
                     21: of this software and associated documentation files (the "Software"), to deal
                     22: in the Software without restriction, including without limitation the rights
                     23: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     24: copies of the Software, and to permit persons to whom the Software is
                     25: furnished to do so, subject to the following conditions:
                     26: 
                     27: The above copyright notice and this permission notice shall be included in
                     28: all copies or substantial portions of the Software.
                     29: 
                     30: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     31: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     32: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
                     33: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     34: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     35: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     36: THE SOFTWARE.
                     37: */
                     38: 
                     39: #include <stdlib.h>
                     40: #include <stdio.h>
                     41: #include <string.h>
                     42: #include <sys/time.h>
                     43: 
                     44: #include "babel_main.h"
                     45: #include "babeld.h"
                     46: #include "util.h"
                     47: #include "source.h"
                     48: #include "babel_interface.h"
                     49: #include "route.h"
                     50: 
                     51: struct source *srcs = NULL;
                     52: 
                     53: struct source*
                     54: find_source(const unsigned char *id, const unsigned char *p, unsigned char plen,
                     55:             int create, unsigned short seqno)
                     56: {
                     57:     struct source *src;
                     58: 
                     59:     for(src = srcs; src; src = src->next) {
                     60:         /* This should really be a hash table.  For now, check the
                     61:            last byte first. */
                     62:         if(src->id[7] != id[7])
                     63:             continue;
                     64:         if(memcmp(src->id, id, 8) != 0)
                     65:             continue;
                     66:         if(src->plen != plen)
                     67:             continue;
                     68:         if(memcmp(src->prefix, p, 16) == 0)
                     69:             return src;
                     70:     }
                     71: 
                     72:     if(!create)
                     73:         return NULL;
                     74: 
                     75:     src = malloc(sizeof(struct source));
                     76:     if(src == NULL) {
                     77:         zlog_err("malloc(source): %s", safe_strerror(errno));
                     78:         return NULL;
                     79:     }
                     80: 
                     81:     memcpy(src->id, id, 8);
                     82:     memcpy(src->prefix, p, 16);
                     83:     src->plen = plen;
                     84:     src->seqno = seqno;
                     85:     src->metric = INFINITY;
                     86:     src->time = babel_now.tv_sec;
                     87:     src->route_count = 0;
                     88:     src->next = srcs;
                     89:     srcs = src;
                     90:     return src;
                     91: }
                     92: 
                     93: struct source *
                     94: retain_source(struct source *src)
                     95: {
                     96:     assert(src->route_count < 0xffff);
                     97:     src->route_count++;
                     98:     return src;
                     99: }
                    100: 
                    101: void
                    102: release_source(struct source *src)
                    103: {
                    104:     assert(src->route_count > 0);
                    105:     src->route_count--;
                    106: }
                    107: 
                    108: int
                    109: flush_source(struct source *src)
                    110: {
                    111:     if(src->route_count > 0)
                    112:         /* The source is in use by a route. */
                    113:         return 0;
                    114: 
                    115:     if(srcs == src) {
                    116:         srcs = src->next;
                    117:     } else {
                    118:         struct source *previous = srcs;
                    119:         while(previous->next != src)
                    120:             previous = previous->next;
                    121:         previous->next = src->next;
                    122:     }
                    123: 
                    124:     free(src);
                    125:     return 1;
                    126: }
                    127: 
                    128: void
                    129: update_source(struct source *src,
                    130:               unsigned short seqno, unsigned short metric)
                    131: {
                    132:     if(metric >= INFINITY)
                    133:         return;
                    134: 
                    135:     /* If a source is expired, pretend that it doesn't exist and update
                    136:        it unconditionally.  This makes ensures that old data will
                    137:        eventually be overridden, and prevents us from getting stuck if
                    138:        a router loses its sequence number. */
                    139:     if(src->time < babel_now.tv_sec - SOURCE_GC_TIME ||
                    140:        seqno_compare(src->seqno, seqno) < 0 ||
                    141:        (src->seqno == seqno && src->metric > metric)) {
                    142:         src->seqno = seqno;
                    143:         src->metric = metric;
                    144:     }
                    145:     src->time = babel_now.tv_sec;
                    146: }
                    147: 
                    148: void
                    149: expire_sources()
                    150: {
                    151:     struct source *src;
                    152: 
                    153:     src = srcs;
                    154:     while(src) {
                    155:         if(src->time > babel_now.tv_sec)
                    156:             /* clock stepped */
                    157:             src->time = babel_now.tv_sec;
                    158:         if(src->time < babel_now.tv_sec - SOURCE_GC_TIME) {
                    159:             struct source *old = src;
                    160:             src = src->next;
                    161:             flush_source(old);
                    162:             continue;
                    163:         }
                    164:         src = src->next;
                    165:     }
                    166: }
                    167: 
                    168: void
                    169: check_sources_released(void)
                    170: {
                    171:     struct source *src;
                    172: 
                    173:     for(src = srcs; src; src = src->next) {
                    174:         if(src->route_count != 0)
                    175:             fprintf(stderr, "Warning: source %s %s has refcount %d.\n",
                    176:                     format_eui64(src->id),
                    177:                     format_prefix(src->prefix, src->plen),
                    178:                     (int)src->route_count);
                    179:     }
                    180: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>