get_route.c

00001 /* Copyright 2008 Michael Marsh, University of Maryland.
00002  *
00003  * This file is part of pydtn.
00004  *
00005  * pydtn is free software: you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation, either version 3 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * pydtn is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with pydtn.  If not, see <http://www.gnu.org/licenses/>.
00017  *
00018  * The views and conclusions contained in the software and documentation
00019  * are those of the authors and should not be interpreted as representing
00020  * official policies, either expressed or implied, of the University
00021  * of Maryland.
00022  *
00023  * pydtn extends and embeds the Python interpreter, which is
00024  * Copyright 2001-2006 Python Software Foundation, All Rights Reserved,
00025  * and is released under the PSF License Agreement.
00026  *
00027  * RANLUX random number generation uses the Boost library,
00028  * Copyright 1994-2006 by various authors (details in individual files),
00029  * which is released under the Boost Software License, Version 1.0.
00030  */
00031 
00032 #include "aodv.h"
00033 
00034 aodv_table_entry_t*
00035 aodv_get_route( aodv_state_t* state,
00036                 const aodv_addr_t* source,
00037                 const aodv_addr_t* destination,
00038                 int* ecode )
00039 {
00040    unsigned char have_ecode = 0;
00041    unsigned char need_rreq = 0;
00042    aodv_table_entry_t* retval = NULL;
00043    aodv_rreq_t* crreq;
00044    struct timeval* tv;
00045    unsigned long timeout;
00046 
00047    if ( NULL != ecode )
00048    {
00049       have_ecode = 1;
00050       *ecode = AODV_GR_OK;
00051    }
00052 
00053    if ( NULL == state )
00054    {
00055       if ( have_ecode ) *ecode = AODV_GR_NULLSTATE;
00056       return NULL;
00057    }
00058 
00059    retval = aodv_lookup( &(state->routing_table), destination );
00060    if ( NULL != retval )
00061    {
00062       if ( aodv_table_entry_is_expired( retval ) )
00063       {
00064          if ( retval->valid_route )
00065          {
00066             retval->valid_route = 0;
00067             aodv_incr_seq_base( &(retval->dest_seq) );
00068          }
00069          else
00070          {
00071             remove_aodv_table_entry( &(state->routing_table), retval );
00072             retval = NULL;
00073          }
00074       }
00075       else
00076       {
00077          if ( retval->valid_route )
00078          {
00079             aodv_update_route_expiry( state, retval );
00080             return retval;
00081          }
00082          else
00083          {
00084             aodv_update_invalid_route_lifetime( state, retval );
00085          }
00086       }
00087    }
00088 
00089    if ( ( 0 != aodv_cmp_addr( source, &(state->self) ) ) &&
00090         ( ( NULL == retval ) ||
00091           ( ! retval->valid_route ) ) )
00092    {
00093       aodv_rerr_t rerr;
00094       rerr.dest_count = 1;
00095       rerr.unreachable = 0;
00096       uint32_t seq = 0;
00097       if ( 0 != retval )
00098       {
00099          seq = retval->dest_seq;
00100       }
00101       aodv_add_to_node_list( &(rerr.unreachable), destination, seq );
00102       if ( aodv_insert_time( state->rerr_time_ring ) )
00103       {
00104          aodv_bcast_rerr( state, &rerr );
00105       }
00106       if ( have_ecode ) *ecode = AODV_GR_NOROUTE;
00107       return NULL;
00108    }
00109 
00110    need_rreq = 1;
00111 
00112    crreq = state->rreq_buffer;
00113    if ( NULL != crreq )
00114    {
00115       do
00116       {
00117          if ( 0 == aodv_cmp_addr( &(crreq->destination), destination ) )
00118          {
00119             need_rreq = 0;
00120             if ( aodv_pasttime( &(crreq->buffer_time) ) )
00121             {
00122                if ( crreq->ntries < state->params.rreq_tries )
00123                {
00124                   if ( aodv_insert_time( state->rreq_time_ring ) )
00125                   {
00126                      timeout =
00127                         ( 1 << crreq->ntries ) *
00128                         state->params.net_traversal_time;
00129                      (crreq->ntries)++;
00130                      crreq->rreq_id = aodv_incr_rreq_id(state);
00131                      tv = &(crreq->buffer_time);
00132                      aodv_gettime(tv);
00133                      tv->tv_usec += 1000 * timeout;
00134                      while ( tv->tv_usec >= 1000000 )
00135                      {
00136                         tv->tv_usec -= 1000000;
00137                         tv->tv_sec += 1;
00138                      }
00139                      aodv_bcast_rreq( state, crreq );
00140                      if ( have_ecode ) *ecode = AODV_GR_PENDING;
00141                      return NULL;
00142                   }
00143                }
00144                else
00145                {
00146                   if ( have_ecode ) *ecode = AODV_GR_NOROUTE;
00147                   unbuffer_aodv_rreq( state, crreq );
00148                   return NULL;
00149                }
00150             }
00151             if ( have_ecode ) *ecode = AODV_GR_PENDING;
00152             return NULL;
00153          }
00154          crreq = crreq->next;
00155       } while ( need_rreq && ( crreq != state->rreq_buffer ) );
00156    }
00157 
00158    if ( have_ecode ) *ecode = AODV_GR_PENDING;
00159 
00160    if ( need_rreq )
00161    {
00162       if ( ! aodv_generate_rreq( state, destination ) )
00163       {
00164          if ( have_ecode ) *ecode = AODV_GR_ERROR;
00165       }
00166    }
00167 
00168    return NULL;
00169 }
00170 

Generated on Mon Mar 24 11:15:45 2008 for Pydtn Simulator by  doxygen 1.5.4