a989b09f20733aaf7244bea77073109ddb49469c
[tinc] / src / net_packet.c
1 /*
2     net_packet.c -- Handles in- and outgoing VPN packets
3     Copyright (C) 1998-2003 Ivo Timmermans <ivo@o2w.nl>,
4                   2000-2003 Guus Sliepen <guus@sliepen.eu.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: net_packet.c,v 1.1.2.41 2003/09/23 20:59:01 guus Exp $
21 */
22
23 #include "system.h"
24
25 #include <openssl/rand.h>
26 #include <openssl/evp.h>
27 #include <openssl/pem.h>
28 #include <openssl/hmac.h>
29
30 #include <zlib.h>
31 #include <lzo1x.h>
32
33 #include "avl_tree.h"
34 #include "conf.h"
35 #include "connection.h"
36 #include "device.h"
37 #include "event.h"
38 #include "graph.h"
39 #include "list.h"
40 #include "logger.h"
41 #include "net.h"
42 #include "netutl.h"
43 #include "protocol.h"
44 #include "process.h"
45 #include "route.h"
46 #include "utils.h"
47 #include "xalloc.h"
48
49 int keylifetime = 0;
50 int keyexpires = 0;
51 EVP_CIPHER_CTX packet_ctx;
52 static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999_MEM_COMPRESS : LZO1X_1_MEM_COMPRESS];
53
54
55 #define MAX_SEQNO 1073741824
56
57 static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level)
58 {
59         if(level == 10) {
60                 lzo_uint lzolen = MAXSIZE;
61                 lzo1x_1_compress(source, len, dest, &lzolen, lzo_wrkmem);
62                 return lzolen;
63         } else if(level < 10) {
64                 unsigned long destlen = MAXSIZE;
65                 if(compress2(dest, &destlen, source, len, level) == Z_OK)
66                         return destlen;
67                 else
68                         return -1;
69         } else {
70                 lzo_uint lzolen = MAXSIZE;
71                 lzo1x_999_compress(source, len, dest, &lzolen, lzo_wrkmem);
72                 return lzolen;
73         }
74         
75         return -1;
76 }
77
78 static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level)
79 {
80         if(level > 9) {
81                 lzo_uint lzolen = MAXSIZE;
82                 if(lzo1x_decompress_safe(source, len, dest, &lzolen, NULL) == LZO_E_OK)
83                         return lzolen;
84                 else
85                         return -1;
86         } else {
87                 unsigned long destlen = MAXSIZE;
88                 if(uncompress(dest, &destlen, source, len) == Z_OK)
89                         return destlen;
90                 else
91                         return -1;
92         }
93         
94         return -1;
95 }
96
97 /* VPN packet I/O */
98
99 static void receive_packet(node_t *n, vpn_packet_t *packet)
100 {
101         cp();
102
103         ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Received packet of %d bytes from %s (%s)"),
104                            packet->len, n->name, n->hostname);
105
106         route_incoming(n, packet);
107 }
108
109 static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
110 {
111         vpn_packet_t pkt1, pkt2;
112         vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
113         int nextpkt = 0;
114         vpn_packet_t *outpkt = pkt[0];
115         int outlen, outpad;
116         char hmac[EVP_MAX_MD_SIZE];
117         int i;
118
119         cp();
120
121         /* Check packet length */
122
123         if(inpkt->len < sizeof(inpkt->seqno) + myself->maclength) {
124                 ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Got too short packet from %s (%s)"),
125                                         n->name, n->hostname);
126                 return;
127         }
128
129         /* Check the message authentication code */
130
131         if(myself->digest && myself->maclength) {
132                 inpkt->len -= myself->maclength;
133                 HMAC(myself->digest, myself->key, myself->keylength,
134                          (char *) &inpkt->seqno, inpkt->len, hmac, NULL);
135
136                 if(memcmp(hmac, (char *) &inpkt->seqno + inpkt->len, myself->maclength)) {
137                         ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Got unauthenticated packet from %s (%s)"),
138                                            n->name, n->hostname);
139                         return;
140                 }
141         }
142
143         /* Decrypt the packet */
144
145         if(myself->cipher) {
146                 outpkt = pkt[nextpkt++];
147
148 //              EVP_DecryptInit_ex(&packet_ctx, myself->cipher, NULL, myself->key,
149 //                                              myself->key + myself->cipher->key_len);
150                 EVP_DecryptInit_ex(&packet_ctx, NULL, NULL, NULL, NULL);
151                 EVP_DecryptUpdate(&packet_ctx, (char *) &outpkt->seqno, &outlen,
152                                                   (char *) &inpkt->seqno, inpkt->len);
153                 EVP_DecryptFinal_ex(&packet_ctx, (char *) &outpkt->seqno + outlen, &outpad);
154                 
155                 outpkt->len = outlen + outpad;
156                 inpkt = outpkt;
157         }
158
159         /* Check the sequence number */
160
161         inpkt->len -= sizeof(inpkt->seqno);
162         inpkt->seqno = ntohl(inpkt->seqno);
163
164         if(inpkt->seqno != n->received_seqno + 1) {
165                 if(inpkt->seqno >= n->received_seqno + sizeof(n->late) * 8) {
166                         logger(LOG_WARNING, _("Lost %d packets from %s (%s)"),
167                                            inpkt->seqno - n->received_seqno - 1, n->name, n->hostname);
168                         
169                         memset(n->late, 0, sizeof(n->late));
170                 } else if (inpkt->seqno <= n->received_seqno) {
171                         if(inpkt->seqno <= n->received_seqno - sizeof(n->late) * 8 || !(n->late[(inpkt->seqno / 8) % sizeof(n->late)] & (1 << inpkt->seqno % 8))) {
172                                 logger(LOG_WARNING, _("Got late or replayed packet from %s (%s), seqno %d, last received %d"),
173                                            n->name, n->hostname, inpkt->seqno, n->received_seqno);
174                         } else
175                                 for(i = n->received_seqno + 1; i < inpkt->seqno; i++)
176                                         n->late[(inpkt->seqno / 8) % sizeof(n->late)] |= 1 << i % 8;
177                 }
178         }
179         
180         n->received_seqno = inpkt->seqno;
181         n->late[(n->received_seqno / 8) % sizeof(n->late)] &= ~(1 << n->received_seqno % 8);
182                         
183         if(n->received_seqno > MAX_SEQNO)
184                 keyexpires = 0;
185
186         /* Decompress the packet */
187
188         if(myself->compression) {
189                 outpkt = pkt[nextpkt++];
190
191                 if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, myself->compression)) < 0) {
192                         logger(LOG_ERR, _("Error while uncompressing packet from %s (%s)"),
193                                    n->name, n->hostname);
194                         return;
195                 }
196
197                 inpkt = outpkt;
198         }
199
200         if(n->connection)
201                 n->connection->last_ping_time = now;
202
203         receive_packet(n, inpkt);
204 }
205
206 void receive_tcppacket(connection_t *c, char *buffer, int len)
207 {
208         vpn_packet_t outpkt;
209
210         cp();
211
212         outpkt.len = len;
213         memcpy(outpkt.data, buffer, len);
214
215         receive_packet(c->node, &outpkt);
216 }
217
218 static void send_udppacket(node_t *n, vpn_packet_t *inpkt)
219 {
220         vpn_packet_t pkt1, pkt2;
221         vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
222         int nextpkt = 0;
223         vpn_packet_t *outpkt;
224         int origlen;
225         int outlen, outpad;
226         vpn_packet_t *copy;
227         static int priority = 0;
228         int origpriority;
229         int sock;
230
231         cp();
232
233         /* Make sure we have a valid key */
234
235         if(!n->status.validkey) {
236                 ifdebug(TRAFFIC) logger(LOG_INFO,
237                                    _("No valid key known yet for %s (%s), queueing packet"),
238                                    n->name, n->hostname);
239
240                 /* Since packet is on the stack of handle_tap_input(), we have to make a copy of it first. */
241
242                 copy = xmalloc(sizeof(vpn_packet_t));
243                 memcpy(copy, inpkt, sizeof(vpn_packet_t));
244
245                 list_insert_tail(n->queue, copy);
246
247                 if(n->queue->count > MAXQUEUELENGTH)
248                         list_delete_head(n->queue);
249
250                 if(!n->status.waitingforkey)
251                         send_req_key(n->nexthop->connection, myself, n);
252
253                 n->status.waitingforkey = true;
254
255                 return;
256         }
257
258         origlen = inpkt->len;
259         origpriority = inpkt->priority;
260
261         /* Compress the packet */
262
263         if(n->compression) {
264                 outpkt = pkt[nextpkt++];
265
266                 if((outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->compression)) < 0) {
267                         logger(LOG_ERR, _("Error while compressing packet to %s (%s)"),
268                                    n->name, n->hostname);
269                         return;
270                 }
271
272                 inpkt = outpkt;
273         }
274
275         /* Add sequence number */
276
277         inpkt->seqno = htonl(++(n->sent_seqno));
278         inpkt->len += sizeof(inpkt->seqno);
279
280         /* Encrypt the packet */
281
282         if(n->cipher) {
283                 outpkt = pkt[nextpkt++];
284
285 //              EVP_EncryptInit_ex(&packet_ctx, n->cipher, NULL, n->key, n->key + n->cipher->key_len);
286                 EVP_EncryptInit_ex(&n->packet_ctx, NULL, NULL, NULL, NULL);
287                 EVP_EncryptUpdate(&n->packet_ctx, (char *) &outpkt->seqno, &outlen,
288                                                   (char *) &inpkt->seqno, inpkt->len);
289                 EVP_EncryptFinal_ex(&n->packet_ctx, (char *) &outpkt->seqno + outlen, &outpad);
290
291                 outpkt->len = outlen + outpad;
292                 inpkt = outpkt;
293         }
294
295         /* Add the message authentication code */
296
297         if(n->digest && n->maclength) {
298                 HMAC(n->digest, n->key, n->keylength, (char *) &inpkt->seqno,
299                          inpkt->len, (char *) &inpkt->seqno + inpkt->len, &outlen);
300                 inpkt->len += n->maclength;
301         }
302
303         /* Determine which socket we have to use */
304
305         for(sock = 0; sock < listen_sockets; sock++)
306                 if(n->address.sa.sa_family == listen_socket[sock].sa.sa.sa_family)
307                         break;
308
309         if(sock >= listen_sockets)
310                 sock = 0;                               /* If none is available, just use the first and hope for the best. */
311
312         /* Send the packet */
313
314 #if defined(SOL_IP) && defined(IP_TOS)
315         if(priorityinheritance && origpriority != priority
316            && listen_socket[sock].sa.sa.sa_family == AF_INET) {
317                 priority = origpriority;
318                 ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Setting outgoing packet priority to %d"), priority);
319                 if(setsockopt(listen_socket[sock].udp, SOL_IP, IP_TOS, &priority, sizeof(priority)))    /* SO_PRIORITY doesn't seem to work */
320                         logger(LOG_ERR, _("System call `%s' failed: %s"), "setsockopt", strerror(errno));
321         }
322 #endif
323
324         if((sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, &(n->address.sa), SALEN(n->address.sa))) < 0) {
325                 logger(LOG_ERR, _("Error sending packet to %s (%s): %s"), n->name, n->hostname, strerror(errno));
326                 return;
327         }
328
329         inpkt->len = origlen;
330 }
331
332 /*
333   send a packet to the given vpn ip.
334 */
335 void send_packet(const node_t *n, vpn_packet_t *packet)
336 {
337         node_t *via;
338
339         cp();
340
341         ifdebug(TRAFFIC) logger(LOG_ERR, _("Sending packet of %d bytes to %s (%s)"),
342                            packet->len, n->name, n->hostname);
343
344         if(n == myself) {
345                 ifdebug(TRAFFIC) logger(LOG_NOTICE, _("Packet is looping back to us!"));
346                 return;
347         }
348
349         if(!n->status.reachable) {
350                 ifdebug(TRAFFIC) logger(LOG_INFO, _("Node %s (%s) is not reachable"),
351                                    n->name, n->hostname);
352                 return;
353         }
354
355         via = (n->via == myself) ? n->nexthop : n->via;
356
357         if(via != n)
358                 ifdebug(TRAFFIC) logger(LOG_ERR, _("Sending packet to %s via %s (%s)"),
359                            n->name, via->name, n->via->hostname);
360
361         if((myself->options | via->options) & OPTION_TCPONLY) {
362                 if(!send_tcppacket(via->connection, packet))
363                         terminate_connection(via->connection, true);
364         } else
365                 send_udppacket(via, packet);
366 }
367
368 /* Broadcast a packet using the minimum spanning tree */
369
370 void broadcast_packet(const node_t *from, vpn_packet_t *packet)
371 {
372         avl_node_t *node;
373         connection_t *c;
374
375         cp();
376
377         ifdebug(TRAFFIC) logger(LOG_INFO, _("Broadcasting packet of %d bytes from %s (%s)"),
378                            packet->len, from->name, from->hostname);
379
380         for(node = connection_tree->head; node; node = node->next) {
381                 c = node->data;
382
383                 if(c->status.active && c->status.mst && c != from->nexthop->connection)
384                         send_packet(c->node, packet);
385         }
386 }
387
388 void flush_queue(node_t *n)
389 {
390         list_node_t *node, *next;
391
392         cp();
393
394         ifdebug(TRAFFIC) logger(LOG_INFO, _("Flushing queue for %s (%s)"), n->name, n->hostname);
395
396         for(node = n->queue->head; node; node = next) {
397                 next = node->next;
398                 send_udppacket(n, node->data);
399                 list_delete_node(n->queue, node);
400         }
401 }
402
403 void handle_incoming_vpn_data(int sock)
404 {
405         vpn_packet_t pkt;
406         char *hostname;
407         sockaddr_t from;
408         socklen_t fromlen = sizeof(from);
409         node_t *n;
410
411         cp();
412
413         pkt.len = recvfrom(sock, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen);
414
415         if(pkt.len < 0) {
416                 logger(LOG_ERR, _("Receiving packet failed: %s"), strerror(errno));
417                 return;
418         }
419
420         sockaddrunmap(&from);           /* Some braindead IPv6 implementations do stupid things. */
421
422         n = lookup_node_udp(&from);
423
424         if(!n) {
425                 hostname = sockaddr2hostname(&from);
426                 logger(LOG_WARNING, _("Received UDP packet from unknown source %s"),
427                            hostname);
428                 free(hostname);
429                 return;
430         }
431
432         receive_udppacket(n, &pkt);
433 }