2 net.c -- most of the network code
3 Copyright (C) 1998,99 Ivo Timmermans <zarq@iname.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <arpa/inet.h>
26 #include <netinet/in.h>
30 #include <sys/signal.h>
31 #include <sys/socket.h>
33 #include <sys/types.h>
50 int total_tap_out = 0;
51 int total_socket_in = 0;
52 int total_socket_out = 0;
54 time_t last_ping_time = 0;
56 /* The global list of existing connections */
57 conn_list_t *conn_list = NULL;
58 conn_list_t *myself = NULL;
61 strip off the MAC adresses of an ethernet frame
63 void strip_mac_addresses(vpn_packet_t *p)
65 unsigned char tmp[MAXSIZE];
67 memcpy(tmp, p->data, p->len);
69 memcpy(p->data, &tmp[12], p->len);
74 reassemble MAC addresses
76 void add_mac_addresses(vpn_packet_t *p)
78 unsigned char tmp[MAXSIZE];
80 memcpy(&tmp[12], p->data, p->len);
82 tmp[0] = tmp[6] = 0xfe;
83 tmp[1] = tmp[7] = 0xfd;
84 *((ip_t*)(&tmp[2])) = (ip_t)(htonl(myself->vpn_ip));
85 *((ip_t*)(&tmp[8])) = *((ip_t*)(&tmp[26]));
86 memcpy(p->data, &tmp[0], p->len);
90 int xsend(conn_list_t *cl, void *packet)
95 do_encrypt((vpn_packet_t*)packet, &rp, cl->key);
96 rp.from = myself->vpn_ip;
99 syslog(LOG_ERR, "Sent %d bytes to %lx", rp.len, cl->vpn_ip);
101 if((r = send(cl->socket, (char*)&rp, rp.len, 0)) < 0)
103 syslog(LOG_ERR, "Error sending data: %m");
107 total_socket_out += r;
112 int xrecv(conn_list_t *cl, void *packet)
117 do_decrypt((real_packet_t*)packet, &vp, cl->key);
118 add_mac_addresses(&vp);
120 if((lenin = write(tap_fd, &vp, vp.len + sizeof(vp.len))) < 0)
121 syslog(LOG_ERR, "Can't write to tap device: %m");
123 total_tap_out += lenin;
129 add the given packet of size s to the
130 queue q, be it the send or receive queue
132 void add_queue(packet_queue_t **q, void *packet, size_t s)
137 syslog(LOG_DEBUG, "packet to queue: %d", s);
139 e = xmalloc(sizeof(*e));
140 e->packet = xmalloc(s);
141 memcpy(e->packet, packet, s);
145 *q = xmalloc(sizeof(**q));
146 (*q)->head = (*q)->tail = NULL;
149 e->next = NULL; /* We insert at the tail */
151 if((*q)->tail) /* Do we have a tail? */
153 (*q)->tail->next = e;
154 e->prev = (*q)->tail;
156 else /* No tail -> no head too */
166 /* Remove a queue element */
167 void del_queue(packet_queue_t **q, queue_element_t *e)
172 if(e->next) /* There is a successor, so we are not tail */
174 if(e->prev) /* There is a predecessor, so we are not head */
176 e->next->prev = e->prev;
177 e->prev->next = e->next;
179 else /* We are head */
181 e->next->prev = NULL;
182 (*q)->head = e->next;
185 else /* We are tail (or all alone!) */
187 if(e->prev) /* We are not alone :) */
189 e->prev->next = NULL;
190 (*q)->tail = e->prev;
204 flush a queue by calling function for
205 each packet, and removing it when that
206 returned a zero exit code
208 void flush_queue(conn_list_t *cl, packet_queue_t **pq,
209 int (*function)(conn_list_t*,void*))
211 queue_element_t *p, *next = NULL;
213 for(p = (*pq)->head; p != NULL; )
217 if(!function(cl, p->packet))
224 syslog(LOG_DEBUG, "queue flushed");
229 flush the send&recv queues
230 void because nothing goes wrong here, packets
231 remain in the queue if something goes wrong
233 void flush_queues(conn_list_t *cl)
239 syslog(LOG_DEBUG, "Flushing send queue for " IP_ADDR_S,
240 IP_ADDR_V(cl->vpn_ip));
241 flush_queue(cl, &(cl->sq), xsend);
247 syslog(LOG_DEBUG, "Flushing receive queue for " IP_ADDR_S,
248 IP_ADDR_V(cl->vpn_ip));
249 flush_queue(cl, &(cl->rq), xrecv);
255 send a packet to the given vpn ip.
257 int send_packet(ip_t to, vpn_packet_t *packet)
261 if((cl = lookup_conn(to)) == NULL)
265 syslog(LOG_NOTICE, "trying to look up " IP_ADDR_S " in connection list failed.",
268 for(cl = conn_list; cl != NULL && !cl->status.outgoing; cl = cl->next);
270 { /* No open outgoing connection has been found. */
272 syslog(LOG_NOTICE, "There is no remote host I can send this packet to.");
277 if(my_key_expiry <= time(NULL))
280 if(!cl->status.dataopen)
281 if(setup_vpn_connection(cl) < 0)
284 if(!cl->status.validkey)
286 add_queue(&(cl->sq), packet, packet->len + 2);
287 if(!cl->status.waitingforkey)
288 send_key_request(cl->vpn_ip); /* Keys should be sent to the host running the tincd */
292 if(!cl->status.active)
294 add_queue(&(cl->sq), packet, packet->len + 2);
296 syslog(LOG_INFO, IP_ADDR_S " is not ready, queueing packet.", IP_ADDR_V(cl->vpn_ip));
297 return 0; /* We don't want to mess up, do we? */
300 /* can we send it? can we? can we? huh? */
302 return xsend(cl, packet);
305 int send_broadcast(conn_list_t *cl, vpn_packet_t *packet)
309 for(p = cl; p != NULL; p = p->next)
310 if(send_packet(p->real_ip, packet) < 0)
312 syslog(LOG_ERR, "Could not send a broadcast packet to %08lx (%08lx): %m",
313 p->vpn_ip, p->real_ip);
314 break; /* FIXME: should retry later, and send a ping over the metaconnection. */
321 open the local ethertap device
323 int setup_tap_fd(void)
326 const char *tapfname;
329 if((cfg = get_config_val(tapdevice)) == NULL)
330 tapfname = "/dev/tap0";
332 tapfname = cfg->data.ptr;
334 if((nfd = open(tapfname, O_RDWR | O_NONBLOCK)) < 0)
336 syslog(LOG_ERR, "Could not open %s: %m", tapfname);
346 set up the socket that we listen on for incoming
349 int setup_listen_meta_socket(int port)
352 struct sockaddr_in a;
355 if((nfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
357 syslog(LOG_ERR, "Creating metasocket failed: %m");
361 if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
363 syslog(LOG_ERR, "setsockopt: %m");
367 flags = fcntl(nfd, F_GETFL);
368 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
370 syslog(LOG_ERR, "fcntl: %m");
374 memset(&a, 0, sizeof(a));
375 a.sin_family = AF_INET;
376 a.sin_port = htons(port);
377 a.sin_addr.s_addr = htonl(INADDR_ANY);
379 if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
381 syslog(LOG_ERR, "Can't bind to port %hd/tcp: %m", port);
387 syslog(LOG_ERR, "listen: %m");
395 setup the socket for incoming encrypted
398 int setup_vpn_in_socket(int port)
401 struct sockaddr_in a;
404 if((nfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
406 syslog(LOG_ERR, "Creating socket failed: %m");
410 if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
412 syslog(LOG_ERR, "setsockopt: %m");
416 flags = fcntl(nfd, F_GETFL);
417 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
419 syslog(LOG_ERR, "fcntl: %m");
423 memset(&a, 0, sizeof(a));
424 a.sin_family = AF_INET;
425 a.sin_port = htons(port);
426 a.sin_addr.s_addr = htonl(INADDR_ANY);
428 if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
430 syslog(LOG_ERR, "Can't bind to port %hd/udp: %m", port);
438 setup an outgoing meta (tcp) socket
440 int setup_outgoing_meta_socket(conn_list_t *cl)
443 struct sockaddr_in a;
446 if((cfg = get_config_val(upstreamport)) == NULL)
449 cl->port = cfg->data.val;
451 cl->meta_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
452 if(cl->meta_socket == -1)
454 syslog(LOG_ERR, "Creating socket failed: %m");
458 a.sin_family = AF_INET;
459 a.sin_port = htons(cl->port);
460 a.sin_addr.s_addr = htonl(cl->real_ip);
462 if(connect(cl->meta_socket, (struct sockaddr *)&a, sizeof(a)) == -1)
464 syslog(LOG_ERR, IP_ADDR_S ":%d: %m", IP_ADDR_V(cl->real_ip), cl->port);
468 flags = fcntl(cl->meta_socket, F_GETFL);
469 if(fcntl(cl->meta_socket, F_SETFL, flags | O_NONBLOCK) < 0)
471 syslog(LOG_ERR, "fcntl: %m");
475 cl->hostname = hostlookup(htonl(cl->real_ip));
477 syslog(LOG_INFO, "Connected to %s:%hd" , cl->hostname, cl->port);
483 setup an outgoing connection. It's not
484 necessary to also open an udp socket as
485 well, because the other host will initiate
486 an authentication sequence during which
487 we will do just that.
489 int setup_outgoing_connection(ip_t ip)
493 ncn = new_conn_list();
496 if(setup_outgoing_meta_socket(ncn) < 0)
498 syslog(LOG_ERR, "Could not set up a meta connection.");
499 free_conn_element(ncn);
503 ncn->status.meta = 1;
504 ncn->status.outgoing = 1;
505 ncn->next = conn_list;
512 set up the local sockets (listen only)
514 int setup_myself(void)
518 myself = new_conn_list();
520 if(!(cfg = get_config_val(myvpnip)))
522 syslog(LOG_ERR, "No value for my VPN IP given");
526 myself->vpn_ip = cfg->data.ip->ip;
527 myself->vpn_mask = cfg->data.ip->mask;
529 if(!(cfg = get_config_val(listenport)))
532 myself->port = cfg->data.val;
534 if((myself->meta_socket = setup_listen_meta_socket(myself->port)) < 0)
536 syslog(LOG_ERR, "Unable to set up a listening socket");
540 if((myself->socket = setup_vpn_in_socket(myself->port)) < 0)
542 syslog(LOG_ERR, "Unable to set up an incoming vpn data socket");
543 close(myself->meta_socket);
547 myself->status.active = 1;
549 syslog(LOG_NOTICE, "Ready: listening on port %d.", myself->port);
555 setup all initial network connections
557 int setup_network_connections(void)
561 if((cfg = get_config_val(pingtimeout)) == NULL)
564 timeout = cfg->data.val;
566 if(setup_tap_fd() < 0)
569 if(setup_myself() < 0)
572 if((cfg = get_config_val(upstreamip)) == NULL)
573 /* No upstream IP given, we're listen only. */
576 if(setup_outgoing_connection(cfg->data.ip->ip))
583 sigalrm_handler(int a)
586 static int seconds_till_retry;
588 cfg = get_config_val(upstreamip);
590 if(!setup_outgoing_connection(cfg->data.ip->ip))
592 signal(SIGALRM, SIG_IGN);
593 seconds_till_retry = 5;
597 signal(SIGALRM, sigalrm_handler);
598 seconds_till_retry += 5;
599 alarm(seconds_till_retry);
600 syslog(LOG_ERR, "Still failed to connect to other. Will retry in %d seconds.",
607 close all open network connections
609 void close_network_connections(void)
613 for(p = conn_list; p != NULL; p = p->next)
615 if(p->status.dataopen)
617 shutdown(p->socket, 0); /* No more receptions */
623 shutdown(p->meta_socket, 0); /* No more receptions */
624 close(p->meta_socket);
629 if(myself->status.active)
631 close(myself->meta_socket);
632 close(myself->socket);
638 syslog(LOG_NOTICE, "Terminating.");
644 create a data (udp) socket
646 int setup_vpn_connection(conn_list_t *cl)
649 struct sockaddr_in a;
652 syslog(LOG_DEBUG, "Opening UDP socket to " IP_ADDR_S, IP_ADDR_V(cl->real_ip));
654 nfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
657 syslog(LOG_ERR, "Creating data socket failed: %m");
661 a.sin_family = AF_INET;
662 a.sin_port = htons(cl->port);
663 a.sin_addr.s_addr = htonl(cl->real_ip);
665 if(connect(nfd, (struct sockaddr *)&a, sizeof(a)) == -1)
667 syslog(LOG_ERR, "Create connection to %08lx:%d failed: %m", ntohs(cl->real_ip),
672 flags = fcntl(nfd, F_GETFL);
673 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
675 syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, nfd);
680 cl->status.dataopen = 1;
686 handle an incoming tcp connect call and open
689 conn_list_t *create_new_connection(int sfd)
692 struct sockaddr_in ci;
693 int len = sizeof(ci);
697 if(getpeername(sfd, &ci, &len) < 0)
699 syslog(LOG_ERR, "Error: getpeername: %m");
703 p->hostname = hostlookup(ci.sin_addr.s_addr);
704 p->real_ip = ntohl(ci.sin_addr.s_addr);
705 p->meta_socket = sfd;
708 syslog(LOG_NOTICE, "Connection from %s:%d", p->hostname, htons(ci.sin_port));
710 if(send_basic_info(p) < 0)
720 put all file descriptors in an fd_set array
722 void build_fdset(fd_set *fs)
728 for(p = conn_list; p != NULL; p = p->next)
731 FD_SET(p->meta_socket, fs);
732 if(p->status.dataopen)
733 FD_SET(p->socket, fs);
736 FD_SET(myself->meta_socket, fs);
737 FD_SET(myself->socket, fs);
743 receive incoming data from the listening
744 udp socket and write it to the ethertap
745 device after being decrypted
747 int handle_incoming_vpn_data(conn_list_t *cl)
751 int x, l = sizeof(x);
754 if(getsockopt(cl->socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
756 syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, cl->socket);
761 syslog(LOG_ERR, "Incoming data socket error: %s", sys_errlist[x]);
766 lenin = recvfrom(cl->socket, &rp, MTU, 0, NULL, NULL);
769 syslog(LOG_ERR, "Receiving data failed: %m");
772 total_socket_in += lenin;
775 f = lookup_conn(rp.from);
777 syslog(LOG_DEBUG, "packet from " IP_ADDR_S " (len %d)",
778 IP_ADDR_V(rp.from), rp.len);
781 syslog(LOG_ERR, "Got packet from unknown source " IP_ADDR_S,
786 if(f->status.validkey)
790 add_queue(&(f->rq), &rp, rp.len);
791 if(!cl->status.waitingforkey)
792 send_key_request(rp.from);
795 if(my_key_expiry <= time(NULL))
803 terminate a connection and notify the other
804 end before closing the sockets
806 void terminate_connection(conn_list_t *cl)
809 if(cl->status.remove)
813 syslog(LOG_NOTICE, "Closing connection with %s.", cl->hostname);
815 if(cl->status.timeout)
817 else if(!cl->status.termreq)
822 close(cl->meta_socket);
824 if(cl->status.outgoing)
827 signal(SIGALRM, sigalrm_handler);
828 syslog(LOG_NOTICE, "Try to re-establish outgoing connection in 5 seconds.");
831 cl->status.remove = 1;
836 send out a ping request to all active
839 int send_broadcast_ping(void)
843 for(p = conn_list; p != NULL; p = p->next)
847 if(p->status.active && p->status.meta)
850 terminate_connection(p);
853 p->status.pinged = 1;
854 p->status.got_pong = 0;
859 last_ping_time = time(NULL);
865 end all connections that did not respond
866 to the ping probe in time
868 int check_dead_connections(void)
872 for(p = conn_list; p != NULL; p = p->next)
876 if(p->status.active && p->status.meta && p->status.pinged && !p->status.got_pong)
878 syslog(LOG_INFO, "%s (" IP_ADDR_S ") didn't respond to ping",
879 p->hostname, IP_ADDR_V(p->vpn_ip));
880 p->status.timeout = 1;
881 terminate_connection(p);
889 accept a new tcp connect and create a
892 int handle_new_meta_connection(conn_list_t *cl)
895 struct sockaddr client;
896 int nfd, len = sizeof(client);
898 if((nfd = accept(cl->meta_socket, &client, &len)) < 0)
900 syslog(LOG_ERR, "Accepting a new connection failed: %m");
904 if((ncn = create_new_connection(nfd)) == NULL)
908 syslog(LOG_NOTICE, "Closed attempted connection.");
912 ncn->status.meta = 1;
913 ncn->next = conn_list;
920 dispatch any incoming meta requests
922 int handle_incoming_meta_data(conn_list_t *cl)
924 int x, l = sizeof(x);
925 unsigned char tmp[1600];
929 if(getsockopt(cl->meta_socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
931 syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, cl->meta_socket);
936 syslog(LOG_ERR, "Metadata socket error: %s", sys_errlist[x]);
940 if(read(cl->meta_socket, &tmp, 1) <= 0)
942 syslog(LOG_ERR, "Receive failed: %m");
946 request = (int)(tmp[0]);
949 syslog(LOG_DEBUG, "got request %d", request);
951 if(request_handlers[request] == NULL)
952 syslog(LOG_ERR, "Unknown request %d.", request);
954 if(request_handlers[request](cl) < 0)
961 check all connections to see if anything
962 happened on their sockets
964 void check_network_activity(fd_set *f)
967 int x, l = sizeof(x);
969 for(p = conn_list; p != NULL; p = p->next)
974 if(p->status.dataopen)
975 if(FD_ISSET(p->socket, f))
978 The only thing that can happen to get us here is apparently an
979 error on this outgoing(!) UDP socket that isn't immediate (i.e.
980 something that will not trigger an error directly on send()).
981 I've once got here when it said `No route to host'.
983 getsockopt(p->socket, SOL_SOCKET, SO_ERROR, &x, &l);
984 syslog(LOG_ERR, "Outgoing data socket error: %s", sys_errlist[x]);
985 terminate_connection(p);
990 if(FD_ISSET(p->meta_socket, f))
991 if(handle_incoming_meta_data(p) < 0)
993 terminate_connection(p);
998 if(FD_ISSET(myself->socket, f))
999 handle_incoming_vpn_data(myself);
1001 if(FD_ISSET(myself->meta_socket, f))
1002 handle_new_meta_connection(myself);
1007 read, encrypt and send data that is
1008 available through the ethertap device
1010 void handle_tap_input(void)
1014 int ether_type, lenin;
1016 memset(&vp, 0, sizeof(vp));
1017 if((lenin = read(tap_fd, &vp, MTU)) <= 0)
1019 syslog(LOG_ERR, "Error while reading from tapdevice: %m");
1023 total_tap_in += lenin;
1025 ether_type = ntohs(*((unsigned short*)(&vp.data[12])));
1026 if(ether_type != 0x0800)
1029 syslog(LOG_INFO, "Non-IP ethernet frame %04x from " MAC_ADDR_S,
1030 ether_type, MAC_ADDR_V(vp.data[6]));
1037 syslog(LOG_INFO, "Dropping short packet");
1041 from = ntohl(*((unsigned long*)(&vp.data[26])));
1042 to = ntohl(*((unsigned long*)(&vp.data[30])));
1045 syslog(LOG_DEBUG, "An IP packet (%04x) for " IP_ADDR_S " from " IP_ADDR_S,
1046 ether_type, IP_ADDR_V(to), IP_ADDR_V(from));
1048 syslog(LOG_DEBUG, MAC_ADDR_S " to " MAC_ADDR_S,
1049 MAC_ADDR_V(vp.data[0]), MAC_ADDR_V(vp.data[6]));
1051 vp.len = (length_t)lenin - 2;
1053 strip_mac_addresses(&vp);
1055 send_packet(to, &vp);
1060 this is where it all happens...
1062 void main_loop(void)
1068 last_ping_time = time(NULL);
1072 tv.tv_sec = timeout;
1078 if((r = select(FD_SETSIZE, &fset, NULL, NULL, &tv)) < 0)
1080 if(errno == EINTR) /* because of alarm */
1082 syslog(LOG_ERR, "Error while waiting for input: %m");
1086 if(r == 0 || last_ping_time + timeout < time(NULL))
1087 /* Timeout... hm... something might be wrong. */
1089 check_dead_connections();
1090 send_broadcast_ping();
1094 check_network_activity(&fset);
1096 /* local tap data */
1097 if(FD_ISSET(tap_fd, &fset))