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