Properly set HMAC length for incoming packets.
[tinc] / src / net_socket.c
1 /*
2     net_socket.c -- Handle various kinds of sockets.
3     Copyright (C) 1998-2005 Ivo Timmermans,
4                   2000-2009 Guus Sliepen <guus@tinc-vpn.org>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20     $Id$
21 */
22
23 #include "system.h"
24
25 #include "avl_tree.h"
26 #include "conf.h"
27 #include "connection.h"
28 #include "event.h"
29 #include "logger.h"
30 #include "meta.h"
31 #include "net.h"
32 #include "netutl.h"
33 #include "protocol.h"
34 #include "utils.h"
35 #include "xalloc.h"
36
37 #include <assert.h>
38
39 #ifdef WSAEINPROGRESS
40 #define EINPROGRESS WSAEINPROGRESS
41 #endif
42
43 /* Needed on Mac OS/X */
44 #ifndef SOL_TCP
45 #define SOL_TCP IPPROTO_TCP
46 #endif
47
48 int addressfamily = AF_UNSPEC;
49 int maxtimeout = 900;
50 int seconds_till_retry = 5;
51
52 listen_socket_t listen_socket[MAXSOCKETS];
53 int listen_sockets;
54 list_t *outgoing_list = NULL;
55
56 /* Setup sockets */
57
58 static void configure_tcp(connection_t *c)
59 {
60         int option;
61
62 #ifdef O_NONBLOCK
63         int flags = fcntl(c->socket, F_GETFL);
64
65         if(fcntl(c->socket, F_SETFL, flags | O_NONBLOCK) < 0) {
66                 logger(LOG_ERR, _("fcntl for %s: %s"), c->hostname, strerror(errno));
67         }
68 #elif defined(WIN32)
69         unsigned long arg = 1;
70
71         if(ioctlsocket(c->socket, FIONBIO, &arg) != 0) {
72                 logger(LOG_ERR, _("ioctlsocket for %s: WSA error %d"), c->hostname, WSAGetLastError());
73         }
74 #endif
75
76 #if defined(SOL_TCP) && defined(TCP_NODELAY)
77         option = 1;
78         setsockopt(c->socket, SOL_TCP, TCP_NODELAY, &option, sizeof(option));
79 #endif
80
81 #if defined(SOL_IP) && defined(IP_TOS) && defined(IPTOS_LOWDELAY)
82         option = IPTOS_LOWDELAY;
83         setsockopt(c->socket, SOL_IP, IP_TOS, &option, sizeof(option));
84 #endif
85 }
86
87 static bool bind_to_interface(int sd) { /* {{{ */
88         char *iface;
89
90 #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
91         struct ifreq ifr;
92         int status;
93 #endif /* defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) */
94
95         if(!get_config_string (lookup_config (config_tree, "BindToInterface"), &iface))
96                 return true;
97
98 #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
99         memset(&ifr, 0, sizeof(ifr));
100         strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
101         ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0;
102
103         status = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr));
104         if(status) {
105                 logger(LOG_ERR, _("Can't bind to interface %s: %s"), iface,
106                                 strerror(errno));
107                 return false;
108         }
109 #else /* if !defined(SOL_SOCKET) || !defined(SO_BINDTODEVICE) */
110         logger(LOG_WARNING, _("%s not supported on this platform"), "BindToInterface");
111 #endif
112
113         return true;
114 } /* }}} bool bind_to_interface */
115
116 static bool bind_to_address(connection_t *c) { /* {{{ */
117         char *node;
118         struct addrinfo *ai_list;
119         struct addrinfo *ai_ptr;
120         struct addrinfo ai_hints;
121         int status;
122
123         assert(c != NULL);
124         assert(c->socket >= 0);
125
126         node = NULL;
127         if(!get_config_string(lookup_config(config_tree, "BindToAddress"),
128                                 &node))
129                 return true;
130
131         assert(node != NULL);
132
133         memset(&ai_hints, 0, sizeof(ai_hints));
134         ai_hints.ai_family = c->address.sa.sa_family;
135         /* We're called from `do_outgoing_connection' only. */
136         ai_hints.ai_socktype = SOCK_STREAM;
137         ai_hints.ai_protocol = IPPROTO_TCP;
138
139         ai_list = NULL;
140
141         status = getaddrinfo(node, /* service = */ NULL,
142                         &ai_hints, &ai_list);
143         if(status) {
144                 free(node);
145                 logger(LOG_WARNING, _("Error looking up %s port %s: %s"),
146                                 node, _("any"), gai_strerror(status));
147                 return false;
148         }
149         assert(ai_list != NULL);
150
151         status = -1;
152         for(ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) {
153                 status = bind(c->socket,
154                                 ai_list->ai_addr, ai_list->ai_addrlen);
155                 if(!status)
156                         break;
157         }
158
159
160         if(status) {
161                 logger(LOG_ERR, _("Can't bind to %s/tcp: %s"), node,
162                                 strerror(errno));
163         } else ifdebug(CONNECTIONS) {
164                 logger(LOG_DEBUG, "Successfully bound outgoing "
165                                 "TCP socket to %s", node);
166         }
167
168         free(node);
169         freeaddrinfo(ai_list);
170
171         return status ? false : true;
172 } /* }}} bool bind_to_address */
173
174 int setup_listen_socket(const sockaddr_t *sa)
175 {
176         int nfd;
177         char *addrstr;
178         int option;
179         char *iface;
180
181         cp();
182
183         nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
184
185         if(nfd < 0) {
186                 ifdebug(STATUS) logger(LOG_ERR, _("Creating metasocket failed: %s"), strerror(errno));
187                 return -1;
188         }
189
190         /* Optimize TCP settings */
191
192         option = 1;
193         setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
194
195 #if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
196         if(sa->sa.sa_family == AF_INET6)
197                 setsockopt(nfd, SOL_IPV6, IPV6_V6ONLY, &option, sizeof option);
198 #endif
199
200         if(get_config_string
201            (lookup_config(config_tree, "BindToInterface"), &iface)) {
202 #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
203                 struct ifreq ifr;
204
205                 memset(&ifr, 0, sizeof(ifr));
206                 strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
207
208                 if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr))) {
209                         closesocket(nfd);
210                         logger(LOG_ERR, _("Can't bind to interface %s: %s"), iface,
211                                    strerror(errno));
212                         return -1;
213                 }
214 #else
215                 logger(LOG_WARNING, _("%s not supported on this platform"), "BindToInterface");
216 #endif
217         }
218
219         if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
220                 closesocket(nfd);
221                 addrstr = sockaddr2hostname(sa);
222                 logger(LOG_ERR, _("Can't bind to %s/tcp: %s"), addrstr,
223                            strerror(errno));
224                 free(addrstr);
225                 return -1;
226         }
227
228         if(listen(nfd, 3)) {
229                 closesocket(nfd);
230                 logger(LOG_ERR, _("System call `%s' failed: %s"), "listen",
231                            strerror(errno));
232                 return -1;
233         }
234
235         return nfd;
236 }
237
238 int setup_vpn_in_socket(const sockaddr_t *sa)
239 {
240         int nfd;
241         char *addrstr;
242         int option;
243
244         cp();
245
246         nfd = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP);
247
248         if(nfd < 0) {
249                 logger(LOG_ERR, _("Creating UDP socket failed: %s"), strerror(errno));
250                 return -1;
251         }
252
253 #ifdef O_NONBLOCK
254         {
255                 int flags = fcntl(nfd, F_GETFL);
256
257                 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
258                         closesocket(nfd);
259                         logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
260                                    strerror(errno));
261                         return -1;
262                 }
263         }
264 #elif defined(WIN32)
265         {
266                 unsigned long arg = 1;
267                 if(ioctlsocket(nfd, FIONBIO, &arg) != 0) {
268                         closesocket(nfd);
269                         logger(LOG_ERR, _("Call to `%s' failed: WSA error %d"), "ioctlsocket",
270                                 WSAGetLastError());
271                         return -1;
272                 }
273         }
274 #endif
275
276         option = 1;
277         setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
278
279 #if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
280         if(sa->sa.sa_family == AF_INET6)
281                 setsockopt(nfd, SOL_IPV6, IPV6_V6ONLY, &option, sizeof option);
282 #endif
283
284 #if defined(SOL_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
285         if(myself->options & OPTION_PMTU_DISCOVERY) {
286                 option = IP_PMTUDISC_DO;
287                 setsockopt(nfd, SOL_IP, IP_MTU_DISCOVER, &option, sizeof(option));
288         }
289 #endif
290
291 #if defined(SOL_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
292         if(myself->options & OPTION_PMTU_DISCOVERY) {
293                 option = IPV6_PMTUDISC_DO;
294                 setsockopt(nfd, SOL_IPV6, IPV6_MTU_DISCOVER, &option, sizeof(option));
295         }
296 #endif
297
298         if (!bind_to_interface(nfd)) {
299                 closesocket(nfd);
300                 return -1;
301         }
302
303         if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
304                 closesocket(nfd);
305                 addrstr = sockaddr2hostname(sa);
306                 logger(LOG_ERR, _("Can't bind to %s/udp: %s"), addrstr,
307                            strerror(errno));
308                 free(addrstr);
309                 return -1;
310         }
311
312         return nfd;
313 } /* int setup_vpn_in_socket */
314
315 void retry_outgoing(outgoing_t *outgoing)
316 {
317         event_t *event;
318
319         cp();
320
321         outgoing->timeout += 5;
322
323         if(outgoing->timeout > maxtimeout)
324                 outgoing->timeout = maxtimeout;
325
326         event = new_event();
327         event->handler = (event_handler_t) setup_outgoing_connection;
328         event->time = now + outgoing->timeout;
329         event->data = outgoing;
330         event_add(event);
331
332         ifdebug(CONNECTIONS) logger(LOG_NOTICE,
333                            _("Trying to re-establish outgoing connection in %d seconds"),
334                            outgoing->timeout);
335 }
336
337 void finish_connecting(connection_t *c)
338 {
339         cp();
340
341         ifdebug(CONNECTIONS) logger(LOG_INFO, _("Connected to %s (%s)"), c->name, c->hostname);
342
343         configure_tcp(c);
344
345         c->last_ping_time = now;
346
347         send_id(c);
348 }
349
350 void do_outgoing_connection(connection_t *c)
351 {
352         char *address, *port;
353         int result;
354
355         cp();
356
357 begin:
358         if(!c->outgoing->ai) {
359                 if(!c->outgoing->cfg) {
360                         ifdebug(CONNECTIONS) logger(LOG_ERR, _("Could not set up a meta connection to %s"),
361                                            c->name);
362                         c->status.remove = true;
363                         retry_outgoing(c->outgoing);
364                         return;
365                 }
366
367                 get_config_string(c->outgoing->cfg, &address);
368
369                 if(!get_config_string(lookup_config(c->config_tree, "Port"), &port))
370                         asprintf(&port, "655");
371
372                 c->outgoing->ai = str2addrinfo(address, port, SOCK_STREAM);
373                 free(address);
374                 free(port);
375
376                 c->outgoing->aip = c->outgoing->ai;
377                 c->outgoing->cfg = lookup_config_next(c->config_tree, c->outgoing->cfg);
378         }
379
380         if(!c->outgoing->aip) {
381                 if(c->outgoing->ai)
382                         freeaddrinfo(c->outgoing->ai);
383                 c->outgoing->ai = NULL;
384                 goto begin;
385         }
386
387         memcpy(&c->address, c->outgoing->aip->ai_addr, c->outgoing->aip->ai_addrlen);
388         c->outgoing->aip = c->outgoing->aip->ai_next;
389
390         if(c->hostname)
391                 free(c->hostname);
392
393         c->hostname = sockaddr2hostname(&c->address);
394
395         ifdebug(CONNECTIONS) logger(LOG_INFO, _("Trying to connect to %s (%s)"), c->name,
396                            c->hostname);
397
398         c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
399
400         if(c->socket == -1) {
401                 ifdebug(CONNECTIONS) logger(LOG_ERR, _("Creating socket for %s failed: %s"), c->hostname,
402                                    strerror(errno));
403
404                 goto begin;
405         }
406
407 #if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
408         int option = 1;
409         if(c->address.sa.sa_family == AF_INET6)
410                 setsockopt(c->socket, SOL_IPV6, IPV6_V6ONLY, &option, sizeof option);
411 #endif
412
413         bind_to_interface(c->socket);
414         bind_to_address(c);
415
416         /* Optimize TCP settings */
417
418         configure_tcp(c);
419
420         /* Connect */
421
422         result = connect(c->socket, &c->address.sa, SALEN(c->address.sa));
423
424         if(result == -1) {
425                 if(errno == EINPROGRESS
426 #if defined(WIN32) && !defined(O_NONBLOCK)
427                    || WSAGetLastError() == WSAEWOULDBLOCK
428 #endif
429                 ) {
430                         c->status.connecting = true;
431                         return;
432                 }
433
434                 closesocket(c->socket);
435
436                 ifdebug(CONNECTIONS) logger(LOG_ERR, _("%s: %s"), c->hostname, strerror(errno));
437
438                 goto begin;
439         }
440
441         finish_connecting(c);
442
443         return;
444 }
445
446 void setup_outgoing_connection(outgoing_t *outgoing)
447 {
448         connection_t *c;
449         node_t *n;
450
451         cp();
452
453         n = lookup_node(outgoing->name);
454
455         if(n)
456                 if(n->connection) {
457                         ifdebug(CONNECTIONS) logger(LOG_INFO, _("Already connected to %s"), outgoing->name);
458
459                         n->connection->outgoing = outgoing;
460                         return;
461                 }
462
463         c = new_connection();
464         c->name = xstrdup(outgoing->name);
465         c->outcipher = myself->connection->outcipher;
466         c->outdigest = myself->connection->outdigest;
467         c->outmaclength = myself->connection->outmaclength;
468         c->outcompression = myself->connection->outcompression;
469
470         init_configuration(&c->config_tree);
471         read_connection_config(c);
472
473         outgoing->cfg = lookup_config(c->config_tree, "Address");
474
475         if(!outgoing->cfg) {
476                 logger(LOG_ERR, _("No address specified for %s"), c->name);
477                 free_connection(c);
478                 return;
479         }
480
481         c->outgoing = outgoing;
482         c->last_ping_time = now;
483
484         connection_add(c);
485
486         do_outgoing_connection(c);
487 }
488
489 /*
490   accept a new tcp connect and create a
491   new connection
492 */
493 bool handle_new_meta_connection(int sock)
494 {
495         connection_t *c;
496         sockaddr_t sa;
497         int fd;
498         socklen_t len = sizeof(sa);
499
500         cp();
501
502         fd = accept(sock, &sa.sa, &len);
503
504         if(fd < 0) {
505                 logger(LOG_ERR, _("Accepting a new connection failed: %s"),
506                            strerror(errno));
507                 return false;
508         }
509
510         sockaddrunmap(&sa);
511
512         c = new_connection();
513         c->name = xstrdup("<unknown>");
514         c->outcipher = myself->connection->outcipher;
515         c->outdigest = myself->connection->outdigest;
516         c->outmaclength = myself->connection->outmaclength;
517         c->outcompression = myself->connection->outcompression;
518
519         c->address = sa;
520         c->hostname = sockaddr2hostname(&sa);
521         c->socket = fd;
522         c->last_ping_time = now;
523
524         ifdebug(CONNECTIONS) logger(LOG_NOTICE, _("Connection from %s"), c->hostname);
525
526         configure_tcp(c);
527
528         connection_add(c);
529
530         c->allow_request = ID;
531         send_id(c);
532
533         return true;
534 }
535
536 void free_outgoing(outgoing_t *outgoing) {
537         if(outgoing->ai)
538                 freeaddrinfo(outgoing->ai);
539
540         if(outgoing->name)
541                 free(outgoing->name);
542
543         free(outgoing);
544 }
545
546 void try_outgoing_connections(void)
547 {
548         static config_t *cfg = NULL;
549         char *name;
550         outgoing_t *outgoing;
551         connection_t *c;
552         avl_node_t *node;
553         
554         cp();
555
556         if(outgoing_list) {
557                 for(node = connection_tree->head; node; node = node->next) {
558                         c = node->data;
559                         c->outgoing = NULL;
560                 }
561
562                 list_delete_list(outgoing_list);
563         }
564
565         outgoing_list = list_alloc((list_action_t)free_outgoing);
566                         
567         for(cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg)) {
568                 get_config_string(cfg, &name);
569
570                 if(!check_id(name)) {
571                         logger(LOG_ERR,
572                                    _("Invalid name for outgoing connection in %s line %d"),
573                                    cfg->file, cfg->line);
574                         free(name);
575                         continue;
576                 }
577
578                 outgoing = xmalloc_and_zero(sizeof(*outgoing));
579                 outgoing->name = name;
580                 list_insert_tail(outgoing_list, outgoing);
581                 setup_outgoing_connection(outgoing);
582         }
583 }