]> git.meshlink.io Git - meshlink/blob - src/net_packet.c
Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1
[meshlink] / src / net_packet.c
1 /*
2     net_packet.c -- Handles in- and outgoing VPN packets
3     Copyright (C) 1998-2005 Ivo Timmermans,
4                   2000-2011 Guus Sliepen <guus@tinc-vpn.org>
5                   2010      Timothy Redaelli <timothy@redaelli.eu>
6                   2010      Brandon Black <blblack@gmail.com>
7
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17
18     You should have received a copy of the GNU General Public License along
19     with this program; if not, write to the Free Software Foundation, Inc.,
20     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23 #include "system.h"
24
25 #include <openssl/rand.h>
26 #include <openssl/err.h>
27 #include <openssl/evp.h>
28 #include <openssl/pem.h>
29 #include <openssl/hmac.h>
30
31 #ifdef HAVE_ZLIB
32 #include <zlib.h>
33 #endif
34
35 #ifdef HAVE_LZO
36 #include LZO1X_H
37 #endif
38
39 #include "splay_tree.h"
40 #include "cipher.h"
41 #include "conf.h"
42 #include "connection.h"
43 #include "crypto.h"
44 #include "digest.h"
45 #include "device.h"
46 #include "ethernet.h"
47 #include "graph.h"
48 #include "logger.h"
49 #include "net.h"
50 #include "netutl.h"
51 #include "protocol.h"
52 #include "process.h"
53 #include "route.h"
54 #include "utils.h"
55 #include "xalloc.h"
56
57 int keylifetime = 0;
58 #ifdef HAVE_LZO
59 static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999_MEM_COMPRESS : LZO1X_1_MEM_COMPRESS];
60 #endif
61
62 static void send_udppacket(node_t *, vpn_packet_t *);
63
64 unsigned replaywin = 16;
65 bool localdiscovery = false;
66
67 #define MAX_SEQNO 1073741824
68
69 /* mtuprobes == 1..30: initial discovery, send bursts with 1 second interval
70    mtuprobes ==    31: sleep pinginterval seconds
71    mtuprobes ==    32: send 1 burst, sleep pingtimeout second
72    mtuprobes ==    33: no response from other side, restart PMTU discovery process
73
74    Probes are sent in batches of three, with random sizes between the lower and
75    upper boundaries for the MTU thus far discovered.
76
77    In case local discovery is enabled, a fourth packet is added to each batch,
78    which will be broadcast to the local network.
79 */
80
81 static void send_mtu_probe_handler(int fd, short events, void *data) {
82         node_t *n = data;
83         vpn_packet_t packet;
84         int len, i;
85         int timeout = 1;
86         
87         n->mtuprobes++;
88
89         if(!n->status.reachable || !n->status.validkey) {
90                 ifdebug(TRAFFIC) logger(LOG_INFO, "Trying to send MTU probe to unreachable or rekeying node %s (%s)", n->name, n->hostname);
91                 n->mtuprobes = 0;
92                 return;
93         }
94
95         if(n->mtuprobes > 32) {
96                 if(!n->minmtu) {
97                         n->mtuprobes = 31;
98                         timeout = pinginterval;
99                         goto end;
100                 }
101
102                 ifdebug(TRAFFIC) logger(LOG_INFO, "%s (%s) did not respond to UDP ping, restarting PMTU discovery", n->name, n->hostname);
103                 n->mtuprobes = 1;
104                 n->minmtu = 0;
105                 n->maxmtu = MTU;
106         }
107
108         if(n->mtuprobes >= 10 && n->mtuprobes < 32 && !n->minmtu) {
109                 ifdebug(TRAFFIC) logger(LOG_INFO, "No response to MTU probes from %s (%s)", n->name, n->hostname);
110                 n->mtuprobes = 31;
111         }
112
113         if(n->mtuprobes == 30 || (n->mtuprobes < 30 && n->minmtu >= n->maxmtu)) {
114                 if(n->minmtu > n->maxmtu)
115                         n->minmtu = n->maxmtu;
116                 else
117                         n->maxmtu = n->minmtu;
118                 n->mtu = n->minmtu;
119                 ifdebug(TRAFFIC) logger(LOG_INFO, "Fixing MTU of %s (%s) to %d after %d probes", n->name, n->hostname, n->mtu, n->mtuprobes);
120                 n->mtuprobes = 31;
121         }
122
123         if(n->mtuprobes == 31) {
124                 timeout = pinginterval;
125                 goto end;
126         } else if(n->mtuprobes == 32) {
127                 timeout = pingtimeout;
128         }
129
130         for(i = 0; i < 3 + localdiscovery; i++) {
131                 if(n->maxmtu <= n->minmtu)
132                         len = n->maxmtu;
133                 else
134                         len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
135
136                 if(len < 64)
137                         len = 64;
138                 
139                 memset(packet.data, 0, 14);
140                 randomize(packet.data + 14, len - 14);
141                 packet.len = len;
142                 packet.priority = i < 3 ? 0 : -1;
143
144                 ifdebug(TRAFFIC) logger(LOG_INFO, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname);
145
146                 send_udppacket(n, &packet);
147         }
148
149 end:
150         event_add(&n->mtuevent, &(struct timeval){timeout, 0});
151 }
152
153 void send_mtu_probe(node_t *n) {
154         if(!timeout_initialized(&n->mtuevent))
155                 timeout_set(&n->mtuevent, send_mtu_probe_handler, n);
156         send_mtu_probe_handler(0, 0, n);
157 }
158
159 static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
160         ifdebug(TRAFFIC) logger(LOG_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname);
161
162         if(!packet->data[0]) {
163                 packet->data[0] = 1;
164                 send_udppacket(n, packet);
165         } else {
166                 if(n->mtuprobes > 30) {
167                         if(n->minmtu)
168                                 n->mtuprobes = 30;
169                         else
170                                 n->mtuprobes = 1;
171                 }
172
173                 if(len > n->maxmtu)
174                         len = n->maxmtu;
175                 if(n->minmtu < len)
176                         n->minmtu = len;
177         }
178 }
179
180 static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level) {
181         if(level == 0) {
182                 memcpy(dest, source, len);
183                 return len;
184         } else if(level == 10) {
185 #ifdef HAVE_LZO
186                 lzo_uint lzolen = MAXSIZE;
187                 lzo1x_1_compress(source, len, dest, &lzolen, lzo_wrkmem);
188                 return lzolen;
189 #else
190                 return -1;
191 #endif
192         } else if(level < 10) {
193 #ifdef HAVE_ZLIB
194                 unsigned long destlen = MAXSIZE;
195                 if(compress2(dest, &destlen, source, len, level) == Z_OK)
196                         return destlen;
197                 else
198 #endif
199                         return -1;
200         } else {
201 #ifdef HAVE_LZO
202                 lzo_uint lzolen = MAXSIZE;
203                 lzo1x_999_compress(source, len, dest, &lzolen, lzo_wrkmem);
204                 return lzolen;
205 #else
206                 return -1;
207 #endif
208         }
209         
210         return -1;
211 }
212
213 static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level) {
214         if(level == 0) {
215                 memcpy(dest, source, len);
216                 return len;
217         } else if(level > 9) {
218 #ifdef HAVE_LZO
219                 lzo_uint lzolen = MAXSIZE;
220                 if(lzo1x_decompress_safe(source, len, dest, &lzolen, NULL) == LZO_E_OK)
221                         return lzolen;
222                 else
223 #endif
224                         return -1;
225         }
226 #ifdef HAVE_ZLIB
227         else {
228                 unsigned long destlen = MAXSIZE;
229                 if(uncompress(dest, &destlen, source, len) == Z_OK)
230                         return destlen;
231                 else
232                         return -1;
233         }
234 #endif
235
236         return -1;
237 }
238
239 /* VPN packet I/O */
240
241 static void receive_packet(node_t *n, vpn_packet_t *packet) {
242         ifdebug(TRAFFIC) logger(LOG_DEBUG, "Received packet of %d bytes from %s (%s)",
243                            packet->len, n->name, n->hostname);
244
245         n->in_packets++;
246         n->in_bytes += packet->len;
247
248         route(n, packet);
249 }
250
251 static bool try_mac(node_t *n, const vpn_packet_t *inpkt) {
252         if(!digest_active(&n->indigest) || inpkt->len < sizeof inpkt->seqno + digest_length(&n->indigest))
253                 return false;
254
255         return digest_verify(&n->indigest, &inpkt->seqno, inpkt->len - n->indigest.maclength, (const char *)&inpkt->seqno + inpkt->len - n->indigest.maclength);
256 }
257
258 static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
259         vpn_packet_t pkt1, pkt2;
260         vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
261         int nextpkt = 0;
262         vpn_packet_t *outpkt = pkt[0];
263         size_t outlen;
264
265         if(!cipher_active(&n->incipher)) {
266                 ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet",
267                                         n->name, n->hostname);
268                 return;
269         }
270
271         /* Check packet length */
272
273         if(inpkt->len < sizeof inpkt->seqno + digest_length(&n->indigest)) {
274                 ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got too short packet from %s (%s)",
275                                         n->name, n->hostname);
276                 return;
277         }
278
279         /* Check the message authentication code */
280
281         if(digest_active(&n->indigest)) {
282                 inpkt->len -= n->indigest.maclength;
283                 if(!digest_verify(&n->indigest, &inpkt->seqno, inpkt->len, (const char *)&inpkt->seqno + inpkt->len)) {
284                         ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got unauthenticated packet from %s (%s)", n->name, n->hostname);
285                         return;
286                 }
287         }
288         /* Decrypt the packet */
289
290         if(cipher_active(&n->incipher)) {
291                 outpkt = pkt[nextpkt++];
292                 outlen = MAXSIZE;
293
294                 if(!cipher_decrypt(&n->incipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) {
295                         ifdebug(TRAFFIC) logger(LOG_DEBUG, "Error decrypting packet from %s (%s)", n->name, n->hostname);
296                         return;
297                 }
298                 
299                 outpkt->len = outlen;
300                 inpkt = outpkt;
301         }
302
303         /* Check the sequence number */
304
305         inpkt->len -= sizeof inpkt->seqno;
306         inpkt->seqno = ntohl(inpkt->seqno);
307
308         if(replaywin) {
309                 if(inpkt->seqno != n->received_seqno + 1) {
310                         if(inpkt->seqno >= n->received_seqno + replaywin * 8) {
311                                 if(n->farfuture++ < replaywin >> 2) {
312                                         logger(LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)",
313                                                 n->name, n->hostname, inpkt->seqno - n->received_seqno - 1, n->farfuture);
314                                         return;
315                                 }
316                                 logger(LOG_WARNING, "Lost %d packets from %s (%s)",
317                                                 inpkt->seqno - n->received_seqno - 1, n->name, n->hostname);
318                                 memset(n->late, 0, replaywin);
319                         } else if (inpkt->seqno <= n->received_seqno) {
320                                 if((n->received_seqno >= replaywin * 8 && inpkt->seqno <= n->received_seqno - replaywin * 8) || !(n->late[(inpkt->seqno / 8) % replaywin] & (1 << inpkt->seqno % 8))) {
321                                         logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d",
322                                                 n->name, n->hostname, inpkt->seqno, n->received_seqno);
323                                         return;
324                                 }
325                         } else {
326                                 for(int i = n->received_seqno + 1; i < inpkt->seqno; i++)
327                                         n->late[(i / 8) % replaywin] |= 1 << i % 8;
328                         }
329                 }
330
331                 n->farfuture = 0;
332                 n->late[(inpkt->seqno / 8) % replaywin] &= ~(1 << inpkt->seqno % 8);
333         }
334
335         if(inpkt->seqno > n->received_seqno)
336                 n->received_seqno = inpkt->seqno;
337                         
338         if(n->received_seqno > MAX_SEQNO)
339                 regenerate_key();
340
341         /* Decompress the packet */
342
343         length_t origlen = inpkt->len;
344
345         if(n->incompression) {
346                 outpkt = pkt[nextpkt++];
347
348                 if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, n->incompression)) < 0) {
349                         ifdebug(TRAFFIC) logger(LOG_ERR, "Error while uncompressing packet from %s (%s)",
350                                                  n->name, n->hostname);
351                         return;
352                 }
353
354                 inpkt = outpkt;
355
356                 origlen -= MTU/64 + 20;
357         }
358
359         inpkt->priority = 0;
360
361         if(!inpkt->data[12] && !inpkt->data[13])
362                 mtu_probe_h(n, inpkt, origlen);
363         else
364                 receive_packet(n, inpkt);
365 }
366
367 void receive_tcppacket(connection_t *c, const char *buffer, int len) {
368         vpn_packet_t outpkt;
369
370         outpkt.len = len;
371         if(c->options & OPTION_TCPONLY)
372                 outpkt.priority = 0;
373         else
374                 outpkt.priority = -1;
375         memcpy(outpkt.data, buffer, len);
376
377         receive_packet(c->node, &outpkt);
378 }
379
380 static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
381         vpn_packet_t pkt1, pkt2;
382         vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
383         vpn_packet_t *inpkt = origpkt;
384         int nextpkt = 0;
385         vpn_packet_t *outpkt;
386         int origlen = origpkt->len;
387         size_t outlen;
388 #if defined(SOL_IP) && defined(IP_TOS)
389         static int priority = 0;
390         int origpriority = origpkt->priority;
391 #endif
392
393         if(!n->status.reachable) {
394                 ifdebug(TRAFFIC) logger(LOG_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname);
395                 return;
396         }
397
398         /* Make sure we have a valid key */
399
400         if(!n->status.validkey) {
401                 time_t now = time(NULL);
402
403                 ifdebug(TRAFFIC) logger(LOG_INFO,
404                                    "No valid key known yet for %s (%s), forwarding via TCP",
405                                    n->name, n->hostname);
406
407                 if(n->last_req_key + 10 <= now) {
408                         send_req_key(n);
409                         n->last_req_key = now;
410                 }
411
412                 send_tcppacket(n->nexthop->connection, origpkt);
413
414                 return;
415         }
416
417         if(n->options & OPTION_PMTU_DISCOVERY && inpkt->len > n->minmtu && (inpkt->data[12] | inpkt->data[13])) {
418                 ifdebug(TRAFFIC) logger(LOG_INFO,
419                                 "Packet for %s (%s) larger than minimum MTU, forwarding via %s",
420                                 n->name, n->hostname, n != n->nexthop ? n->nexthop->name : "TCP");
421
422                 if(n != n->nexthop)
423                         send_packet(n->nexthop, origpkt);
424                 else
425                         send_tcppacket(n->nexthop->connection, origpkt);
426
427                 return;
428         }
429
430         /* Compress the packet */
431
432         if(n->outcompression) {
433                 outpkt = pkt[nextpkt++];
434
435                 if((outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->outcompression)) < 0) {
436                         ifdebug(TRAFFIC) logger(LOG_ERR, "Error while compressing packet to %s (%s)",
437                                    n->name, n->hostname);
438                         return;
439                 }
440
441                 inpkt = outpkt;
442         }
443
444         /* Add sequence number */
445
446         inpkt->seqno = htonl(++(n->sent_seqno));
447         inpkt->len += sizeof inpkt->seqno;
448
449         /* Encrypt the packet */
450
451         if(cipher_active(&n->outcipher)) {
452                 outpkt = pkt[nextpkt++];
453                 outlen = MAXSIZE;
454
455                 if(!cipher_encrypt(&n->outcipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) {
456                         ifdebug(TRAFFIC) logger(LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname);
457                         goto end;
458                 }
459
460                 outpkt->len = outlen;
461                 inpkt = outpkt;
462         }
463
464         /* Add the message authentication code */
465
466         if(digest_active(&n->outdigest)) {
467                 digest_create(&n->outdigest, &inpkt->seqno, inpkt->len, (char *)&inpkt->seqno + inpkt->len);
468                 inpkt->len += digest_length(&n->outdigest);
469         }
470
471         /* Determine which socket we have to use */
472
473         if(n->address.sa.sa_family != listen_socket[n->sock].sa.sa.sa_family) {
474                 for(int sock = 0; sock < listen_sockets; sock++) {
475                         if(n->address.sa.sa_family == listen_socket[sock].sa.sa.sa_family) {
476                                 n->sock = sock;
477                                 break;
478                         }
479                 }
480         }
481
482         /* Send the packet */
483
484         struct sockaddr *sa;
485         socklen_t sl;
486         int sock;
487
488         /* Overloaded use of priority field: -1 means local broadcast */
489
490         if(origpriority == -1 && n->prevedge) {
491                 struct sockaddr_in in;
492                 in.sin_family = AF_INET;
493                 in.sin_addr.s_addr = -1;
494                 in.sin_port = n->prevedge->address.in.sin_port;
495                 sa = (struct sockaddr *)&in;
496                 sl = sizeof in;
497                 sock = 0;
498         } else {
499                 if(origpriority == -1)
500                         origpriority = 0;
501
502                 sa = &(n->address.sa);
503                 sl = SALEN(n->address.sa);
504                 sock = n->sock;
505         }
506
507 #if defined(SOL_IP) && defined(IP_TOS)
508         if(priorityinheritance && origpriority != priority
509            && listen_socket[n->sock].sa.sa.sa_family == AF_INET) {
510                 priority = origpriority;
511                 ifdebug(TRAFFIC) logger(LOG_DEBUG, "Setting outgoing packet priority to %d", priority);
512                 if(setsockopt(listen_socket[n->sock].udp, SOL_IP, IP_TOS, &priority, sizeof(priority))) /* SO_PRIORITY doesn't seem to work */
513                         logger(LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno));
514         }
515 #endif
516
517         if(sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, sa, sl) < 0 && !sockwouldblock(sockerrno)) {
518                 if(sockmsgsize(sockerrno)) {
519                         if(n->maxmtu >= origlen)
520                                 n->maxmtu = origlen - 1;
521                         if(n->mtu >= origlen)
522                                 n->mtu = origlen - 1;
523                 } else
524                         logger(LOG_ERR, "Error sending packet to %s (%s): %s", n->name, n->hostname, sockstrerror(sockerrno));
525         }
526
527 end:
528         origpkt->len = origlen;
529 }
530
531 /*
532   send a packet to the given vpn ip.
533 */
534 void send_packet(node_t *n, vpn_packet_t *packet) {
535         node_t *via;
536
537         if(n == myself) {
538                 if(overwrite_mac)
539                          memcpy(packet->data, mymac.x, ETH_ALEN);
540                 n->out_packets++;
541                 n->out_bytes += packet->len;
542                 devops.write(packet);
543                 return;
544         }
545
546         ifdebug(TRAFFIC) logger(LOG_ERR, "Sending packet of %d bytes to %s (%s)",
547                            packet->len, n->name, n->hostname);
548
549         if(!n->status.reachable) {
550                 ifdebug(TRAFFIC) logger(LOG_INFO, "Node %s (%s) is not reachable",
551                                    n->name, n->hostname);
552                 return;
553         }
554
555         n->out_packets++;
556         n->out_bytes += packet->len;
557
558         via = (packet->priority == -1 || n->via == myself) ? n->nexthop : n->via;
559
560         if(via != n)
561                 ifdebug(TRAFFIC) logger(LOG_INFO, "Sending packet to %s via %s (%s)",
562                            n->name, via->name, n->via->hostname);
563
564         if(packet->priority == -1 || ((myself->options | via->options) & OPTION_TCPONLY)) {
565                 if(!send_tcppacket(via->connection, packet))
566                         terminate_connection(via->connection, true);
567         } else
568                 send_udppacket(via, packet);
569 }
570
571 /* Broadcast a packet using the minimum spanning tree */
572
573 void broadcast_packet(const node_t *from, vpn_packet_t *packet) {
574         splay_node_t *node;
575         connection_t *c;
576
577         ifdebug(TRAFFIC) logger(LOG_INFO, "Broadcasting packet of %d bytes from %s (%s)",
578                            packet->len, from->name, from->hostname);
579
580         if(from != myself) {
581                 send_packet(myself, packet);
582
583                 // In TunnelServer mode, do not forward broadcast packets.
584                 // The MST might not be valid and create loops.
585                 if(tunnelserver)
586                         return;
587         }
588
589         for(node = connection_tree->head; node; node = node->next) {
590                 c = node->data;
591
592                 if(c->status.active && c->status.mst && c != from->nexthop->connection)
593                         send_packet(c->node, packet);
594         }
595 }
596
597 static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) {
598         splay_node_t *node;
599         edge_t *e;
600         node_t *n = NULL;
601         bool hard = false;
602         static time_t last_hard_try = 0;
603         time_t now = time(NULL);
604
605         for(node = edge_weight_tree->head; node; node = node->next) {
606                 e = node->data;
607
608                 if(e->to == myself)
609                         continue;
610
611                 if(sockaddrcmp_noport(from, &e->address)) {
612                         if(last_hard_try == now)
613                                 continue;
614                         hard = true;
615                 }
616
617                 if(!try_mac(e->to, pkt))
618                         continue;
619
620                 n = e->to;
621                 break;
622         }
623
624         if(hard)
625                 last_hard_try = now;
626
627         last_hard_try = now;
628         return n;
629 }
630
631 void handle_incoming_vpn_data(int sock, short events, void *data) {
632         vpn_packet_t pkt;
633         char *hostname;
634         sockaddr_t from;
635         socklen_t fromlen = sizeof from;
636         node_t *n;
637         int len;
638
639         len = recvfrom(sock, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen);
640
641         if(len <= 0 || len > MAXSIZE) {
642                 if(!sockwouldblock(sockerrno))
643                         logger(LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno));
644                 return;
645         }
646
647         pkt.len = len;
648
649         sockaddrunmap(&from);           /* Some braindead IPv6 implementations do stupid things. */
650
651         n = lookup_node_udp(&from);
652
653         if(!n) {
654                 n = try_harder(&from, &pkt);
655                 if(n)
656                         update_node_udp(n, &from);
657                 else ifdebug(PROTOCOL) {
658                         hostname = sockaddr2hostname(&from);
659                         logger(LOG_WARNING, "Received UDP packet from unknown source %s", hostname);
660                         free(hostname);
661                         return;
662                 }
663                 else
664                         return;
665         }
666
667         n->sock = (intptr_t)data;
668
669         receive_udppacket(n, &pkt);
670 }
671
672 void handle_device_data(int sock, short events, void *data) {
673         vpn_packet_t packet;
674
675         packet.priority = 0;
676
677         if(devops.read(&packet)) {
678                 myself->in_packets++;
679                 myself->in_bytes += packet.len;
680                 route(myself, &packet);
681         }
682 }