⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mid_set.c

📁 wifi 无线网络路由协议OLSR linux下C代码
💻 C
字号:
/* * The olsr.org Optimized Link-State Routing daemon(olsrd) * Copyright (c) 2004, Andreas T鴑nesen(andreto@olsr.org) * All rights reserved. * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met: * * * Redistributions of source code must retain the above copyright  *   notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright  *   notice, this list of conditions and the following disclaimer in  *   the documentation and/or other materials provided with the  *   distribution. * * Neither the name of olsr.org, olsrd nor the names of its  *   contributors may be used to endorse or promote products derived  *   from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  * POSSIBILITY OF SUCH DAMAGE. * * Visit http://www.olsr.org for more information. * * If you find this software useful feel free to make a donation * to the project. For more information see the website or contact * the copyright holders. * * $Id: mid_set.c,v 1.22 2007/09/17 22:24:22 bernd67 Exp $ */#include "defs.h"#include "two_hop_neighbor_table.h"#include "mid_set.h"#include "olsr.h"#include "scheduler.h"#include "neighbor_table.h"#include "link_set.h"#include "packet.h" /* struct mid_alias */struct mid_entry mid_set[HASHSIZE];struct mid_address reverse_mid_set[HASHSIZE];struct mid_entry *mid_lookup_entry_bymain(const union olsr_ip_addr *adr);/** * Initialize the MID set * */intolsr_init_mid_set(void){  int idx;  OLSR_PRINTF(5, "MID: init\n");  /* Since the holdingtime is assumed to be rather large for    * MID entries, the timeoutfunction is only ran once every second   */  olsr_register_scheduler_event_dijkstra(&olsr_time_out_mid_set, NULL, 1, 0, NULL);  for(idx=0;idx<HASHSIZE;idx++)    {      mid_set[idx].next = &mid_set[idx];      mid_set[idx].prev = &mid_set[idx];      reverse_mid_set[idx].next = &reverse_mid_set[idx];      reverse_mid_set[idx].prev = &reverse_mid_set[idx];    }  return 1;}/** *Insert a new interface alias to the interface association set. *If the main interface of the association is not yet registered *in the set a new entry is created. * *@param m_addr the main address of the node *@param alias the alias address to insert * *@return nada */void insert_mid_tuple(const union olsr_ip_addr *m_addr, struct mid_address *alias, float vtime){  struct mid_entry *tmp;  struct mid_address *tmp_adr;  olsr_u32_t hash, alias_hash;  union olsr_ip_addr *registered_m_addr;  hash = olsr_hashing(m_addr);  alias_hash = olsr_hashing(&alias->alias);  /* Check for registered entry */  for(tmp = mid_set[hash].next;      tmp != &mid_set[hash];      tmp = tmp->next)    {      if(COMP_IP(&tmp->main_addr, m_addr))	break;     }  /* Check if alias is already registered with m_addr */  registered_m_addr = mid_lookup_main_addr(&alias->alias);  if (registered_m_addr != NULL && COMP_IP(registered_m_addr, m_addr))    {      /* Alias is already registered with main address. Nothing to do here. */      return;    }  /*If the address was registered*/   if(tmp != &mid_set[hash])    {      tmp_adr = tmp->aliases;      tmp->aliases = alias;      alias->main_entry = tmp;      QUEUE_ELEM(reverse_mid_set[alias_hash], alias);      alias->next_alias = tmp_adr;      tmp->ass_timer = GET_TIMESTAMP(vtime*1000);    }  else    {      /*Create new node*/      tmp = olsr_malloc(sizeof(struct mid_entry), "MID new alias");      tmp->aliases = alias;      alias->main_entry = tmp;      QUEUE_ELEM(reverse_mid_set[alias_hash], alias);      COPY_IP(&tmp->main_addr, m_addr);      tmp->ass_timer = GET_TIMESTAMP(vtime*1000);      /* Queue */      QUEUE_ELEM(mid_set[hash], tmp);    }    /*   * Delete possible duplicate entries in 2 hop set   * and delete duplicate neighbor entries. Redirect   * link entries to the correct neighbor entry.   *   *THIS OPTIMIZATION IS NOT SPECIFIED IN RFC3626   */  tmp_adr = alias;  while(tmp_adr)    {      struct neighbor_2_entry *tmp_2_neighbor;      struct neighbor_entry *tmp_neigh, *real_neigh;      /* Delete possible 2 hop neighbor */      if((tmp_2_neighbor = olsr_lookup_two_hop_neighbor_table_mid(&tmp_adr->alias)) != NULL)	{	  OLSR_PRINTF(1, "Deleting 2 hop node from MID: %s to ", olsr_ip_to_string(&tmp_adr->alias));	  OLSR_PRINTF(1, "%s\n", olsr_ip_to_string(m_addr));	  olsr_delete_two_hop_neighbor_table(tmp_2_neighbor);	  changes_neighborhood = OLSR_TRUE;	}      /* Delete a possible neighbor entry */      if(((tmp_neigh = olsr_lookup_neighbor_table_alias(&tmp_adr->alias)) != NULL)	 && ((real_neigh = olsr_lookup_neighbor_table_alias(m_addr)) != NULL))	{	  OLSR_PRINTF(1, "[MID]Deleting bogus neighbor entry %s real ", olsr_ip_to_string(&tmp_adr->alias));	  OLSR_PRINTF(1, "%s\n", olsr_ip_to_string(m_addr));	  replace_neighbor_link_set(tmp_neigh, real_neigh);	  /* Dequeue */	  DEQUEUE_ELEM(tmp_neigh);	  /* Delete */	  free(tmp_neigh);	  changes_neighborhood = OLSR_TRUE;	}            tmp_adr = tmp_adr->next_alias;    }}/** *Insert an alias address for a node. *If the main address is not registered *then a new entry is created. * *@param main_add the main address of the node *@param alias the alias address to insert *@param seq the sequence number to register a new node with * *@return nada */voidinsert_mid_alias(const union olsr_ip_addr *main_add, const union olsr_ip_addr *alias, float vtime){  struct mid_address *adr;  struct neighbor_entry *ne_old, *ne_new;  struct mid_entry *me_old;  int ne_ref_rp_count;  adr = olsr_malloc(sizeof(struct mid_address), "Insert MID alias");    OLSR_PRINTF(1, "Inserting alias %s for ", olsr_ip_to_string(alias));  OLSR_PRINTF(1, "%s\n", olsr_ip_to_string(main_add));  COPY_IP(&adr->alias, alias);  adr->next_alias = NULL;    // If we have an entry for this alias in neighbortable, we better adjust it's  // main address, because otherwise a fatal inconsistency between  // neighbortable and link_set will be created by way of this mid entry.  ne_old = olsr_lookup_neighbor_table_alias(alias);  if (ne_old != NULL) {     OLSR_PRINTF(2, "Remote main address change detected. Mangling neighbortable to replace %s with %s.\n", olsr_ip_to_string(alias), olsr_ip_to_string(main_add));     olsr_delete_neighbor_table(alias);     ne_new = olsr_insert_neighbor_table(main_add);     // adjust pointers to neighbortable-entry in link_set     ne_ref_rp_count = replace_neighbor_link_set(ne_old, ne_new);     if (ne_ref_rp_count > 0)        OLSR_PRINTF(2, "Performed %d neighbortable-pointer replacements (%p -> %p) in link_set.\n", ne_ref_rp_count, ne_old, ne_new);          me_old = mid_lookup_entry_bymain(alias);     if (me_old) {        // we knew aliases to the previous main address; better forget about        // them now.        OLSR_PRINTF(2, "I already have an mid entry mapping addresses to this alias address. Removing existing mid entry to preserve consistency of mid_set.\n");        mid_delete_node(me_old);     }  }    insert_mid_tuple(main_add, adr, vtime);    /*   *Recalculate topology   */  changes_neighborhood = OLSR_TRUE;  changes_topology = OLSR_TRUE;    //print_mid_list();}/** *Lookup the main address for a alias address * *@param adr the alias address to check * *@return the main address registered on the alias *or NULL if not found */union olsr_ip_addr *mid_lookup_main_addr(const union olsr_ip_addr *adr){  olsr_u32_t hash;  struct mid_address *tmp_list;  hash = olsr_hashing(adr);  /*Traverse MID list*/  for(tmp_list = reverse_mid_set[hash].next;       tmp_list != &reverse_mid_set[hash];      tmp_list = tmp_list->next)	{	  if(COMP_IP(&tmp_list->alias, adr))	    return &tmp_list->main_entry->main_addr;	}  return NULL;}/* Find mid entry to an address. * @param adr the main address to search for * * @return a linked list of address structs */struct mid_entry *mid_lookup_entry_bymain(const union olsr_ip_addr *adr){  struct mid_entry *tmp_list;  olsr_u32_t hash;  //OLSR_PRINTF(1, "MID: lookup entry...");  hash = olsr_hashing(adr);  /* Check all registered nodes...*/  for(tmp_list = mid_set[hash].next;      tmp_list != &mid_set[hash];      tmp_list = tmp_list->next)    {      if(COMP_IP(&tmp_list->main_addr, adr))	return tmp_list;    }  return NULL;}/* *Find all aliases for an address. * *@param adr the main address to search for * *@return a linked list of addresses structs */struct mid_address *mid_lookup_aliases(const union olsr_ip_addr *adr){  struct mid_entry *tmp = mid_lookup_entry_bymain(adr);  return tmp ? tmp->aliases : NULL;}/** *Update the timer for an entry * *@param adr the main address of the entry * *@return 1 if the node was updated, 0 if not */intolsr_update_mid_table(const union olsr_ip_addr *adr, float vtime){  struct mid_entry *tmp_list = mid_set;  olsr_u32_t hash;  OLSR_PRINTF(3, "MID: update %s\n", olsr_ip_to_string(adr));  hash = olsr_hashing(adr);  /* Check all registered nodes...*/  for(tmp_list = mid_set[hash].next;      tmp_list != &mid_set[hash];      tmp_list = tmp_list->next)    {      /*find match*/      if(COMP_IP(&tmp_list->main_addr, adr))	{	  // printf("MID: Updating timer for node %s\n", olsr_ip_to_string(&tmp_list->main_addr));	  tmp_list->ass_timer = GET_TIMESTAMP(vtime*1000);	  return 1;	}    }  return 0;}/** *Remove aliases from 'entry' which are not listed in 'declared_aliases'. * *@param entry the MID entry *@param declared_aliases the list of declared aliases for the MID entry * *@return nada */voidolsr_prune_aliases(const union olsr_ip_addr *m_addr, struct mid_alias *declared_aliases){  struct mid_entry *entry;  olsr_u32_t hash;  struct mid_address *registered_aliases;  struct mid_address *previous_alias;  struct mid_alias *save_declared_aliases = declared_aliases;  hash = olsr_hashing(m_addr);  /* Check for registered entry */  for(entry = mid_set[hash].next;      entry != &mid_set[hash];      entry = entry->next)    {      if(COMP_IP(&entry->main_addr, m_addr))	break;    }  if(entry == &mid_set[hash])    {      /* MID entry not found, nothing to prune here */      return;    }  registered_aliases = entry->aliases;  previous_alias = NULL;  while(registered_aliases != NULL)    {      struct mid_address *current_alias = registered_aliases;      registered_aliases = registered_aliases->next_alias;      declared_aliases = save_declared_aliases;      /* Go through the list of declared aliases to find the matching current alias */      while(declared_aliases != 0 &&            ! COMP_IP(&current_alias->alias, &declared_aliases->alias_addr))        {          declared_aliases = declared_aliases->next;        }      if (declared_aliases == NULL)        {          /* Current alias not found in list of declared aliases: free current alias */          OLSR_PRINTF(1, "MID remove: (%s, ", olsr_ip_to_string(&entry->main_addr));            OLSR_PRINTF(1, "%s)\n", olsr_ip_to_string(&current_alias->alias));          /* Update linked list as seen by 'entry' */          if (previous_alias != NULL)            {              previous_alias->next_alias = current_alias->next_alias;            }          else            {              entry->aliases = current_alias->next_alias;            }          /* Remove from hash table */          DEQUEUE_ELEM(current_alias);           free(current_alias);          /*           *Recalculate topology           */          changes_neighborhood = OLSR_TRUE;          changes_topology = OLSR_TRUE;        }      else        {          previous_alias = current_alias;        }    }}/** *Find timed out entries and delete them * *@return nada */voidolsr_time_out_mid_set(void *foo __attribute__((unused))){  int idx;  for(idx=0;idx<HASHSIZE;idx++)    {      struct mid_entry *tmp_list = mid_set[idx].next;      /*Traverse MID list*/      while(tmp_list != &mid_set[idx])	{	  /*Check if the entry is timed out*/	  if(TIMED_OUT(tmp_list->ass_timer))	    {	      struct mid_entry *entry_to_delete = tmp_list;	      tmp_list = tmp_list->next;#ifdef DEBUG	      OLSR_PRINTF(1, "MID info for %s timed out.. deleting it\n",			  olsr_ip_to_string(&entry_to_delete->main_addr));#endif	      /*Delete it*/	      mid_delete_node(entry_to_delete);	    }	  else	      tmp_list = tmp_list->next;	}    }  return;}/* *Delete an entry * *@param entry the entry to delete * *@return 1 */intmid_delete_node(struct mid_entry *entry){  struct mid_address *aliases;  /* Free aliases */  aliases = entry->aliases;  while(aliases)    {      struct mid_address *tmp_aliases = aliases;      aliases = aliases->next_alias;      DEQUEUE_ELEM(tmp_aliases);      free(tmp_aliases);    }  /* Dequeue */  DEQUEUE_ELEM(entry);  free(entry);    return 0;}/** *Print all multiple interface info *For debuging purposes */voidolsr_print_mid_set(void){  int idx;  OLSR_PRINTF(1, "mid set: %02d:%02d:%02d.%06lu\n",nowtm->tm_hour, nowtm->tm_min, nowtm->tm_sec, now.tv_usec);  for(idx=0;idx<HASHSIZE;idx++)    {      struct mid_entry *tmp_list = mid_set[idx].next;      /*Traverse MID list*/      for(tmp_list = mid_set[idx].next; tmp_list != &mid_set[idx]; tmp_list = tmp_list->next)	{	  struct mid_address *tmp_addr;          	  OLSR_PRINTF(1, "%s: ", olsr_ip_to_string(&tmp_list->main_addr));          for(tmp_addr = tmp_list->aliases;tmp_addr;tmp_addr = tmp_addr->next_alias)	    {	      OLSR_PRINTF(1, " %s ", olsr_ip_to_string(&tmp_addr->alias));	    }	  OLSR_PRINTF(1, "\n");	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -