2c6836e2ad72cbbedc6fa0aa158d870265aadb33
[olsrd.git] / lib / pud / src / networkInterfaces.c
1 #include "networkInterfaces.h"
2
3 /* Plugin includes */
4 #include "pud.h"
5 #include "configuration.h"
6 #include "netTools.h"
7
8 /* OLSRD includes */
9 #include "olsr.h"
10 #include "interfaces.h"
11
12 /* System includes */
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <ifaddrs.h>
16
17 /*
18  * Main IP MAC address
19  */
20
21 /** the MAC address of the main IP address */
22 static unsigned char mac[PUD_NODEIDTYPE_MAC_BYTES] = { 0 };
23
24 /** true when the MAC address of the main IP address has been retrieved */
25 static bool macSet = false;
26
27 /**
28  * @return
29  * the MAC address of the main IP address
30  */
31 unsigned char * getMainIpMacAddress(void) {
32         if (!macSet) {
33                 struct ifreq ifr;
34                 unsigned char * macInIfr;
35
36                 struct interface *mainInterface = if_ifwithaddr(&olsr_cnf->main_addr);
37                 if (!mainInterface) {
38                         pudError(true, "Could not get the main interface");
39                         return NULL;
40                 }
41                 macInIfr = getHardwareAddress(mainInterface->int_name, olsr_cnf->ip_version, &ifr);
42                 if (!macInIfr) {
43                         pudError(true, "Could not get the MAC address of the main interface");
44                         return NULL;
45                 }
46                 memcpy(&mac[0], &macInIfr[0], PUD_NODEIDTYPE_MAC_BYTES);
47                 macSet = true;
48         }
49
50         return &mac[0];
51 }
52
53 /*
54  * RX interfaces
55  */
56
57 /** The list of network interface objects, receiving GPS NMEA sentences */
58 static TRxTxNetworkInterface *rxNetworkInterfacesListHead = NULL;
59
60 /** Pointer to the last network interface object, receiving GPS NMEA sentences */
61 static TRxTxNetworkInterface *lastRxNetworkInterface = NULL;
62
63 /**
64  @return
65  The list of network interface objects, receiving GPS NMEA sentences
66  */
67 TRxTxNetworkInterface *getRxNetworkInterfaces(void) {
68         return rxNetworkInterfacesListHead;
69 }
70
71 /**
72  Create a receive socket for a network interface
73
74  @param networkInterface
75  The network interface object. This function expects it to be filled with all
76  information, except for the socket descriptor.
77  @param rxSocketHandlerFunction
78  The function that handles reception of data on the network interface
79  @param rxMcAddr
80  The receive multicast address
81
82  @return
83  - the socket descriptor (>= 0)
84  - -1 if an error occurred
85  */
86 static int createRxSocket(TRxTxNetworkInterface * networkInterface,
87                 socket_handler_func rxSocketHandlerFunction, union olsr_sockaddr * rxMcAddr) {
88         int ipFamilySetting;
89         int ipProtoSetting;
90         int ipMcLoopSetting;
91         int ipAddMembershipSetting;
92
93         union olsr_sockaddr address;
94         void * addr;
95         size_t addrSize;
96
97         int rxSocket = -1;
98
99         int socketReuseFlagValue = 1;
100         int mcLoopValue = 1;
101
102         assert(networkInterface != NULL);
103         assert(rxSocketHandlerFunction != NULL);
104         assert(strncmp((char *) &networkInterface->name[0], "",
105                                         sizeof(networkInterface->name)) != 0);
106
107         memset(&address, 0, sizeof(address));
108         if (rxMcAddr->in.sa_family == AF_INET) {
109                 assert(rxMcAddr->in4.sin_addr.s_addr != INADDR_ANY);
110
111                 ipFamilySetting = AF_INET;
112                 ipProtoSetting = IPPROTO_IP;
113                 ipMcLoopSetting = IP_MULTICAST_LOOP;
114                 ipAddMembershipSetting = IP_ADD_MEMBERSHIP;
115
116                 address.in4.sin_family = ipFamilySetting;
117                 address.in4.sin_addr.s_addr = INADDR_ANY;
118                 address.in4.sin_port = getRxMcPort();
119                 addr = &address.in4;
120                 addrSize = sizeof(struct sockaddr_in);
121         } else {
122                 assert(rxMcAddr->in6.sin6_addr.s6_addr != in6addr_any.s6_addr);
123
124                 ipFamilySetting = AF_INET6;
125                 ipProtoSetting = IPPROTO_IPV6;
126                 ipMcLoopSetting = IPV6_MULTICAST_LOOP;
127                 ipAddMembershipSetting = IPV6_ADD_MEMBERSHIP;
128
129                 address.in6.sin6_family = ipFamilySetting;
130                 address.in6.sin6_addr = in6addr_any;
131                 address.in6.sin6_port = getRxMcPort();
132                 addr = &address.in6;
133                 addrSize = sizeof(struct sockaddr_in6);
134         }
135
136         /* Create a datagram socket on which to receive. */
137         errno = 0;
138         rxSocket = socket(ipFamilySetting, SOCK_DGRAM, 0);
139         if (rxSocket < 0) {
140                 pudError(true, "Could not create a receive socket for interface %s",
141                                 networkInterface->name);
142                 goto bail;
143         }
144
145         /* Enable SO_REUSEADDR to allow multiple applications to receive the same
146          * multicast messages */
147         errno = 0;
148         if (setsockopt(rxSocket, SOL_SOCKET, SO_REUSEADDR, &socketReuseFlagValue,
149                         sizeof(socketReuseFlagValue)) < 0) {
150                 pudError(true, "Could not set the reuse flag on the receive socket for"
151                         " interface %s", networkInterface->name);
152                 goto bail;
153         }
154
155         /* Bind to the proper port number with the IP address INADDR_ANY
156          * (INADDR_ANY is really required here, do not change it) */
157         errno = 0;
158         if (bind(rxSocket, addr, addrSize) < 0) {
159                 pudError(true, "Could not bind the receive socket for interface"
160                         " %s to port %u", networkInterface->name, ntohs(getRxMcPort()));
161                 goto bail;
162         }
163
164         /* Enable multicast local loopback */
165         errno = 0;
166         if (setsockopt(rxSocket, ipProtoSetting, ipMcLoopSetting, &mcLoopValue,
167                         sizeof(mcLoopValue)) < 0) {
168                 pudError(true, "Could not %s multicast loopback on the"
169                         " receive socket for interface %s", mcLoopValue ? "enable"
170                                 : "disable", networkInterface->name);
171                 goto bail;
172         }
173
174         /* Join the multicast group on the local interface. Note that this
175          * ADD_MEMBERSHIP option must be called for each local interface over
176          * which the multicast datagrams are to be received. */
177         if (ipFamilySetting == AF_INET) {
178                 struct ip_mreq mc_settings;
179                 struct interface* interface = if_ifwithname((const char *)networkInterface->name);
180
181                 if (!interface) {
182                         pudError(true, "Could not get interface address of %s", networkInterface->name);
183                         goto bail;
184                 }
185
186                 (void) memset(&mc_settings, 0, sizeof(mc_settings));
187                 mc_settings.imr_multiaddr = rxMcAddr->in4.sin_addr;
188                 mc_settings.imr_interface = interface->int_addr.sin_addr;
189                 errno = 0;
190                 if (setsockopt(rxSocket, ipProtoSetting, ipAddMembershipSetting,
191                                 &mc_settings, sizeof(mc_settings)) < 0) {
192                         pudError(true, "Could not subscribe interface %s to the configured"
193                                 " multicast group", networkInterface->name);
194                         goto bail;
195                 }
196         } else {
197                 struct ipv6_mreq mc6_settings;
198                 (void) memset(&mc6_settings, 0, sizeof(mc6_settings));
199                 mc6_settings.ipv6mr_multiaddr = rxMcAddr->in6.sin6_addr;
200                 mc6_settings.ipv6mr_interface = if_nametoindex((char *)networkInterface->name);
201                 errno = 0;
202                 if (setsockopt(rxSocket, ipProtoSetting, ipAddMembershipSetting,
203                                 &mc6_settings, sizeof(mc6_settings)) < 0) {
204                         pudError(true, "Could not subscribe interface %s to the configured"
205                                 " multicast group", networkInterface->name);
206                         goto bail;
207                 }
208         }
209
210         add_olsr_socket(rxSocket, rxSocketHandlerFunction, NULL, networkInterface,
211                         SP_PR_READ);
212
213         return rxSocket;
214
215         bail: if (rxSocket >= 0) {
216                 close(rxSocket);
217         }
218         return -1;
219
220 }
221
222 /**
223  Create a receive interface and add it to the list of receive network interface
224  objects
225
226  @param ifName
227  the network interface name
228  @param rxSocketHandlerFunction
229  the function that handles reception of data on the network interface
230  @param rxMcAddr
231  The receive multicast address
232
233  @return
234  - true on success
235  - false on failure
236  */
237 static bool createRxInterface(const char * ifName,
238                 socket_handler_func rxSocketHandlerFunction, union olsr_sockaddr * rxMcAddr) {
239         int socketFd = -1;
240         TRxTxNetworkInterface * networkInterface = NULL;
241
242         if (ifName == NULL) {
243                 goto bail;
244         }
245
246         networkInterface = olsr_malloc(sizeof(TRxTxNetworkInterface),
247                         "TRxTxNetworkInterface (PUD)");
248         if (networkInterface == NULL) {
249                 goto bail;
250         }
251
252         memcpy(networkInterface->name, ifName, sizeof(networkInterface->name));
253         networkInterface->name[IFNAMSIZ] = '\0';
254         networkInterface->handler = NULL;
255         networkInterface->next = NULL;
256
257         /* networkInterface needs to be filled in when calling createRxSocket */
258         socketFd = createRxSocket(networkInterface, rxSocketHandlerFunction, rxMcAddr);
259         if (socketFd < 0) {
260                 goto bail;
261         }
262         networkInterface->socketFd = socketFd;
263         networkInterface->handler = rxSocketHandlerFunction;
264
265         /* Add new object to the end of the global list. */
266         if (rxNetworkInterfacesListHead == NULL) {
267                 rxNetworkInterfacesListHead = networkInterface;
268                 lastRxNetworkInterface = networkInterface;
269         } else {
270                 lastRxNetworkInterface->next = networkInterface;
271                 lastRxNetworkInterface = networkInterface;
272         }
273
274         return true;
275
276         bail: if (networkInterface != NULL) {
277                 free(networkInterface);
278         }
279         return false;
280
281 }
282
283 /*
284  * TX interfaces
285  */
286
287 /** The list of network interface objects, sending our NMEA sentences */
288 static TRxTxNetworkInterface *txNetworkInterfacesListHead = NULL;
289
290 /** Pointer to the last network interface object, sending our NMEA sentences */
291 static TRxTxNetworkInterface *lastTxNetworkInterface = NULL;
292
293 /**
294  @return
295  The list of network interface objects, sending our NMEA sentences
296  */
297 TRxTxNetworkInterface *getTxNetworkInterfaces(void) {
298         return txNetworkInterfacesListHead;
299 }
300
301 /**
302  Create a transmit socket for a network interface
303
304  @param networkInterface
305  The network interface object. This function expects it to be filled with all
306  information, except for the socket descriptor.
307  @param txMcAddr
308  The transmit multicast address
309
310  @return
311  - the socket descriptor (>= 0)
312  - -1 if an error occurred
313  */
314 static int createTxSocket(TRxTxNetworkInterface * networkInterface, union olsr_sockaddr * txMcAddr) {
315         int ipFamilySetting;
316         int ipProtoSetting;
317         int ipMcLoopSetting;
318         int ipMcIfSetting;
319         int ipTtlSetting;
320         unsigned int ifIndex;
321
322         union olsr_sockaddr address;
323         void * addr;
324         size_t addrSize;
325
326         int txSocket = -1;
327
328         int mcLoopValue = 0;
329         int txTtl = getTxTtl();
330
331         assert(networkInterface != NULL);
332         assert(strncmp((char *) &networkInterface->name[0], "",
333                                         sizeof(networkInterface->name)) != 0);
334
335         memset(&address, 0, sizeof(address));
336         if (txMcAddr->in.sa_family == AF_INET) {
337                 struct interface* interface = if_ifwithname((const char *)networkInterface->name);
338
339                 if (!interface) {
340                         pudError(true, "Could not get interface address of %s", networkInterface->name);
341                         goto bail;
342                 }
343
344                 assert(txMcAddr->in4.sin_addr.s_addr != INADDR_ANY);
345
346                 ipFamilySetting = AF_INET;
347                 ipProtoSetting = IPPROTO_IP;
348                 ipMcLoopSetting = IP_MULTICAST_LOOP;
349                 ipMcIfSetting = IP_MULTICAST_IF;
350                 ipTtlSetting = IP_MULTICAST_TTL;
351                 ifIndex = 0;
352
353                 address.in4.sin_family = ipFamilySetting;
354                 address.in4.sin_addr = interface->int_addr.sin_addr;
355                 address.in4.sin_port = getTxMcPort();
356                 addr = &address.in4;
357                 addrSize = sizeof(struct sockaddr_in);
358         } else {
359                 assert(txMcAddr->in6.sin6_addr.s6_addr != in6addr_any.s6_addr);
360
361                 ipFamilySetting = AF_INET6;
362                 ipProtoSetting = IPPROTO_IPV6;
363                 ipMcLoopSetting = IPV6_MULTICAST_LOOP;
364                 ipMcIfSetting = IPV6_MULTICAST_IF;
365                 ipTtlSetting = IPV6_MULTICAST_HOPS;
366                 ifIndex = if_nametoindex((char *)networkInterface->name);
367
368                 addr = &ifIndex;
369                 addrSize = sizeof(ifIndex);
370         }
371
372         /*  Create a datagram socket on which to transmit */
373         errno = 0;
374         txSocket = socket(ipFamilySetting, SOCK_DGRAM, 0);
375         if (txSocket < 0) {
376                 pudError(true, "Could not create a transmit socket for interface %s",
377                                 networkInterface->name);
378                 goto bail;
379         }
380
381         /* Bind the socket to the desired interface */
382         errno = 0;
383         if (setsockopt(txSocket, ipProtoSetting, ipMcIfSetting, addr, addrSize) < 0) {
384                 pudError(true, "Could not set the multicast interface on the"
385                         " transmit socket to interface %s", networkInterface->name);
386                 goto bail;
387         }
388
389         /* Disable multicast local loopback */
390         errno = 0;
391         if (setsockopt(txSocket, ipProtoSetting, ipMcLoopSetting, &mcLoopValue,
392                         sizeof(mcLoopValue)) < 0) {
393                 pudError(true, "Could not %s multicast loopback on the"
394                         " transmit socket for interface %s", mcLoopValue ? "enable"
395                                 : "disable", networkInterface->name);
396                 goto bail;
397         }
398
399         /* Set the TTL on the socket */
400         errno = 0;
401         if (setsockopt(txSocket, ipProtoSetting, ipTtlSetting, &txTtl,
402                         sizeof(txTtl)) < 0) {
403                 pudError(true, "Could not set TTL on the transmit socket"
404                         " for interface %s", networkInterface->name);
405                 goto bail;
406         }
407
408         /* Set the no delay option on the socket */
409         errno = 0;
410         if (fcntl(txSocket, F_SETFL, O_NDELAY) < 0) {
411                 pudError(true, "Could not set the no delay option on the"
412                         " transmit socket for interface %s", networkInterface->name);
413                 goto bail;
414         }
415
416         return txSocket;
417
418         bail: if (txSocket >= 0) {
419                 close(txSocket);
420         }
421         return -1;
422 }
423
424 /**
425  Create a transmit interface and add it to the list of transmit network
426  interface objects
427
428  @param ifName
429  the network interface name
430  @param txMcAddr
431  the transmit multicast address
432
433  @return
434  - true on success
435  - false on failure
436  */
437 static bool createTxInterface(const char * ifName, union olsr_sockaddr * txMcAddr) {
438         int socketFd = -1;
439         TRxTxNetworkInterface * networkInterface = NULL;
440
441         if (ifName == NULL) {
442                 goto bail;
443         }
444
445         networkInterface = olsr_malloc(sizeof(TRxTxNetworkInterface),
446                         "TRxTxNetworkInterface (PUD)");
447         if (networkInterface == NULL) {
448                 goto bail;
449         }
450
451         memcpy(networkInterface->name, ifName, sizeof(networkInterface->name));
452         networkInterface->name[IFNAMSIZ] = '\0';
453         networkInterface->handler = NULL;
454         networkInterface->next = NULL;
455
456         /* networkInterface needs to be filled in when calling createTxSocket */
457         socketFd = createTxSocket(networkInterface, txMcAddr);
458         if (socketFd < 0) {
459                 goto bail;
460         }
461         networkInterface->socketFd = socketFd;
462
463         /* Add new object to the end of the global list. */
464         if (txNetworkInterfacesListHead == NULL) {
465                 txNetworkInterfacesListHead = networkInterface;
466                 lastTxNetworkInterface = networkInterface;
467         } else {
468                 lastTxNetworkInterface->next = networkInterface;
469                 lastTxNetworkInterface = networkInterface;
470         }
471
472         return true;
473
474         bail: if (networkInterface != NULL) {
475                 free(networkInterface);
476         }
477         return false;
478 }
479
480 /*
481  * Downlink interface
482  */
483
484 /** The socket fd, receiving downlinked messages */
485 static int downlinkSocketFd = -1;
486
487 /** the downlink handler function */
488 static socket_handler_func downlinkHandler = NULL;
489
490
491 /**
492  @return
493  The downlink socket fd. -1 when not valid.
494  */
495 int getDownlinkSocketFd(void) {
496         return downlinkSocketFd;
497 }
498
499 /**
500  Create an downlink socket
501
502  @param ipVersion
503  The IP version (AF_INET or AF_INET6) for the socket
504  @param rxSocketHandlerFunction
505  The socket handler function
506
507  @return
508  - the socket descriptor (>= 0)
509  - -1 if an error occurred
510  */
511 static int createDownlinkSocket(int ipVersion, socket_handler_func rxSocketHandlerFunction) {
512         union olsr_sockaddr address;
513         void * addr;
514         size_t addrSize;
515
516         int downlinkSocket = -1;
517
518         int socketReuseFlagValue = 1;
519
520         memset(&address, 0, sizeof(address));
521         if (ipVersion == AF_INET) {
522                 address.in4.sin_family = AF_INET;
523                 address.in4.sin_addr.s_addr = INADDR_ANY;
524                 address.in4.sin_port = getDownlinkPort();
525                 addr = &address.in4;
526                 addrSize = sizeof(struct sockaddr_in);
527         } else {
528                 address.in6.sin6_family = AF_INET6;
529                 address.in6.sin6_addr = in6addr_any;
530                 address.in6.sin6_port = getDownlinkPort();
531                 addr = &address.in6;
532                 addrSize = sizeof(struct sockaddr_in6);
533         }
534
535         /*  Create a datagram socket on which to receive */
536         errno = 0;
537         downlinkSocket = socket(ipVersion, SOCK_DGRAM, 0);
538         if (downlinkSocket < 0) {
539                 pudError(true, "Could not create the downlink socket");
540                 goto bail;
541         }
542
543         /* Enable SO_REUSEADDR to allow multiple applications to receive the same
544          * messages */
545         errno = 0;
546         if (setsockopt(downlinkSocket, SOL_SOCKET, SO_REUSEADDR, &socketReuseFlagValue,
547                         sizeof(socketReuseFlagValue)) < 0) {
548                 pudError(true, "Could not set REUSE option on the downlink socket");
549                 goto bail;
550         }
551
552         /* Bind to the proper port number with the IP address INADDR_ANY
553          * (INADDR_ANY is really required here, do not change it) */
554         errno = 0;
555         if (bind(downlinkSocket, addr, addrSize)) {
556                 pudError(true, "Could not bind downlink socket to port %d",
557                                 getDownlinkPort());
558                 goto bail;
559         }
560
561         add_olsr_socket(downlinkSocket, rxSocketHandlerFunction, NULL, NULL,
562                         SP_PR_READ);
563
564         downlinkHandler = rxSocketHandlerFunction;
565
566         return downlinkSocket;
567
568         bail: if (downlinkSocket >= 0) {
569                 close(downlinkSocket);
570         }
571         return -1;
572 }
573
574 /*
575  * Interface Functions
576  */
577
578 /**
579  Creates receive and transmit sockets and register the receive sockets with
580  the OLSR stack
581
582  @param rxSocketHandlerFunction
583  The function to call upon reception of data on a receive socket
584  @param rxSocketHandlerFunctionDownlink
585  The function to call upon reception of data on a downlink receive socket
586
587  @return
588  - true on success
589  - false on failure
590  */
591 bool createNetworkInterfaces(socket_handler_func rxSocketHandlerFunction,
592                 socket_handler_func rxSocketHandlerFunctionDownlink) {
593         int retval = false;
594         struct ifaddrs *ifAddrs = NULL;
595         struct ifaddrs *ifAddr = NULL;
596         union olsr_sockaddr * rxMcAddr = getRxMcAddr();
597         union olsr_sockaddr * txMcAddr = getTxMcAddr();
598
599         errno = 0;
600         if (getifaddrs(&ifAddrs) != 0) {
601                 pudError(true, "Could not get list of interfaces and their addresses");
602                 return retval;
603         }
604
605         /* loop over all interfaces */
606         for (ifAddr = ifAddrs; ifAddr != NULL; ifAddr = ifAddr->ifa_next) {
607                 union olsr_sockaddr * addr = (union olsr_sockaddr *)ifAddr->ifa_addr;
608                 if ((addr != NULL) && ((addr->in.sa_family == AF_INET) || (addr->in.sa_family == AF_INET6))) {
609                         char * ifName = ifAddr->ifa_name;
610
611                         /* determine whether the iterated interface is configured as a
612                          * non-OLSR interface in the plugin parameter list */
613                         bool isRxNonOlsrIf = isRxNonOlsrInterface(ifName) && (addr->in.sa_family == rxMcAddr->in.sa_family);
614                         bool isTxNonOlsrIf = isTxNonOlsrInterface(ifName) && (addr->in.sa_family == txMcAddr->in.sa_family);
615
616                         bool isNonOlsrIf = isRxNonOlsrIf || isTxNonOlsrIf;
617
618                         if (!isNonOlsrIf) {
619                                 /* interface is not configured as non-OLSR interface: skip */
620                                 continue;
621                         }
622
623                         if (isRxNonOlsrIf && !createRxInterface(ifName, rxSocketHandlerFunction, rxMcAddr)) {
624                                 /* creating a receive interface failed */
625                                 goto end;
626                         }
627
628                         if (isTxNonOlsrIf && !createTxInterface(ifName, txMcAddr)) {
629                                 /* creating a transmit interface failed */
630                                 goto end;
631                         }
632                 }
633         }
634
635         if (isUplinkAddrSet()) {
636                 downlinkSocketFd = createDownlinkSocket(getUplinkAddr()->in.sa_family, rxSocketHandlerFunctionDownlink);
637                 if (downlinkSocketFd == -1) {
638                         goto end;
639                 }
640         } else {
641                 downlinkSocketFd = -1;
642         }
643
644         retval = true;
645
646         end: freeifaddrs(ifAddrs);
647         return retval;
648 }
649
650 /**
651  Close and cleanup the network interfaces in the given list
652
653  @param networkInterface
654  the list of network interface to close and clean up
655  */
656 static void closeInterfaces(TRxTxNetworkInterface * networkInterface) {
657         TRxTxNetworkInterface * nextNetworkInterface = networkInterface;
658         while (nextNetworkInterface != NULL) {
659                 TRxTxNetworkInterface * iteratedNetworkInterface = nextNetworkInterface;
660                 if (iteratedNetworkInterface->socketFd >= 0) {
661                         if (iteratedNetworkInterface->handler) {
662                                 remove_olsr_socket(iteratedNetworkInterface->socketFd,
663                                                 iteratedNetworkInterface->handler, NULL);
664                         }
665                         close(iteratedNetworkInterface->socketFd);
666                         iteratedNetworkInterface->socketFd = -1;
667                 }
668                 nextNetworkInterface = iteratedNetworkInterface->next;
669                 iteratedNetworkInterface->next = NULL;
670                 free(iteratedNetworkInterface);
671         }
672 }
673
674 /**
675  Close and cleanup all receive and transmit network interfaces
676  */
677 void closeNetworkInterfaces(void) {
678         if (rxNetworkInterfacesListHead != NULL) {
679                 closeInterfaces(rxNetworkInterfacesListHead);
680                 rxNetworkInterfacesListHead = NULL;
681         }
682
683         if (txNetworkInterfacesListHead != NULL) {
684                 closeInterfaces(txNetworkInterfacesListHead);
685                 txNetworkInterfacesListHead = NULL;
686         }
687
688         if (downlinkSocketFd != -1 ) {
689                 if (downlinkHandler) {
690                         remove_olsr_socket (downlinkSocketFd, downlinkHandler, NULL);
691                         downlinkHandler = NULL;
692                 }
693                 close(downlinkSocketFd);
694                 downlinkSocketFd = -1;
695         }
696 }