Merge branch 'master' into 1.1
[tinc] / src / net_packet.c
1 /*
2     net_packet.c -- Handles in- and outgoing VPN packets
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 along
17     with this program; if not, write to the Free Software Foundation, Inc.,
18     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "system.h"
22
23 #include <zlib.h>
24 #include LZO1X_H
25
26 #include "splay_tree.h"
27 #include "cipher.h"
28 #include "conf.h"
29 #include "connection.h"
30 #include "crypto.h"
31 #include "digest.h"
32 #include "device.h"
33 #include "ethernet.h"
34 #include "graph.h"
35 #include "list.h"
36 #include "logger.h"
37 #include "net.h"
38 #include "netutl.h"
39 #include "protocol.h"
40 #include "process.h"
41 #include "route.h"
42 #include "utils.h"
43 #include "xalloc.h"
44
45 #ifdef WSAEMSGSIZE
46 #define EMSGSIZE WSAEMSGSIZE
47 #endif
48
49 int keylifetime = 0;
50 int keyexpires = 0;
51 static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999_MEM_COMPRESS : LZO1X_1_MEM_COMPRESS];
52
53 static void send_udppacket(node_t *, vpn_packet_t *);
54
55 #define MAX_SEQNO 1073741824
56
57 static void send_mtu_probe_handler(int fd, short events, void *data) {
58         node_t *n = data;
59         vpn_packet_t packet;
60         int len, i;
61         
62         n->mtuprobes++;
63
64         if(!n->status.reachable) {
65                 logger(LOG_DEBUG, "Trying to send MTU probe to unreachable node %s (%s)", n->name, n->hostname);
66                 return;
67         }
68
69         if(n->mtuprobes >= 10 && !n->minmtu) {
70                 ifdebug(TRAFFIC) logger(LOG_INFO, "No response to MTU probes from %s (%s)", n->name, n->hostname);
71                 return;
72         }
73
74         for(i = 0; i < 3; i++) {
75                 if(n->mtuprobes >= 30 || n->minmtu >= n->maxmtu) {
76                         n->mtu = n->minmtu;
77                         ifdebug(TRAFFIC) logger(LOG_INFO, "Fixing MTU of %s (%s) to %d after %d probes", n->name, n->hostname, n->mtu, n->mtuprobes);
78                         return;
79                 }
80
81                 len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
82                 if(len < 64)
83                         len = 64;
84                 
85                 memset(packet.data, 0, 14);
86                 randomize(packet.data + 14, len - 14);
87                 packet.len = len;
88                 packet.priority = 0;
89
90                 ifdebug(TRAFFIC) logger(LOG_INFO, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname);
91
92                 send_udppacket(n, &packet);
93         }
94
95         event_add(&n->mtuevent, &(struct timeval){1, 0});
96 }
97
98 void send_mtu_probe(node_t *n) {
99         if(!timeout_initialized(&n->mtuevent))
100                 timeout_set(&n->mtuevent, send_mtu_probe_handler, n);
101         send_mtu_probe_handler(0, 0, n);
102 }
103
104 void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
105         ifdebug(TRAFFIC) logger(LOG_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname);
106
107         if(!packet->data[0]) {
108                 packet->data[0] = 1;
109                 send_packet(n, packet);
110         } else {
111                 if(n->minmtu < len)
112                         n->minmtu = len;
113         }
114 }
115
116 static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level) {
117         if(level == 10) {
118                 lzo_uint lzolen = MAXSIZE;
119                 lzo1x_1_compress(source, len, dest, &lzolen, lzo_wrkmem);
120                 return lzolen;
121         } else if(level < 10) {
122                 unsigned long destlen = MAXSIZE;
123                 if(compress2(dest, &destlen, source, len, level) == Z_OK)
124                         return destlen;
125                 else
126                         return -1;
127         } else {
128                 lzo_uint lzolen = MAXSIZE;
129                 lzo1x_999_compress(source, len, dest, &lzolen, lzo_wrkmem);
130                 return lzolen;
131         }
132         
133         return -1;
134 }
135
136 static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level) {
137         if(level > 9) {
138                 lzo_uint lzolen = MAXSIZE;
139                 if(lzo1x_decompress_safe(source, len, dest, &lzolen, NULL) == LZO_E_OK)
140                         return lzolen;
141                 else
142                         return -1;
143         } else {
144                 unsigned long destlen = MAXSIZE;
145                 if(uncompress(dest, &destlen, source, len) == Z_OK)
146                         return destlen;
147                 else
148                         return -1;
149         }
150         
151         return -1;
152 }
153
154 /* VPN packet I/O */
155
156 static void receive_packet(node_t *n, vpn_packet_t *packet) {
157         ifdebug(TRAFFIC) logger(LOG_DEBUG, "Received packet of %d bytes from %s (%s)",
158                            packet->len, n->name, n->hostname);
159
160         route(n, packet);
161 }
162
163 static bool try_mac(node_t *n, const vpn_packet_t *inpkt) {
164         if(!digest_active(&n->indigest) || inpkt->len < sizeof inpkt->seqno + digest_length(&n->indigest))
165                 return false;
166
167         return digest_verify(&n->indigest, &inpkt->seqno, inpkt->len, (const char *)&inpkt->seqno + inpkt->len);
168 }
169
170 static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
171         vpn_packet_t pkt1, pkt2;
172         vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
173         int nextpkt = 0;
174         vpn_packet_t *outpkt = pkt[0];
175         size_t outlen;
176         int i;
177
178         if(!cipher_active(&n->incipher)) {
179                 ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet",
180                                         n->name, n->hostname);
181                 return;
182         }
183
184         /* Check packet length */
185
186         if(inpkt->len < sizeof inpkt->seqno + digest_length(&n->indigest)) {
187                 ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got too short packet from %s (%s)",
188                                         n->name, n->hostname);
189                 return;
190         }
191
192         /* Check the message authentication code */
193
194         if(digest_active(&n->indigest) && !digest_verify(&n->indigest, &inpkt->seqno, inpkt->len, (const char *)&inpkt->seqno + inpkt->len)) {
195                 ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got unauthenticated packet from %s (%s)", n->name, n->hostname);
196                 return;
197         }
198
199         /* Decrypt the packet */
200
201         if(cipher_active(&n->incipher)) {
202                 outpkt = pkt[nextpkt++];
203                 outlen = MAXSIZE;
204
205                 if(!cipher_decrypt(&n->incipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) {
206                         ifdebug(TRAFFIC) logger(LOG_DEBUG, "Error decrypting packet from %s (%s)", n->name, n->hostname);
207                         return;
208                 }
209                 
210                 outpkt->len = outlen;
211                 inpkt = outpkt;
212         }
213
214         /* Check the sequence number */
215
216         inpkt->len -= sizeof inpkt->seqno;
217         inpkt->seqno = ntohl(inpkt->seqno);
218
219         if(inpkt->seqno != n->received_seqno + 1) {
220                 if(inpkt->seqno >= n->received_seqno + sizeof n->late * 8) {
221                         logger(LOG_WARNING, "Lost %d packets from %s (%s)",
222                                            inpkt->seqno - n->received_seqno - 1, n->name, n->hostname);
223                         
224                         memset(n->late, 0, sizeof n->late);
225                 } else if (inpkt->seqno <= n->received_seqno) {
226                         if((n->received_seqno >= sizeof n->late * 8 && inpkt->seqno <= n->received_seqno - sizeof n->late * 8) || !(n->late[(inpkt->seqno / 8) % sizeof n->late] & (1 << inpkt->seqno % 8))) {
227                                 logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d",
228                                            n->name, n->hostname, inpkt->seqno, n->received_seqno);
229                                 return;
230                         }
231                 } else {
232                         for(i = n->received_seqno + 1; i < inpkt->seqno; i++)
233                                 n->late[(i / 8) % sizeof n->late] |= 1 << i % 8;
234                 }
235         }
236         
237         n->late[(inpkt->seqno / 8) % sizeof n->late] &= ~(1 << inpkt->seqno % 8);
238
239         if(inpkt->seqno > n->received_seqno)
240                 n->received_seqno = inpkt->seqno;
241                         
242         if(n->received_seqno > MAX_SEQNO)
243                 regenerate_key();
244
245         /* Decompress the packet */
246
247         length_t origlen = inpkt->len;
248
249         if(n->incompression) {
250                 outpkt = pkt[nextpkt++];
251
252                 if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, n->incompression)) < 0) {
253                         ifdebug(TRAFFIC) logger(LOG_ERR, "Error while uncompressing packet from %s (%s)",
254                                                  n->name, n->hostname);
255                         return;
256                 }
257
258                 inpkt = outpkt;
259
260                 origlen -= MTU/64 + 20;
261         }
262
263         inpkt->priority = 0;
264
265         if(!inpkt->data[12] && !inpkt->data[13])
266                 mtu_probe_h(n, inpkt, origlen);
267         else
268                 receive_packet(n, inpkt);
269 }
270
271 void receive_tcppacket(connection_t *c, char *buffer, int len) {
272         vpn_packet_t outpkt;
273
274         outpkt.len = len;
275         if(c->options & OPTION_TCPONLY)
276                 outpkt.priority = 0;
277         else
278                 outpkt.priority = -1;
279         memcpy(outpkt.data, buffer, len);
280
281         receive_packet(c->node, &outpkt);
282 }
283
284 static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
285         vpn_packet_t pkt1, pkt2;
286         vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
287         vpn_packet_t *inpkt = origpkt;
288         int nextpkt = 0;
289         vpn_packet_t *outpkt;
290         int origlen;
291         size_t outlen;
292         static int priority = 0;
293         int origpriority;
294         int sock;
295
296         if(!n->status.reachable) {
297                 ifdebug(TRAFFIC) logger(LOG_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname);
298                 return;
299         }
300
301         /* Make sure we have a valid key */
302
303         if(!n->status.validkey) {
304                 ifdebug(TRAFFIC) logger(LOG_INFO,
305                                    "No valid key known yet for %s (%s), forwarding via TCP",
306                                    n->name, n->hostname);
307
308                 if(!n->status.waitingforkey)
309                         send_req_key(n);
310
311                 n->status.waitingforkey = true;
312
313                 send_tcppacket(n->nexthop->connection, origpkt);
314
315                 return;
316         }
317
318         if(n->options & OPTION_PMTU_DISCOVERY && inpkt->len > n->minmtu && (inpkt->data[12] | inpkt->data[13])) {
319                 ifdebug(TRAFFIC) logger(LOG_INFO,
320                                 "Packet for %s (%s) larger than minimum MTU, forwarding via TCP",
321                                 n->name, n->hostname);
322
323                 send_tcppacket(n->nexthop->connection, origpkt);
324
325                 return;
326         }
327
328         origlen = inpkt->len;
329         origpriority = inpkt->priority;
330
331         /* Compress the packet */
332
333         if(n->outcompression) {
334                 outpkt = pkt[nextpkt++];
335
336                 if((outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->outcompression)) < 0) {
337                         ifdebug(TRAFFIC) logger(LOG_ERR, "Error while compressing packet to %s (%s)",
338                                    n->name, n->hostname);
339                         return;
340                 }
341
342                 inpkt = outpkt;
343         }
344
345         /* Add sequence number */
346
347         inpkt->seqno = htonl(++(n->sent_seqno));
348         inpkt->len += sizeof inpkt->seqno;
349
350         /* Encrypt the packet */
351
352         if(cipher_active(&n->outcipher)) {
353                 outpkt = pkt[nextpkt++];
354                 outlen = MAXSIZE;
355
356                 if(!cipher_encrypt(&n->outcipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) {
357                         ifdebug(TRAFFIC) logger(LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname);
358                         goto end;
359                 }
360
361                 outpkt->len = outlen;
362                 inpkt = outpkt;
363         }
364
365         /* Add the message authentication code */
366
367         if(digest_active(&n->outdigest)) {
368                 digest_create(&n->outdigest, &inpkt->seqno, inpkt->len, (char *)&inpkt->seqno + inpkt->len);
369                 inpkt->len += digest_length(&n->outdigest);
370         }
371
372         /* Determine which socket we have to use */
373
374         for(sock = 0; sock < listen_sockets; sock++)
375                 if(n->address.sa.sa_family == listen_socket[sock].sa.sa.sa_family)
376                         break;
377
378         if(sock >= listen_sockets)
379                 sock = 0;                               /* If none is available, just use the first and hope for the best. */
380
381         /* Send the packet */
382
383 #if defined(SOL_IP) && defined(IP_TOS)
384         if(priorityinheritance && origpriority != priority
385            && listen_socket[sock].sa.sa.sa_family == AF_INET) {
386                 priority = origpriority;
387                 ifdebug(TRAFFIC) logger(LOG_DEBUG, "Setting outgoing packet priority to %d", priority);
388                 if(setsockopt(listen_socket[sock].udp, SOL_IP, IP_TOS, &priority, sizeof priority))     /* SO_PRIORITY doesn't seem to work */
389                         logger(LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno));
390         }
391 #endif
392
393         if((sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, &(n->address.sa), SALEN(n->address.sa))) < 0) {
394                 if(errno == EMSGSIZE) {
395                         if(n->maxmtu >= origlen)
396                                 n->maxmtu = origlen - 1;
397                         if(n->mtu >= origlen)
398                                 n->mtu = origlen - 1;
399                 } else
400                         logger(LOG_ERR, "Error sending packet to %s (%s): %s", n->name, n->hostname, strerror(errno));
401         }
402
403 end:
404         origpkt->len = origlen;
405 }
406
407 /*
408   send a packet to the given vpn ip.
409 */
410 void send_packet(const node_t *n, vpn_packet_t *packet) {
411         node_t *via;
412
413         if(n == myself) {
414                 if(overwrite_mac)
415                          memcpy(packet->data, mymac.x, ETH_ALEN);
416                 write_packet(packet);
417                 return;
418         }
419
420         ifdebug(TRAFFIC) logger(LOG_ERR, "Sending packet of %d bytes to %s (%s)",
421                            packet->len, n->name, n->hostname);
422
423         if(!n->status.reachable) {
424                 ifdebug(TRAFFIC) logger(LOG_INFO, "Node %s (%s) is not reachable",
425                                    n->name, n->hostname);
426                 return;
427         }
428
429         via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via;
430
431         if(via != n)
432                 ifdebug(TRAFFIC) logger(LOG_INFO, "Sending packet to %s via %s (%s)",
433                            n->name, via->name, n->via->hostname);
434
435         if(packet->priority == -1 || ((myself->options | via->options) & OPTION_TCPONLY)) {
436                 if(!send_tcppacket(via->connection, packet))
437                         terminate_connection(via->connection, true);
438         } else
439                 send_udppacket(via, packet);
440 }
441
442 /* Broadcast a packet using the minimum spanning tree */
443
444 void broadcast_packet(const node_t *from, vpn_packet_t *packet) {
445         splay_node_t *node;
446         connection_t *c;
447
448         ifdebug(TRAFFIC) logger(LOG_INFO, "Broadcasting packet of %d bytes from %s (%s)",
449                            packet->len, from->name, from->hostname);
450
451         if(from != myself) {
452                 send_packet(myself, packet);
453
454                 // In TunnelServer mode, do not forward broadcast packets.
455                 // The MST might not be valid and create loops.
456                 if(tunnelserver)
457                         return;
458         }
459
460         for(node = connection_tree->head; node; node = node->next) {
461                 c = node->data;
462
463                 if(c->status.active && c->status.mst && c != from->nexthop->connection)
464                         send_packet(c->node, packet);
465         }
466 }
467
468 static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) {
469         splay_node_t *node;
470         edge_t *e;
471         node_t *n = NULL;
472
473         for(node = edge_weight_tree->head; node; node = node->next) {
474                 e = node->data;
475
476                 if(sockaddrcmp_noport(from, &e->address))
477                         continue;
478
479                 if(!n)
480                         n = e->to;
481
482                 if(!try_mac(e->to, pkt))
483                         continue;
484
485                 n = e->to;
486                 break;
487         }
488
489         return n;
490 }
491
492 void handle_incoming_vpn_data(int sock, short events, void *data) {
493         vpn_packet_t pkt;
494         char *hostname;
495         sockaddr_t from;
496         socklen_t fromlen = sizeof from;
497         node_t *n;
498
499         pkt.len = recvfrom(sock, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen);
500
501         if(pkt.len < 0) {
502                 if(errno != EAGAIN && errno != EINTR)
503                         logger(LOG_ERR, "Receiving packet failed: %s", strerror(errno));
504                 return;
505         }
506
507         sockaddrunmap(&from);           /* Some braindead IPv6 implementations do stupid things. */
508
509         n = lookup_node_udp(&from);
510
511         if(!n) {
512                 n = try_harder(&from, &pkt);
513                 if(n)
514                         update_node_udp(n, &from);
515                 else ifdebug(PROTOCOL) {
516                         hostname = sockaddr2hostname(&from);
517                         logger(LOG_WARNING, "Received UDP packet from unknown source %s", hostname);
518                         free(hostname);
519                         return;
520                 }
521                 else
522                         return;
523         }
524
525         receive_udppacket(n, &pkt);
526 }
527
528 void handle_device_data(int sock, short events, void *data) {
529         vpn_packet_t packet;
530
531         if(read_packet(&packet))
532                 route(myself, &packet);
533 }