tora_dest.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 /*
00003  * Copyright (c) 1997 Regents of the University of California.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. All advertising materials mentioning features or use of this software
00015  *    must display the following acknowledgement:
00016  *      This product includes software developed by the Computer Systems
00017  *      Engineering Group at Lawrence Berkeley Laboratory.
00018  * 4. Neither the name of the University nor of the Laboratory may be used
00019  *    to endorse or promote products derived from this software without
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  */
00034 /* Ported from CMU/Monarch's code */
00035 /* 
00036    $Id: tora_dest.cc,v 1.2 1999/08/12 21:12:29 yaxu Exp $
00037    */
00038 
00039 #include <agent.h>
00040 #include <random.h>
00041 #include <trace.h>
00042 
00043 #include <ll.h>
00044 #include <priqueue.h>
00045 #include <tora/tora_packet.h>
00046 #include <tora/tora.h>
00047 
00048 #define CURRENT_TIME    Scheduler::instance().clock()
00049 
00050 /* ======================================================================
00051    TORADest Class Functions
00052    ====================================================================== */
00053 TORADest::TORADest(nsaddr_t id, Agent *a) :  height(id)
00054 {
00055     index = id;
00056 
00057     rt_req = 0;
00058     time_upd = 0.0;
00059 
00060     time_rt_req = 0.0;
00061     time_tx_qry = 0.0;
00062 
00063     LIST_INIT(&nblist);
00064     num_active = num_down = num_up = 0;
00065 
00066         agent = (toraAgent*) a;
00067 }
00068 
00069 
00070 void
00071 TORADest::dump()
00072 {
00073     TORANeighbor *tn = nb_find_next_hop();
00074 
00075     fprintf(stdout, "\tDEST: %d, RT Req: %x, Time UPD: %f\n",
00076         index, rt_req, time_upd);
00077     fprintf(stdout, "\t\ttau: %f, oid: %d, r: %d, delta: %d, id: %d\n",
00078         height.tau, height.oid, height.r, height.delta, height.id);
00079     fprintf(stdout, "\t\tActive: %d, Down: %d, Up: %d, Next Hop: %d\n\n",
00080         num_active, num_down, num_up, tn ? tn->index : -1);
00081 
00082     for(tn = nblist.lh_first; tn; tn = tn->link.le_next)
00083         tn->dump();
00084 }
00085 
00086 
00087 /* ====================================================================== */
00088 
00089 TORANeighbor*
00090 TORADest::nb_add(nsaddr_t id)
00091 {
00092     TORANeighbor *tn = new TORANeighbor(id, agent);
00093     assert(tn);
00094 
00095     LIST_INSERT_HEAD(&nblist, tn, link);
00096 
00097     num_active += 1;
00098     if(tn->index == index) {
00099         tn->height.Zero();
00100         tn->lnk_stat = LINK_DN;
00101         num_down += 1;
00102     }
00103 
00104     return tn;
00105 }
00106 
00107 
00108 int
00109 TORADest::nb_del(nsaddr_t id)
00110 {
00111     TORANeighbor *tn = nblist.lh_first;
00112 
00113     for( ; tn; tn = tn->link.le_next) {
00114         if(tn->index == id) {
00115 
00116             num_active -= 1;
00117 
00118             if(tn->lnk_stat == LINK_DN)
00119                 num_down -=1;
00120             if(tn->lnk_stat == LINK_UP)
00121                 num_up -= 1;
00122 
00123 
00124             LIST_REMOVE(tn, link);
00125             delete tn;
00126 
00127                         /*
00128                          *  Here's were we decide whether or not to
00129                          *  do route maintenance.
00130                          */
00131                         if(num_down == 0) {
00132                 if(num_up > 0) {
00133                     update_height(CURRENT_TIME,
00134                               index,
00135                               0,
00136                               0,
00137                               index);
00138                 } else {
00139                     update_height(-1,
00140                               -1,
00141                               -1,
00142                               -1,
00143                               index);
00144                     // set height to NULL
00145                 }
00146 
00147                 agent->logNbDeletedLastDN(this);
00148 
00149                 return 1;
00150                 // send an UPDATE packet
00151             }
00152             return 0;
00153         }
00154     }
00155         return 0;
00156 }
00157 
00158 
00159 TORANeighbor*
00160 TORADest::nb_find(nsaddr_t id)
00161 {
00162     TORANeighbor *tn = nblist.lh_first;
00163     for( ; tn; tn = tn->link.le_next) {
00164         if(tn->index == id)
00165             return tn;
00166     }
00167     return 0;
00168 }
00169 
00170 
00171 TORANeighbor*
00172 TORADest::nb_find_next_hop()
00173 {
00174     TORANeighbor *tn = nblist.lh_first;
00175     TORANeighbor *tn_min = 0;
00176 
00177     for( ; tn; tn = tn->link.le_next) {
00178         if(tn->height.isNull())
00179                         continue;
00180 
00181                 if(tn->lnk_stat != LINK_DN)
00182                         continue;
00183 
00184                 if(tn_min == 0 || tn_min->height.compare(&tn->height) < 0) {
00185                         tn_min = tn;
00186                 }
00187     }
00188     assert(tn_min == 0 || tn_min->lnk_stat == LINK_DN);
00189     return tn_min;
00190 }
00191 
00192 
00193 /*
00194  *  Find a neighbor of minimum height, subject to the constraint
00195  *  that height.r == R.
00196  */
00197 TORANeighbor*
00198 TORADest::nb_find_min_height(int R)
00199 {
00200     TORANeighbor *tn = nblist.lh_first;
00201     TORANeighbor *tn_min = 0;
00202 
00203     for( ; tn; tn = tn->link.le_next) {
00204         if(tn->height.r == R) {
00205             if(tn_min == 0 ||
00206                            tn_min->height.compare(&tn->height) < 0)
00207                 tn_min = tn;
00208         }
00209     }
00210     return tn_min;
00211 }
00212 
00213 
00214 /*
00215  *  Find a neighbor of minimum height, subject to the constraint
00216  *  that height.(tau,oid,r) == (tau,oid,r) and height != NULL
00217  */
00218 TORANeighbor*
00219 TORADest::nb_find_min_nonnull_height(Height *h)
00220 {
00221     TORANeighbor *tn = nblist.lh_first;
00222     TORANeighbor *tn_min = 0;
00223 
00224     assert(h);
00225 
00226     for( ; tn; tn = tn->link.le_next) {
00227         if(tn->height.isNull() == 0 &&
00228            tn->height.tau == h->tau &&
00229            tn->height.oid == h->oid &&
00230            tn->height.r == h->r) {
00231             if(tn_min == 0 ||
00232                            tn_min->height.compare(&tn->height) < 0)
00233                 tn_min = tn;
00234         }
00235     }
00236     return tn_min;
00237 }
00238 
00239 
00240 /*
00241  *  Find a neighbor of maximum height, subject to the constraint
00242  *  that height != NULL.
00243  */
00244 TORANeighbor*
00245 TORADest::nb_find_max_height()
00246 {
00247     TORANeighbor *tn = nblist.lh_first;
00248     TORANeighbor *tn_max = 0;
00249 
00250     for( ; tn; tn = tn->link.le_next) {
00251         if(tn->height.isNull() == 0) {
00252             if(tn_max == 0 ||
00253                            tn_max->height.compare(&tn->height) > 0)
00254                 tn_max = tn;
00255         }
00256     }
00257     return tn_max;
00258 }
00259 
00260 
00261 // Verify that all neighbors of non-null height have the same reference
00262 // level.
00263 int
00264 TORADest::nb_check_same_ref()
00265 {
00266     TORANeighbor *tn = nblist.lh_first;
00267     TORANeighbor *tref = 0;
00268 
00269     for( ; tn; tn = tn->link.le_next) {
00270         if(tn->height.isNull() == 0) {
00271             if(tref == 0)
00272                 tref = tn;
00273             else if(tref->height.tau != tn->height.tau ||
00274                 tref->height.oid != tn->height.oid ||
00275                 tref->height.r != tn->height.r)
00276                 return 0;
00277         }
00278     }
00279     return 1;
00280 }
00281 
00282     
00283 void
00284 TORADest::update_height_nb(TORANeighbor *tn, struct hdr_tora_upd *uh)
00285 {
00286     Height h(uh->tu_id);
00287 
00288     h.tau = uh->tu_tau;
00289     h.oid = uh->tu_oid;
00290     h.r = uh->tu_r;
00291     h.delta = uh->tu_delta;
00292 
00293     tn->height.update(&h);
00294 
00295     /*
00296      *  Update num_down/num_up
00297      */
00298     if(tn->lnk_stat == LINK_DN)
00299         num_down -= 1;
00300     if(tn->lnk_stat == LINK_UP)
00301         num_up -= 1;
00302 
00303     tn->update_link_status(&height);
00304 
00305     /*
00306      *  Update num_down/num_up
00307      */
00308     if(tn->lnk_stat == LINK_DN)
00309         num_down += 1;
00310     if(tn->lnk_stat == LINK_UP)
00311         num_up += 1;
00312 }
00313 
00314 
00315 /*
00316  *  Updates the height of a destination and then recomputes
00317  *  all of the link status information for the neighbors.
00318  */
00319 void
00320 TORADest::update_height(double TAU, nsaddr_t OID, int R, int DELTA, nsaddr_t ID)
00321 {
00322     TORANeighbor *tn = nblist.lh_first;
00323 
00324     height.tau = TAU;
00325     height.oid = OID;
00326     height.r = R;
00327     height.delta = DELTA;
00328     height.id = ID;
00329 
00330 #ifdef LOGGING
00331         agent->log_dst_state_change(this);
00332 #endif
00333     num_active = num_down = num_up = 0;
00334 
00335     for( ; tn; tn = tn->link.le_next) {
00336 
00337         tn->update_link_status(&height);
00338 
00339         num_active += 1;
00340 
00341         if(tn->lnk_stat == LINK_DN)
00342             num_down += 1;
00343         if(tn->lnk_stat == LINK_UP)
00344             num_up += 1;
00345     }
00346 }
00347 

Generated on Tue Mar 6 16:47:52 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6