Merge branch 'niit' into tunnel
[olsrd.git] / src / olsr.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 /**
43  * All these functions are global
44  */
45
46 #include "defs.h"
47 #include "olsr.h"
48 #include "link_set.h"
49 #include "two_hop_neighbor_table.h"
50 #include "tc_set.h"
51 #include "duplicate_set.h"
52 #include "mpr_selector_set.h"
53 #include "mid_set.h"
54 #include "mpr.h"
55 #include "lq_mpr.h"
56 #include "olsr_spf.h"
57 #include "scheduler.h"
58 #include "apm.h"
59 #include "misc.h"
60 #include "neighbor_table.h"
61 #include "log.h"
62 #include "lq_packet.h"
63 #include "common/avl.h"
64 #include "net_olsr.h"
65 #include "lq_plugin.h"
66 #include "gateway.h"
67
68 #include <stdarg.h>
69 #include <signal.h>
70 #include <unistd.h>
71
72 bool changes_topology;
73 bool changes_neighborhood;
74 bool changes_hna;
75 bool changes_force;
76
77 /*COLLECT startup sleeps caused by warnings*/
78
79 #ifdef OLSR_COLLECT_STARTUP_SLEEP
80 static int max_startup_sleep = 0;
81 #endif
82 static int sum_startup_sleep = 0;
83
84 void olsr_startup_sleep(int s)
85 {
86   sum_startup_sleep += s;
87 #ifdef OLSR_COLLECT_STARTUP_SLEEP
88   if (s > max_startup_sleep) max_startup_sleep=s;
89 #else
90   sleep(s);
91 #endif
92 }
93
94 void olsr_do_startup_sleep(void)
95 {
96 #ifdef OLSR_COLLECT_STARTUP_SLEEP
97   if (sum_startup_sleep > max_startup_sleep)
98     printf("OLSR encountered multiple problems on startup, which should delay startup by %i seconds.\nAs this is quite much time, OLSR will sleep only %i seconds.\nBUT YOU SHOULD FIX ABOVE PROBLEMS!\n",
99            sum_startup_sleep,max_startup_sleep);
100   sleep(max_startup_sleep);
101 #else
102   if (sum_startup_sleep > 0) 
103     printf("olsrd startup was delayed %i seconds due to various nasty error messages.\nYOU SHOULD REALLY FIX ABOVE PROBLEMS!\n",
104            sum_startup_sleep);
105 #endif
106 }
107
108 /**
109  * Process changes functions
110  */
111
112 struct pcf {
113   int (*function) (int, int, int);
114   struct pcf *next;
115 };
116
117 static struct pcf *pcf_list;
118
119 static uint16_t message_seqno;
120 union olsr_ip_addr all_zero;
121
122 /**
123  *Initialize the message sequence number as a random value
124  */
125 void
126 init_msg_seqno(void)
127 {
128   message_seqno = random() & 0xFFFF;
129 }
130
131 /**
132  * Get and increment the message sequence number
133  *
134  *@return the seqno
135  */
136 uint16_t
137 get_msg_seqno(void)
138 {
139   return message_seqno++;
140 }
141
142 void
143 register_pcf(int (*f) (int, int, int))
144 {
145   struct pcf *new_pcf;
146
147   OLSR_PRINTF(1, "Registering pcf function\n");
148
149   new_pcf = olsr_malloc(sizeof(struct pcf), "New PCF");
150
151   new_pcf->function = f;
152   new_pcf->next = pcf_list;
153   pcf_list = new_pcf;
154
155 }
156
157 /**
158  *Process changes in neighborhood or/and topology.
159  *Re-calculates the neighborhood/topology if there
160  *are any updates - then calls the right functions to
161  *update the routing table.
162  *@return 0
163  */
164 void
165 olsr_process_changes(void)
166 {
167   struct pcf *tmp_pc_list;
168
169 #ifdef DEBUG
170   if (changes_neighborhood)
171     OLSR_PRINTF(3, "CHANGES IN NEIGHBORHOOD\n");
172   if (changes_topology)
173     OLSR_PRINTF(3, "CHANGES IN TOPOLOGY\n");
174   if (changes_hna)
175     OLSR_PRINTF(3, "CHANGES IN HNA\n");
176 #endif
177
178   if (!changes_force && 2 <= olsr_cnf->lq_level && 0 >= olsr_cnf->lq_dlimit)
179     return;
180
181   if (!changes_neighborhood && !changes_topology && !changes_hna)
182     return;
183
184   if (olsr_cnf->debug_level > 0 && olsr_cnf->clear_screen && isatty(1)) {
185     clear_console();
186     printf("       *** %s (%s on %s) ***\n", olsrd_version, build_date, build_host);
187   }
188
189   if (changes_neighborhood) {
190     if (olsr_cnf->lq_level < 1) {
191       olsr_calculate_mpr();
192     } else {
193       olsr_calculate_lq_mpr();
194     }
195   }
196
197   /* calculate the routing table */
198   if (changes_neighborhood || changes_topology || changes_hna) {
199     olsr_calculate_routing_table();
200   }
201
202   if (olsr_cnf->debug_level > 0) {
203     if (olsr_cnf->debug_level > 2) {
204       olsr_print_mid_set();
205
206       if (olsr_cnf->debug_level > 3) {
207         if (olsr_cnf->debug_level > 8) {
208           olsr_print_duplicate_table();
209         }
210         olsr_print_hna_set();
211       }
212     }
213 #if 1
214     olsr_print_link_set();
215     olsr_print_neighbor_table();
216     olsr_print_two_hop_neighbor_table();
217     olsr_print_tc_table();
218
219     // TODO push this to debug level 3 or 4
220     olsr_print_gateway();
221 #endif
222   }
223
224   for (tmp_pc_list = pcf_list; tmp_pc_list != NULL; tmp_pc_list = tmp_pc_list->next) {
225     tmp_pc_list->function(changes_neighborhood, changes_topology, changes_hna);
226   }
227
228   changes_neighborhood = false;
229   changes_topology = false;
230   changes_hna = false;
231   changes_force = false;
232 }
233
234 /*
235  * Callback for the periodic route calculation.
236  */
237 void
238 olsr_trigger_forced_update(void *unused __attribute__ ((unused)))
239 {
240
241   changes_force = true;
242   changes_neighborhood = true;
243   changes_topology = true;
244   changes_hna = true;
245
246   olsr_process_changes();
247 }
248
249 /**
250  *Initialize all the tables used(neighbor,
251  *topology, MID,  HNA, MPR, dup).
252  *Also initalizes other variables
253  */
254 void
255 olsr_init_tables(void)
256 {
257   changes_topology = false;
258   changes_neighborhood = false;
259   changes_hna = false;
260
261   /* Set avl tree comparator */
262   if (olsr_cnf->ipsize == 4) {
263     avl_comp_default = avl_comp_ipv4;
264     avl_comp_prefix_default = avl_comp_ipv4_prefix;
265   } else {
266     avl_comp_default = avl_comp_ipv6;
267     avl_comp_prefix_default = avl_comp_ipv6_prefix;
268   }
269
270   /* Initialize lq plugin set */
271   init_lq_handler_tree();
272
273   /* Initialize link set */
274   olsr_init_link_set();
275
276   /* Initialize duplicate table */
277   olsr_init_duplicate_set();
278
279   /* Initialize neighbor table */
280   olsr_init_neighbor_table();
281
282   /* Initialize routing table */
283   olsr_init_routing_table();
284
285   /* Initialize two hop table */
286   olsr_init_two_hop_table();
287
288   /* Initialize topology */
289   olsr_init_tc();
290
291   /* Initialize mpr selector table */
292   olsr_init_mprs_set();
293
294   /* Initialize MID set */
295   olsr_init_mid_set();
296
297   /* Initialize HNA set */
298   olsr_init_hna_set();
299
300   /* Initialize smart gateways */
301   olsr_init_gateways();
302
303   /* Start periodic SPF and RIB recalculation */
304   if (olsr_cnf->lq_dinter > 0.0) {
305     olsr_start_timer((unsigned int)(olsr_cnf->lq_dinter * MSEC_PER_SEC), 5, OLSR_TIMER_PERIODIC, &olsr_trigger_forced_update, NULL,
306                      0);
307   }
308 }
309
310 /**
311  *Check if a message is to be forwarded and forward
312  *it if necessary.
313  *
314  *@param m the OLSR message to be forwarded
315  *@param neighbour we received message from
316  *
317  *@returns positive if forwarded
318  */
319 int
320 olsr_forward_message(union olsr_message *m, struct interface *in_if, union olsr_ip_addr *from_addr)
321 {
322   union olsr_ip_addr *src;
323   struct neighbor_entry *neighbor;
324   int msgsize;
325   struct interface *ifn;
326
327
328   /*
329    * Sven-Ola: We should not flood the mesh with overdue messages. Because
330    * of a bug in parser.c:parse_packet, we have a lot of messages because
331    * all older olsrd's have lq_fish enabled.
332    */
333   if (AF_INET == olsr_cnf->ip_version) {
334     if (m->v4.ttl < 2 || 255 < (int)m->v4.hopcnt + (int)m->v4.ttl)
335       return 0;
336   } else {
337     if (m->v6.ttl < 2 || 255 < (int)m->v6.hopcnt + (int)m->v6.ttl)
338       return 0;
339   }
340
341   /* Lookup sender address */
342   src = mid_lookup_main_addr(from_addr);
343   if (!src)
344     src = from_addr;
345
346   neighbor = olsr_lookup_neighbor_table(src);
347   if (!neighbor)
348     return 0;
349
350   if (neighbor->status != SYM)
351     return 0;
352
353   /* Check MPR */
354   if (olsr_lookup_mprs_set(src) == NULL) {
355 #ifdef DEBUG
356     struct ipaddr_str buf;
357     OLSR_PRINTF(5, "Forward - sender %s not MPR selector\n", olsr_ip_to_string(&buf, src));
358 #endif
359     return 0;
360   }
361
362   if (olsr_message_is_duplicate(m)) {
363     return 0;
364   }
365
366   /* Treat TTL hopcnt */
367   if (olsr_cnf->ip_version == AF_INET) {
368     /* IPv4 */
369     m->v4.hopcnt++;
370     m->v4.ttl--;
371   } else {
372     /* IPv6 */
373     m->v6.hopcnt++;
374     m->v6.ttl--;
375   }
376
377   /* Update packet data */
378   msgsize = ntohs(m->v4.olsr_msgsize);
379
380   /* looping trough interfaces */
381   for (ifn = ifnet; ifn; ifn = ifn->int_next) {
382     if (net_output_pending(ifn)) {
383
384       /* dont forward to incoming interface if interface is mode ether */
385       if (in_if->mode == IF_MODE_ETHER && ifn == in_if) continue;
386
387       /*
388        * Check if message is to big to be piggybacked
389        */
390       if (net_outbuffer_push(ifn, m, msgsize) != msgsize) {
391         /* Send */
392         net_output(ifn);
393         /* Buffer message */
394         set_buffer_timer(ifn);
395
396         if (net_outbuffer_push(ifn, m, msgsize) != msgsize) {
397           OLSR_PRINTF(1, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msgsize);
398           olsr_syslog(OLSR_LOG_ERR, "Received message to big to be forwarded on %s(%d bytes)!", ifn->int_name, msgsize);
399         }
400       }
401     } else {
402       /* No forwarding pending */
403       set_buffer_timer(ifn);
404
405       if (net_outbuffer_push(ifn, m, msgsize) != msgsize) {
406         OLSR_PRINTF(1, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msgsize);
407         olsr_syslog(OLSR_LOG_ERR, "Received message to big to be forwarded on %s(%d bytes)!", ifn->int_name, msgsize);
408       }
409     }
410   }
411   return 1;
412 }
413
414 void
415 set_buffer_timer(struct interface *ifn)
416 {
417   /* Set timer */
418   ifn->fwdtimer = GET_TIMESTAMP(random() * olsr_cnf->max_jitter * MSEC_PER_SEC / RAND_MAX);
419 }
420
421 void
422 olsr_init_willingness(void)
423 {
424   if (olsr_cnf->willingness_auto) {
425
426     /* Run it first and then periodic. */
427     olsr_update_willingness(NULL);
428
429     olsr_start_timer((unsigned int)olsr_cnf->will_int * MSEC_PER_SEC, 5, OLSR_TIMER_PERIODIC, &olsr_update_willingness, NULL, 0);
430   }
431 }
432
433 void
434 olsr_update_willingness(void *foo __attribute__ ((unused)))
435 {
436   int tmp_will = olsr_cnf->willingness;
437
438   /* Re-calculate willingness */
439   olsr_cnf->willingness = olsr_calculate_willingness();
440
441   if (tmp_will != olsr_cnf->willingness) {
442     OLSR_PRINTF(1, "Local willingness updated: old %d new %d\n", tmp_will, olsr_cnf->willingness);
443   }
444 }
445
446 /**
447  *Calculate this nodes willingness to act as a MPR
448  *based on either a fixed value or the power status
449  *of the node using APM
450  *
451  *@return a 8bit value from 0-7 representing the willingness
452  */
453
454 uint8_t
455 olsr_calculate_willingness(void)
456 {
457   struct olsr_apm_info ainfo;
458
459   /* If fixed willingness */
460   if (!olsr_cnf->willingness_auto)
461     return olsr_cnf->willingness;
462
463   if (apm_read(&ainfo) < 1)
464     return WILL_DEFAULT;
465
466   apm_printinfo(&ainfo);
467
468   /* If AC powered */
469   if (ainfo.ac_line_status == OLSR_AC_POWERED)
470     return 6;
471
472   /* If battery powered
473    *
474    * juice > 78% will: 3
475    * 78% > juice > 26% will: 2
476    * 26% > juice will: 1
477    */
478   return (ainfo.battery_percentage / 26);
479 }
480
481 const char *
482 olsr_msgtype_to_string(uint8_t msgtype)
483 {
484   static char type[20];
485
486   switch (msgtype) {
487   case (HELLO_MESSAGE):
488     return "HELLO";
489   case (TC_MESSAGE):
490     return "TC";
491   case (MID_MESSAGE):
492     return "MID";
493   case (HNA_MESSAGE):
494     return "HNA";
495   case (LQ_HELLO_MESSAGE):
496     return ("LQ-HELLO");
497   case (LQ_TC_MESSAGE):
498     return ("LQ-TC");
499   default:
500     break;
501   }
502
503   snprintf(type, sizeof(type), "UNKNOWN(%d)", msgtype);
504   return type;
505 }
506
507 const char *
508 olsr_link_to_string(uint8_t linktype)
509 {
510   static char type[20];
511
512   switch (linktype) {
513   case (UNSPEC_LINK):
514     return "UNSPEC";
515   case (ASYM_LINK):
516     return "ASYM";
517   case (SYM_LINK):
518     return "SYM";
519   case (LOST_LINK):
520     return "LOST";
521   case (HIDE_LINK):
522     return "HIDE";
523   default:
524     break;
525   }
526
527   snprintf(type, sizeof(type), "UNKNOWN(%d)", linktype);
528   return type;
529 }
530
531 const char *
532 olsr_status_to_string(uint8_t status)
533 {
534   static char type[20];
535
536   switch (status) {
537   case (NOT_NEIGH):
538     return "NOT NEIGH";
539   case (SYM_NEIGH):
540     return "NEIGHBOR";
541   case (MPR_NEIGH):
542     return "MPR";
543   default:
544     break;
545   }
546
547   snprintf(type, sizeof(type), "UNKNOWN(%d)", status);
548   return type;
549 }
550
551 /**
552  *Termination function to be called whenever a error occures
553  *that requires the daemon to terminate
554  *
555  *@param msg the message to write to the syslog and possibly stdout
556  */
557
558 void
559 olsr_exit(const char *msg, int val)
560 {
561   OLSR_PRINTF(1, "OLSR EXIT: %s\n", msg);
562   olsr_syslog(OLSR_LOG_ERR, "olsrd exit: %s\n", msg);
563   fflush(stdout);
564   olsr_cnf->exit_value = val;
565
566   raise(SIGTERM);
567 }
568
569 /**
570  * Wrapper for malloc(3) that does error-checking
571  *
572  * @param size the number of bytes to allocalte
573  * @param caller a string identifying the caller for
574  * use in error messaging
575  *
576  * @return a void pointer to the memory allocated
577  */
578 void *
579 olsr_malloc(size_t size, const char *id)
580 {
581   void *ptr;
582
583   /*
584    * Not all the callers do a proper cleaning of memory.
585    * Clean it on behalf of those.
586    */
587   ptr = calloc(1, size);
588
589   if (!ptr) {
590     const char *const err_msg = strerror(errno);
591     OLSR_PRINTF(1, "OUT OF MEMORY: %s\n", err_msg);
592     olsr_syslog(OLSR_LOG_ERR, "olsrd: out of memory!: %s\n", err_msg);
593     olsr_exit(id, EXIT_FAILURE);
594   }
595 #if 0
596   /* useful for debugging */
597   olsr_printf(1, "MEMORY: alloc %s %p, %u bytes\n", id, ptr, size);
598 #endif
599
600   return ptr;
601 }
602
603 /**
604  *Wrapper for printf that prints to a specific
605  *debuglevel upper limit
606  *
607  */
608
609 int
610 olsr_printf(int loglevel, const char *format, ...)
611 {
612   if ((loglevel <= olsr_cnf->debug_level) && debug_handle) {
613     va_list arglist;
614     va_start(arglist, format);
615     vfprintf(debug_handle, format, arglist);
616     va_end(arglist);
617   }
618   return 0;
619 }
620
621 /*
622  * Local Variables:
623  * c-basic-offset: 2
624  * indent-tabs-mode: nil
625  * End:
626  */