Annotation of embedaddon/quagga/babeld/source.c, revision 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>