9238ca48c9c39a9a3728b26c2dff2218c8215c87
[olsrd.git] / src / mid_set.c
1 /*
2  * OLSR ad-hoc routing table management protocol
3  * Copyright (C) 2003 Andreas T√łnnesen (andreto@ifi.uio.no)
4  *
5  * This file is part of the olsr.org OLSR daemon.
6  *
7  * olsr.org is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * olsr.org is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with olsr.org; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  * 
21  * 
22  * $ Id $
23  *
24  */
25
26 #include "defs.h"
27 #include "two_hop_neighbor_table.h"
28 #include "mid_set.h"
29 #include "olsr.h"
30 #include "scheduler.h"
31 #include "neighbor_table.h"
32 #include "link_set.h"
33
34 /**
35  * Initialize the MID set
36  *
37  */
38
39 int
40 olsr_init_mid_set()
41 {
42   int index;
43
44   olsr_printf(5, "MID: init\n");
45
46   /* Since the holdingtime is assumed to be rather large for 
47    * MID entries, the timeoutfunction is only ran once every second
48    */
49   olsr_register_scheduler_event(&olsr_time_out_mid_set, 1, 0, NULL);
50
51   for(index=0;index<HASHSIZE;index++)
52     {
53       mid_set[index].next = &mid_set[index];
54       mid_set[index].prev = &mid_set[index];
55     }
56
57   return 1;
58 }
59
60
61 /**
62  *Insert a new interface alias to the interface association set.
63  *If the main interface of the association is not yet registered
64  *in the set a new entry is created.
65  *
66  *@param m_addr the main address of the node
67  *@param alias the alias address to insert
68  *
69  *@return nada
70  */
71
72 void 
73 insert_mid_tuple(union olsr_ip_addr *m_addr, struct addresses *alias, float vtime)
74 {
75   struct mid_entry *tmp;
76   struct addresses *tmp_adr;
77   struct neighbor_2_entry *tmp_2_neighbor;
78   olsr_u32_t hash;
79   struct neighbor_entry *tmp_neigh, *real_neigh;
80
81   //olsr_printf(5, "TC: lookup entry\n");
82
83   hash = olsr_hashing(m_addr);
84
85
86
87   /* Check for registered entry */
88   for(tmp = mid_set[hash].next;
89       tmp != &mid_set[hash];
90       tmp = tmp->next)
91     {
92       if(COMP_IP(&tmp->main_addr, m_addr))
93         break;
94     }
95          
96   /*If the address was registered*/ 
97   if(tmp != &mid_set[hash])
98     {
99       tmp_adr = tmp->aliases;
100       tmp->aliases = alias;
101       alias->next = tmp_adr;
102       olsr_get_timestamp((olsr_u32_t) vtime*1000, &tmp->ass_timer);
103     }
104       /*Create new node*/
105   else
106     {
107       tmp = olsr_malloc(sizeof(struct mid_entry), "MID new alias");
108
109       tmp->aliases = alias;
110       COPY_IP(&tmp->main_addr, m_addr);
111       olsr_get_timestamp((olsr_u32_t) vtime*1000, &tmp->ass_timer);
112       /* Queue */
113       QUEUE_ELEM(mid_set[hash], tmp);
114       /*
115       tmp->next = mid_set[hash].next;
116       tmp->prev = &mid_set[hash];
117       mid_set[hash].next->prev = tmp;
118       mid_set[hash].next = tmp;
119       */
120     }
121   
122
123
124   /*
125    * Delete possible duplicate entries in 2 hop set
126    * and delete duplicate neighbor entries. Redirect
127    * link entries to the correct neighbor entry.
128    *
129    *THIS OPTIMALIZATION IS NOT SPECIFIED IN RFC3626
130    */
131
132   tmp_adr = alias;
133
134   while(tmp_adr)
135     {
136
137       /* Delete possible 2 hop neighbor */
138       if((tmp_2_neighbor = olsr_lookup_two_hop_neighbor_table_mid(&tmp_adr->address)) != NULL)
139         {
140           olsr_printf(1, "Deleting 2 hop node from MID: %s to ", olsr_ip_to_string(&tmp_adr->address));
141           olsr_printf(1, "%s\n", olsr_ip_to_string(m_addr));
142
143           olsr_delete_two_hop_neighbor_table(tmp_2_neighbor);
144
145           changes_neighborhood = UP;
146         }
147
148       /* Delete a possible neighbor entry */
149       if(((tmp_neigh = olsr_lookup_neighbor_table_alias(&tmp_adr->address)) != NULL)
150          && ((real_neigh = olsr_lookup_neighbor_table_alias(m_addr)) != NULL))
151
152         {
153           olsr_printf(1, "[MID]Deleting bogus neighbor entry %s real ", olsr_ip_to_string(&tmp_adr->address));
154           olsr_printf(1, "%s\n", olsr_ip_to_string(m_addr));
155
156           replace_neighbor_link_set(tmp_neigh, real_neigh);
157
158           /* Delete the neighbor */
159           /* Dequeue */
160           DEQUEUE_ELEM(tmp_neigh);
161           //tmp_neigh->prev->next = tmp_neigh->next;
162           //tmp_neigh->next->prev = tmp_neigh->prev;
163           /* Delete */
164           free(tmp_neigh);
165
166           changes_neighborhood = UP;
167         }
168       
169       tmp_adr = tmp_adr->next;
170     }
171
172
173 }
174
175
176 /**
177  *Insert an alias address for a node.
178  *If the main address is not registered
179  *then a new entry is created.
180  *
181  *@param main_add the main address of the node
182  *@param alias the alias address to insert
183  *@param seq the sequence number to register a new node with
184  *
185  *@return nada
186  */
187 void
188 insert_mid_alias(union olsr_ip_addr *main_add, union olsr_ip_addr *alias, float vtime)
189 {
190   struct addresses *adr;
191
192   adr = olsr_malloc(sizeof(struct addresses), "Insert MID alias");
193
194   olsr_printf(1, "Inserting alias %s for ", olsr_ip_to_string(alias));
195   olsr_printf(1, "%s\n", olsr_ip_to_string(main_add));
196
197   COPY_IP(&adr->address, alias);
198   adr->next = NULL;
199
200   insert_mid_tuple(main_add, adr, vtime);
201
202   /*
203    *Recalculate topology
204    */
205   changes_neighborhood=UP;
206   changes_topology=UP;
207
208   //print_mid_list();
209 }
210
211
212
213
214 /**
215  *Lookup the main address for a alias address
216  *
217  *@param adr the alias address to check
218  *
219  *@return the main address registered on the alias
220  *or NULL if not found
221  */
222 union olsr_ip_addr *
223 mid_lookup_main_addr(union olsr_ip_addr *adr)
224 {
225
226   struct mid_entry *tmp_list;
227   struct addresses *tmp_addr;
228   int index;
229
230
231   for(index=0;index<HASHSIZE;index++)
232     {
233       tmp_list = mid_set[index].next;
234       /*Traverse MID list*/
235       while(tmp_list != &mid_set[index])
236         {
237           if(COMP_IP(&tmp_list->main_addr, adr))
238             return NULL;
239
240           tmp_addr = tmp_list->aliases;
241           /*And all aliases registered on them*/
242           while(tmp_addr)
243             {
244               if(COMP_IP(&tmp_addr->address, adr))
245                 return &tmp_list->main_addr;
246               tmp_addr = tmp_addr->next;
247             }
248
249           tmp_list = tmp_list->next;
250         }
251     }
252   return NULL;
253
254 }
255
256
257
258
259 /*
260  *Find all aliases for an address.
261  *
262  *@param adr the main address to search for
263  *
264  *@return a linked list of addresses structs
265  */
266 struct addresses *
267 mid_lookup_aliases(union olsr_ip_addr *adr)
268 {
269   struct mid_entry *tmp_list;
270   olsr_u32_t hash;
271
272   //olsr_printf(1, "MID: lookup entry...");
273
274   hash = olsr_hashing(adr);
275
276   /* Check all registered nodes...*/
277   for(tmp_list = mid_set[hash].next;
278       tmp_list != &mid_set[hash];
279       tmp_list = tmp_list->next)
280     {
281       if(COMP_IP(&tmp_list->main_addr, adr))
282         return tmp_list->aliases;
283     }
284
285
286   return NULL;
287 }
288
289
290 /**
291  *Update the timer for an entry
292  *
293  *@param adr the main address of the entry
294  *
295  *@return 1 if the node was updated, 0 if not
296  */
297 int
298 olsr_update_mid_table(union olsr_ip_addr *adr, float vtime)
299 {
300   struct mid_entry *tmp_list = mid_set;
301   olsr_u32_t hash;
302
303   olsr_printf(3, "MID: update %s\n", olsr_ip_to_string(adr));
304   hash = olsr_hashing(adr);
305
306   /* Check all registered nodes...*/
307   for(tmp_list = mid_set[hash].next;
308       tmp_list != &mid_set[hash];
309       tmp_list = tmp_list->next)
310     {
311       /*find match*/
312       if(COMP_IP(&tmp_list->main_addr, adr))
313         {
314           //printf("Updating timer for node %s\n",ip_to_string(&tmp_list->main_addr));
315           olsr_get_timestamp((olsr_u32_t) vtime*1000, &tmp_list->ass_timer);
316
317           return 1;
318         }
319     }
320   return 0;
321 }
322
323
324
325 /**
326  *Find timed out entries and delete them
327  *
328  *@return nada
329  */
330 void
331 olsr_time_out_mid_set()
332 {
333   struct mid_entry *tmp_list;
334   struct mid_entry *entry_to_delete;
335   int index;
336
337
338   for(index=0;index<HASHSIZE;index++)
339     {
340       tmp_list = mid_set[index].next;
341       /*Traverse MID list*/
342       while(tmp_list != &mid_set[index])
343         {
344           /*Check if the entry is timed out*/
345           if(TIMED_OUT(&tmp_list->ass_timer))
346             {
347               entry_to_delete = tmp_list;
348               tmp_list = tmp_list->next;
349 #ifdef DEBUG
350               olsr_printf(1, "MID info for %s timed out.. deleting it\n", 
351                           olsr_ip_to_string(&entry_to_delete->main_addr));
352 #endif
353               /*Delete it*/
354               mid_delete_node(entry_to_delete);
355             }
356           else
357               tmp_list = tmp_list->next;
358         }
359     }
360
361   return;
362 }
363
364
365 /*
366  *Delete an entry
367  *
368  *@param entry the entry to delete
369  *
370  *@return 1
371  */
372 int
373 mid_delete_node(struct mid_entry *entry)
374 {
375   struct addresses *aliases, *tmp_aliases;
376
377   /* Free aliases */
378   aliases = entry->aliases;
379   while(aliases)
380     {
381       tmp_aliases = aliases;
382       aliases = aliases->next;
383       free(tmp_aliases);
384     }
385   /* Dequeue */
386   DEQUEUE_ELEM(entry);
387   //entry->prev->next = entry->next;
388   //entry->next->prev = entry->prev;
389
390   free(entry);
391   
392   return 0;
393 }
394
395
396 /**
397  *Print all multiple interface info
398  *For debuging purposes
399  */
400 void
401 olsr_print_mid_set()
402 {
403
404   struct mid_entry *tmp_list;
405   struct addresses *tmp_addr;
406   int index;
407
408   olsr_printf(1, "mid set: %02d:%02d:%02d.%06lu\n",nowtm->tm_hour, nowtm->tm_min, nowtm->tm_sec, now.tv_usec);
409
410   for(index=0;index<HASHSIZE;index++)
411     {
412       tmp_list = mid_set[index].next;
413       /*Traverse MID list*/
414       for(tmp_list = mid_set[index].next;
415           tmp_list != &mid_set[index];
416           tmp_list = tmp_list->next)
417         {
418           olsr_printf(1, "%s: ", olsr_ip_to_string(&tmp_list->main_addr));
419           
420           tmp_addr = tmp_list->aliases;
421           
422           while(tmp_addr)
423             {
424               olsr_printf(1, " %s ", olsr_ip_to_string(&tmp_addr->address));
425               tmp_addr = tmp_addr->next;
426             }
427           olsr_printf(1, "\n");
428           
429         }
430     }
431
432 }
433
434
435
436
437