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;
113 write as many bytes as possible to the tap
114 device, possibly in multiple turns.
116 int write_n(int fd, void *buf, size_t len)
122 if((r = write(fd, buf, len)) < 0)
133 int xrecv(conn_list_t *cl, void *packet)
138 do_decrypt((real_packet_t*)packet, &vp, cl->key);
139 add_mac_addresses(&vp);
141 if((lenin = write_n(tap_fd, &vp, vp.len + 2)) < 0)
142 syslog(LOG_ERR, "Can't write to tap device: %m");
144 total_tap_out += lenin;
150 add the given packet of size s to the
151 queue q, be it the send or receive queue
153 void add_queue(packet_queue_t **q, void *packet, size_t s)
155 queue_element_t *e, *p;
158 syslog(LOG_DEBUG, "packet to queue: %d", s);
160 e = xmalloc(sizeof(queue_element_t));
161 e->packet = xmalloc(s);
162 memcpy(e->packet, packet, s);
165 *q = xmalloc(sizeof(packet_queue_t));
166 (*q)->head = (*q)->tail = NULL;
171 if((*q)->tail != NULL)
172 (*q)->tail->next = e;
176 if((*q)->head == NULL)
182 flush a queue by calling function for
183 each packet, and removing it when that
184 returned a zero exit code
186 void flush_queue(conn_list_t *cl, packet_queue_t *pq,
187 int (*function)(conn_list_t*,void*))
189 queue_element_t *p, *prev = NULL, *next = NULL;
191 for(p = pq->head; p != NULL; )
195 if(!function(cl, p->packet))
212 syslog(LOG_DEBUG, "queue flushed");
217 flush the send&recv queues
218 void because nothing goes wrong here, packets
219 remain in the queue if something goes wrong
221 void flush_queues(conn_list_t *cl)
227 syslog(LOG_DEBUG, "Flushing send queue for " IP_ADDR_S,
228 IP_ADDR_V(cl->vpn_ip));
229 flush_queue(cl, cl->sq, xsend);
235 syslog(LOG_DEBUG, "Flushing receive queue for " IP_ADDR_S,
236 IP_ADDR_V(cl->vpn_ip));
237 flush_queue(cl, cl->rq, xrecv);
243 send a packet to the given vpn ip.
245 int send_packet(ip_t to, vpn_packet_t *packet)
249 if((cl = lookup_conn(to)) == NULL)
253 syslog(LOG_NOTICE, "trying to look up " IP_ADDR_S " in connection list failed.",
256 for(cl = conn_list; cl != NULL && !cl->status.outgoing; cl = cl->next);
258 { /* No open outgoing connection has been found. */
260 syslog(LOG_NOTICE, "There is no remote host I can send this packet to.");
265 if(my_key_expiry <= time(NULL))
268 if(!cl->status.dataopen)
269 if(setup_vpn_connection(cl) < 0)
272 if(!cl->status.validkey)
274 add_queue(&(cl->sq), packet, packet->len + 2);
275 if(!cl->status.waitingforkey)
276 send_key_request(to);
280 if(!cl->status.active)
282 add_queue(&(cl->sq), packet, packet->len + 2);
284 syslog(LOG_INFO, IP_ADDR_S " is not ready, queueing packet.", IP_ADDR_V(cl->vpn_ip));
285 return 0; /* We don't want to mess up, do we? */
288 /* can we send it? can we? can we? huh? */
290 return xsend(cl, packet);
293 int send_broadcast(conn_list_t *cl, vpn_packet_t *packet)
297 for(p = cl; p != NULL; p = p->next)
298 if(send_packet(p->real_ip, packet) < 0)
300 syslog(LOG_ERR, "Could not send a broadcast packet to %08lx (%08lx): %m",
301 p->vpn_ip, p->real_ip);
302 break; /* FIXME: should retry later, and send a ping over the metaconnection. */
309 open the local ethertap device
311 int setup_tap_fd(void)
314 const char *tapfname;
317 if((cfg = get_config_val(tapdevice)) == NULL)
318 tapfname = "/dev/tap0";
320 tapfname = cfg->data.ptr;
322 if((nfd = open(tapfname, O_RDWR | O_NONBLOCK)) < 0)
324 syslog(LOG_ERR, "Could not open %s: %m", tapfname);
334 set up the socket that we listen on for incoming
337 int setup_listen_meta_socket(int port)
340 struct sockaddr_in a;
343 if((nfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
345 syslog(LOG_ERR, "Creating metasocket failed: %m");
349 if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
351 syslog(LOG_ERR, "setsockopt: %m");
355 flags = fcntl(nfd, F_GETFL);
356 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
358 syslog(LOG_ERR, "fcntl: %m");
362 memset(&a, 0, sizeof(a));
363 a.sin_family = AF_INET;
364 a.sin_port = htons(port);
365 a.sin_addr.s_addr = htonl(INADDR_ANY);
367 if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
369 syslog(LOG_ERR, "Can't bind to port %hd/tcp: %m", port);
375 syslog(LOG_ERR, "listen: %m");
383 setup the socket for incoming encrypted
386 int setup_vpn_in_socket(int port)
389 struct sockaddr_in a;
392 if((nfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
394 syslog(LOG_ERR, "Creating socket failed: %m");
398 if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
400 syslog(LOG_ERR, "setsockopt: %m");
404 flags = fcntl(nfd, F_GETFL);
405 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
407 syslog(LOG_ERR, "fcntl: %m");
411 memset(&a, 0, sizeof(a));
412 a.sin_family = AF_INET;
413 a.sin_port = htons(port);
414 a.sin_addr.s_addr = htonl(INADDR_ANY);
416 if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
418 syslog(LOG_ERR, "Can't bind to port %hd/udp: %m", port);
426 setup an outgoing meta (tcp) socket
428 int setup_outgoing_meta_socket(conn_list_t *cl)
431 struct sockaddr_in a;
434 if((cfg = get_config_val(upstreamport)) == NULL)
437 cl->port = cfg->data.val;
439 cl->meta_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
440 if(cl->meta_socket == -1)
442 syslog(LOG_ERR, "Creating socket failed: %m");
446 a.sin_family = AF_INET;
447 a.sin_port = htons(cl->port);
448 a.sin_addr.s_addr = htonl(cl->real_ip);
450 if(connect(cl->meta_socket, (struct sockaddr *)&a, sizeof(a)) == -1)
452 syslog(LOG_ERR, IP_ADDR_S ":%d: %m", IP_ADDR_V(cl->real_ip), cl->port);
456 flags = fcntl(cl->meta_socket, F_GETFL);
457 if(fcntl(cl->meta_socket, F_SETFL, flags | O_NONBLOCK) < 0)
459 syslog(LOG_ERR, "fcntl: %m");
463 cl->hostname = hostlookup(htonl(cl->real_ip));
465 syslog(LOG_INFO, "Connected to %s:%hd" , cl->hostname, cl->port);
471 setup an outgoing connection. It's not
472 necessary to also open an udp socket as
473 well, because the other host will initiate
474 an authentication sequence during which
475 we will do just that.
477 int setup_outgoing_connection(ip_t ip)
481 ncn = new_conn_list();
484 if(setup_outgoing_meta_socket(ncn) < 0)
486 syslog(LOG_ERR, "Could not set up a meta connection.");
487 free_conn_element(ncn);
491 ncn->status.meta = 1;
492 ncn->status.outgoing = 1;
493 ncn->next = conn_list;
500 set up the local sockets (listen only)
502 int setup_myself(void)
506 myself = new_conn_list();
508 if(!(cfg = get_config_val(myvpnip)))
510 syslog(LOG_ERR, "No value for my VPN IP given");
514 myself->vpn_ip = cfg->data.ip->ip;
515 myself->vpn_mask = cfg->data.ip->mask;
517 if(!(cfg = get_config_val(listenport)))
520 myself->port = cfg->data.val;
522 if((myself->meta_socket = setup_listen_meta_socket(myself->port)) < 0)
524 syslog(LOG_ERR, "Unable to set up a listening socket");
528 if((myself->socket = setup_vpn_in_socket(myself->port)) < 0)
530 syslog(LOG_ERR, "Unable to set up an incoming vpn data socket");
531 close(myself->meta_socket);
535 myself->status.active = 1;
537 syslog(LOG_NOTICE, "Ready: listening on port %d.", myself->port);
543 setup all initial network connections
545 int setup_network_connections(void)
549 if((cfg = get_config_val(pingtimeout)) == NULL)
552 timeout = cfg->data.val;
554 if(setup_tap_fd() < 0)
557 if(setup_myself() < 0)
560 if((cfg = get_config_val(upstreamip)) == NULL)
561 /* No upstream IP given, we're listen only. */
564 if(setup_outgoing_connection(cfg->data.ip->ip))
571 sigalrm_handler(int a)
574 static int seconds_till_retry;
576 cfg = get_config_val(upstreamip);
578 if(!setup_outgoing_connection(cfg->data.ip->ip))
580 signal(SIGALRM, SIG_IGN);
581 seconds_till_retry = 5;
585 signal(SIGALRM, sigalrm_handler);
586 seconds_till_retry += 5;
587 alarm(seconds_till_retry);
588 syslog(LOG_ERR, "Still failed to connect to other. Will retry in %d seconds.",
595 close all open network connections
597 void close_network_connections(void)
601 for(p = conn_list; p != NULL; p = p->next)
603 if(p->status.dataopen)
605 shutdown(p->socket, 0); /* No more receptions */
611 shutdown(p->meta_socket, 0); /* No more receptions */
612 close(p->meta_socket);
617 if(myself->status.active)
619 close(myself->meta_socket);
620 close(myself->socket);
626 syslog(LOG_NOTICE, "Terminating.");
632 create a data (udp) socket
634 int setup_vpn_connection(conn_list_t *cl)
637 struct sockaddr_in a;
640 syslog(LOG_DEBUG, "Opening UDP socket to " IP_ADDR_S, IP_ADDR_V(cl->real_ip));
642 nfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
645 syslog(LOG_ERR, "Creating data socket failed: %m");
649 a.sin_family = AF_INET;
650 a.sin_port = htons(cl->port);
651 a.sin_addr.s_addr = htonl(cl->real_ip);
653 if(connect(nfd, (struct sockaddr *)&a, sizeof(a)) == -1)
655 syslog(LOG_ERR, "Create connection to %08lx:%d failed: %m", ntohs(cl->real_ip),
660 flags = fcntl(nfd, F_GETFL);
661 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
663 syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, nfd);
668 cl->status.dataopen = 1;
674 handle an incoming tcp connect call and open
677 conn_list_t *create_new_connection(int sfd)
680 struct sockaddr_in ci;
681 int len = sizeof(ci);
685 if(getpeername(sfd, &ci, &len) < 0)
687 syslog(LOG_ERR, "Error: getpeername: %m");
691 p->hostname = hostlookup(ci.sin_addr.s_addr);
692 p->real_ip = ntohl(ci.sin_addr.s_addr);
693 p->meta_socket = sfd;
696 syslog(LOG_NOTICE, "Connection from %s:%d", p->hostname, htons(ci.sin_port));
698 if(send_basic_info(p) < 0)
708 put all file descriptors in an fd_set array
710 void build_fdset(fd_set *fs)
716 for(p = conn_list; p != NULL; p = p->next)
719 FD_SET(p->meta_socket, fs);
720 if(p->status.dataopen)
721 FD_SET(p->socket, fs);
724 FD_SET(myself->meta_socket, fs);
725 FD_SET(myself->socket, fs);
731 receive incoming data from the listening
732 udp socket and write it to the ethertap
733 device after being decrypted
735 int handle_incoming_vpn_data(conn_list_t *cl)
739 int x, l = sizeof(x);
742 if(getsockopt(cl->socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
744 syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, cl->socket);
749 syslog(LOG_ERR, "Incoming data socket error: %s", sys_errlist[x]);
754 lenin = recvfrom(cl->socket, &rp, MTU, 0, NULL, NULL);
757 syslog(LOG_ERR, "Receiving data failed: %m");
760 total_socket_in += lenin;
763 f = lookup_conn(rp.from);
765 syslog(LOG_DEBUG, "packet from " IP_ADDR_S " (len %d)",
766 IP_ADDR_V(rp.from), rp.len);
769 syslog(LOG_ERR, "Got packet from unknown source " IP_ADDR_S,
774 if(f->status.validkey)
778 add_queue(&(f->rq), &rp, rp.len);
779 if(!cl->status.waitingforkey)
780 send_key_request(rp.from);
783 if(my_key_expiry <= time(NULL))
791 terminate a connection and notify the other
792 end before closing the sockets
794 void terminate_connection(conn_list_t *cl)
797 if(cl->status.remove)
801 syslog(LOG_NOTICE, "Closing connection with %s.", cl->hostname);
803 if(cl->status.timeout)
805 else if(!cl->status.termreq)
810 close(cl->meta_socket);
812 if(cl->status.outgoing)
815 signal(SIGALRM, sigalrm_handler);
816 syslog(LOG_NOTICE, "Try to re-establish outgoing connection in 5 seconds.");
819 cl->status.remove = 1;
824 send out a ping request to all active
827 int send_broadcast_ping(void)
831 for(p = conn_list; p != NULL; p = p->next)
835 if(p->status.active && p->status.meta)
838 terminate_connection(p);
841 p->status.pinged = 1;
842 p->status.got_pong = 0;
847 last_ping_time = time(NULL);
853 end all connections that did not respond
854 to the ping probe in time
856 int check_dead_connections(void)
860 for(p = conn_list; p != NULL; p = p->next)
864 if(p->status.active && p->status.meta && p->status.pinged && !p->status.got_pong)
866 syslog(LOG_INFO, "%s (" IP_ADDR_S ") didn't respond to ping",
867 p->hostname, IP_ADDR_V(p->vpn_ip));
868 p->status.timeout = 1;
869 terminate_connection(p);
877 accept a new tcp connect and create a
880 int handle_new_meta_connection(conn_list_t *cl)
883 struct sockaddr client;
884 int nfd, len = sizeof(struct sockaddr);
886 if((nfd = accept(cl->meta_socket, &client, &len)) < 0)
888 syslog(LOG_ERR, "Accepting a new connection failed: %m");
892 if((ncn = create_new_connection(nfd)) == NULL)
896 syslog(LOG_NOTICE, "Closed attempted connection.");
900 ncn->status.meta = 1;
901 ncn->next = conn_list;
908 dispatch any incoming meta requests
910 int handle_incoming_meta_data(conn_list_t *cl)
912 int x, l = sizeof(x), lenin;
913 unsigned char tmp[1600];
916 if(getsockopt(cl->meta_socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
918 syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, cl->meta_socket);
923 syslog(LOG_ERR, "Metadata socket error: %s", sys_errlist[x]);
927 if((lenin = recv(cl->meta_socket, &tmp, sizeof(tmp), 0)) <= 0)
929 syslog(LOG_ERR, "Receive failed: %m");
933 request = (int)(tmp[0]);
936 syslog(LOG_DEBUG, "got request %d", request);
938 if(request_handlers[request] == NULL)
939 syslog(LOG_ERR, "Unknown request %d.", request);
941 if(request_handlers[request](cl, tmp, lenin) < 0)
948 check all connections to see if anything
949 happened on their sockets
951 void check_network_activity(fd_set *f)
954 int x, l = sizeof(x);
956 for(p = conn_list; p != NULL; p = p->next)
962 if(FD_ISSET(p->socket, f))
965 The only thing that can happen to get us here is apparently an
966 error on this outgoing(!) UDP socket that isn't immediate (i.e.
967 something that will not trigger an error directly on send()).
968 I've once got here when it said `No route to host'.
970 getsockopt(p->socket, SOL_SOCKET, SO_ERROR, &x, &l);
971 syslog(LOG_ERR, "Outgoing data socket error: %s", sys_errlist[x]);
972 terminate_connection(p);
977 if(FD_ISSET(p->meta_socket, f))
978 if(handle_incoming_meta_data(p) < 0)
980 terminate_connection(p);
985 if(FD_ISSET(myself->socket, f))
986 handle_incoming_vpn_data(myself);
988 if(FD_ISSET(myself->meta_socket, f))
989 handle_new_meta_connection(myself);
994 read, encrypt and send data that is
995 available through the ethertap device
997 void handle_tap_input(void)
1001 int ether_type, lenin;
1003 memset(&vp, 0, sizeof(vp));
1004 if((lenin = read(tap_fd, &vp, MTU)) <= 0)
1006 syslog(LOG_ERR, "Error while reading from tapdevice: %m");
1010 total_tap_in += lenin;
1012 ether_type = ntohs(*((unsigned short*)(&vp.data[12])));
1013 if(ether_type != 0x0800)
1016 syslog(LOG_INFO, "Non-IP ethernet frame %04x from " MAC_ADDR_S,
1017 ether_type, MAC_ADDR_V(vp.data[6]));
1024 syslog(LOG_INFO, "Dropping short packet");
1028 from = ntohl(*((unsigned long*)(&vp.data[26])));
1029 to = ntohl(*((unsigned long*)(&vp.data[30])));
1032 syslog(LOG_DEBUG, "An IP packet (%04x) for " IP_ADDR_S " from " IP_ADDR_S,
1033 ether_type, IP_ADDR_V(to), IP_ADDR_V(from));
1035 syslog(LOG_DEBUG, MAC_ADDR_S " to " MAC_ADDR_S,
1036 MAC_ADDR_V(vp.data[0]), MAC_ADDR_V(vp.data[6]));
1038 vp.len = (length_t)lenin - 2;
1040 strip_mac_addresses(&vp);
1042 send_packet(to, &vp);
1047 this is where it al happens...
1049 void main_loop(void)
1055 last_ping_time = time(NULL);
1059 tv.tv_sec = timeout;
1065 if((r = select(FD_SETSIZE, &fset, NULL, NULL, &tv)) < 0)
1067 if(errno == EINTR) /* because of alarm */
1069 syslog(LOG_ERR, "Error while waiting for input: %m");
1073 if(r == 0 || last_ping_time + timeout < time(NULL))
1074 /* Timeout... hm... something might be wrong. */
1076 check_dead_connections();
1077 send_broadcast_ping();
1081 check_network_activity(&fset);
1083 /* local tap data */
1084 if(FD_ISSET(tap_fd, &fset))