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);
73 reassemble MAC addresses
75 void add_mac_addresses(vpn_packet_t *p)
77 unsigned char tmp[MAXSIZE];
79 memcpy(&tmp[12], p->data, p->len);
81 tmp[0] = tmp[6] = 0xfe;
82 tmp[1] = tmp[7] = 0xfd;
83 *((ip_t*)(&tmp[2])) = (ip_t)(htonl(myself->vpn_ip));
84 *((ip_t*)(&tmp[8])) = *((ip_t*)(&tmp[26]));
85 memcpy(p->data, &tmp[0], p->len);
88 int xsend(conn_list_t *cl, void *packet)
93 do_encrypt((vpn_packet_t*)packet, &rp, cl->key);
94 rp.from = myself->vpn_ip;
97 syslog(LOG_ERR, "Sent %d bytes to %lx", rp.len, cl->vpn_ip);
99 if((r = send(cl->socket, (char*)&rp, rp.len, 0)) < 0)
101 syslog(LOG_ERR, "Error sending data: %m");
105 total_socket_out += r;
111 write as many bytes as possible to the tap
112 device, possibly in multiple turns.
114 int write_n(int fd, void *buf, size_t len)
120 if((r = write(fd, buf, len)) < 0)
130 int xrecv(conn_list_t *cl, void *packet)
135 do_decrypt((real_packet_t*)packet, &vp, cl->key);
136 add_mac_addresses(&vp);
138 if((lenin = write_n(tap_fd, &vp, vp.len + 2)) < 0)
139 syslog(LOG_ERR, "Can't write to tap device: %m");
141 total_tap_out += lenin;
147 add the given packet of size s to the
148 queue q, be it the send or receive queue
150 void add_queue(packet_queue_t **q, void *packet, size_t s)
152 queue_element_t *e, *p;
155 syslog(LOG_DEBUG, "packet to queue: %d", s);
157 e = xmalloc(sizeof(queue_element_t));
158 e->packet = xmalloc(s);
159 memcpy(e->packet, packet, s);
162 *q = xmalloc(sizeof(packet_queue_t));
163 (*q)->head = (*q)->tail = NULL;
168 if((*q)->tail != NULL)
169 (*q)->tail->next = e;
173 if((*q)->head == NULL)
178 flush a queue by calling function for
179 each packet, and removing it when that
180 returned a zero exit code
182 void flush_queue(conn_list_t *cl, packet_queue_t *pq,
183 int (*function)(conn_list_t*,void*))
185 queue_element_t *p, *prev = NULL, *next = NULL;
187 for(p = pq->head; p != NULL; )
192 if(!function(cl, p->packet))
213 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);
236 syslog(LOG_DEBUG, "Flushing receive queue for " IP_ADDR_S,
237 IP_ADDR_V(cl->vpn_ip));
238 flush_queue(cl, cl->rq, xrecv);
244 send a packet to the given vpn ip.
246 int send_packet(ip_t to, vpn_packet_t *packet)
250 if((cl = lookup_conn(to)) == NULL)
254 syslog(LOG_NOTICE, "trying to look up " IP_ADDR_S " in connection list failed.",
257 for(cl = conn_list; cl != NULL && !cl->status.outgoing; cl = cl->next);
259 { /* No open outgoing connection has been found. */
261 syslog(LOG_NOTICE, "There is no remote host I can send this packet to.");
267 if(my_key_expiry <= time(NULL))
271 if(!cl->status.dataopen)
272 if(setup_vpn_connection(cl) < 0)
276 if(!cl->status.validkey)
278 add_queue(&(cl->sq), packet, packet->len + 2);
279 if(!cl->status.waitingforkey)
280 send_key_request(to);
285 if(!cl->status.active)
287 add_queue(&(cl->sq), packet, packet->len + 2);
289 syslog(LOG_INFO, IP_ADDR_S " is not ready, queueing packet.", IP_ADDR_V(cl->vpn_ip));
290 return 0; /* We don't want to mess up, do we? */
293 /* can we send it? can we? can we? huh? */
295 return xsend(cl, packet);
298 int send_broadcast(conn_list_t *cl, vpn_packet_t *packet)
302 for(p = cl; p != NULL; p = p->next)
303 if(send_packet(p->real_ip, packet) < 0)
305 syslog(LOG_ERR, "Could not send a broadcast packet to %08lx (%08lx): %m",
306 p->vpn_ip, p->real_ip);
307 break; /* FIXME: should retry later, and send a ping over the metaconnection. */
314 open the local ethertap device
316 int setup_tap_fd(void)
319 const char *tapfname;
322 if((cfg = get_config_val(tapdevice)) == NULL)
323 tapfname = "/dev/tap0";
325 tapfname = cfg->data.ptr;
327 if((nfd = open(tapfname, O_RDWR | O_NONBLOCK)) < 0)
329 syslog(LOG_ERR, "Could not open %s: %m", tapfname);
338 set up the socket that we listen on for incoming
341 int setup_listen_meta_socket(int port)
344 struct sockaddr_in a;
347 if((nfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
349 syslog(LOG_ERR, "Creating metasocket failed: %m");
353 if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
355 syslog(LOG_ERR, "setsockopt: %m");
359 flags = fcntl(nfd, F_GETFL);
360 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
362 syslog(LOG_ERR, "fcntl: %m");
366 memset(&a, 0, sizeof(a));
367 a.sin_family = AF_INET;
368 a.sin_port = htons(port);
369 a.sin_addr.s_addr = htonl(INADDR_ANY);
371 if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
373 syslog(LOG_ERR, "Can't bind to port %hd/tcp: %m", port);
379 syslog(LOG_ERR, "listen: %m");
387 setup the socket for incoming encrypted
390 int setup_vpn_in_socket(int port)
393 struct sockaddr_in a;
396 if((nfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
398 syslog(LOG_ERR, "Creating socket failed: %m");
402 if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
404 syslog(LOG_ERR, "setsockopt: %m");
408 flags = fcntl(nfd, F_GETFL);
409 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
411 syslog(LOG_ERR, "fcntl: %m");
415 memset(&a, 0, sizeof(a));
416 a.sin_family = AF_INET;
417 a.sin_port = htons(port);
418 a.sin_addr.s_addr = htonl(INADDR_ANY);
420 if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
422 syslog(LOG_ERR, "Can't bind to port %hd/udp: %m", port);
430 setup an outgoing meta (tcp) socket
432 int setup_outgoing_meta_socket(conn_list_t *cl)
435 struct sockaddr_in a;
438 if((cfg = get_config_val(upstreamport)) == NULL)
441 cl->port = cfg->data.val;
443 cl->meta_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
444 if(cl->meta_socket == -1)
446 syslog(LOG_ERR, "Creating socket failed: %m");
450 a.sin_family = AF_INET;
451 a.sin_port = htons(cl->port);
452 a.sin_addr.s_addr = htonl(cl->real_ip);
454 if(connect(cl->meta_socket, (struct sockaddr *)&a, sizeof(a)) == -1)
456 syslog(LOG_ERR, IP_ADDR_S ":%d: %m", IP_ADDR_V(cl->real_ip), cl->port);
460 flags = fcntl(cl->meta_socket, F_GETFL);
461 if(fcntl(cl->meta_socket, F_SETFL, flags | O_NONBLOCK) < 0)
463 syslog(LOG_ERR, "fcntl: %m");
467 cl->hostname = hostlookup(htonl(cl->real_ip));
469 syslog(LOG_INFO, "Connected to %s:%hd" , cl->hostname, cl->port);
475 setup an outgoing connection. It's not
476 necessary to also open an udp socket as
477 well, because the other host will initiate
478 an authentication sequence during which
479 we will do just that.
481 int setup_outgoing_connection(ip_t ip)
485 ncn = new_conn_list();
488 if(setup_outgoing_meta_socket(ncn) < 0)
490 syslog(LOG_ERR, "Could not set up a meta connection.");
491 free_conn_element(ncn);
495 ncn->status.meta = 1;
496 ncn->status.outgoing = 1;
497 ncn->next = conn_list;
504 set up the local sockets (listen only)
506 int setup_myself(void)
510 myself = new_conn_list();
512 if(!(cfg = get_config_val(myvpnip)))
514 syslog(LOG_ERR, "No value for my VPN IP given");
518 myself->vpn_ip = cfg->data.ip->ip;
519 myself->vpn_mask = cfg->data.ip->mask;
521 if(!(cfg = get_config_val(listenport)))
524 myself->port = cfg->data.val;
526 if((myself->meta_socket = setup_listen_meta_socket(myself->port)) < 0)
528 syslog(LOG_ERR, "Unable to set up a listening socket");
532 if((myself->socket = setup_vpn_in_socket(myself->port)) < 0)
534 syslog(LOG_ERR, "Unable to set up an incoming vpn data socket");
535 close(myself->meta_socket);
539 myself->status.active = 1;
541 syslog(LOG_NOTICE, "Ready: listening on port %d.", myself->port);
547 setup all initial network connections
549 int setup_network_connections(void)
553 if((cfg = get_config_val(pingtimeout)) == NULL)
556 timeout = cfg->data.val;
558 if(setup_tap_fd() < 0)
561 if(setup_myself() < 0)
564 if((cfg = get_config_val(upstreamip)) == NULL)
565 /* No upstream IP given, we're listen only. */
568 if(setup_outgoing_connection(cfg->data.ip->ip))
575 sigalrm_handler(int a)
578 static int seconds_till_retry;
580 cfg = get_config_val(upstreamip);
582 if(!setup_outgoing_connection(cfg->data.ip->ip))
584 signal(SIGALRM, SIG_IGN);
585 seconds_till_retry = 5;
589 signal(SIGALRM, sigalrm_handler);
590 seconds_till_retry += 5;
591 alarm(seconds_till_retry);
592 syslog(LOG_ERR, "Still failed to connect to other. Will retry in %d seconds.",
598 close all open network connections
600 void close_network_connections(void)
604 for(p = conn_list; p != NULL; p = p->next)
606 if(p->status.dataopen)
608 shutdown(p->socket, 0); /* No more receptions */
614 shutdown(p->meta_socket, 0); /* No more receptions */
615 close(p->meta_socket);
620 if(myself->status.active)
622 close(myself->meta_socket);
623 close(myself->socket);
629 syslog(LOG_NOTICE, "Terminating.");
634 create a data (udp) socket
636 int setup_vpn_connection(conn_list_t *cl)
639 struct sockaddr_in a;
642 syslog(LOG_DEBUG, "Opening UDP socket to " IP_ADDR_S, IP_ADDR_V(cl->real_ip));
644 nfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
647 syslog(LOG_ERR, "Creating data socket failed: %m");
651 a.sin_family = AF_INET;
652 a.sin_port = htons(cl->port);
653 a.sin_addr.s_addr = htonl(cl->real_ip);
655 if(connect(nfd, (struct sockaddr *)&a, sizeof(a)) == -1)
657 syslog(LOG_ERR, "Create connection to %08lx:%d failed: %m", ntohs(cl->real_ip),
662 flags = fcntl(nfd, F_GETFL);
663 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
665 syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, nfd);
670 cl->status.dataopen = 1;
676 handle an incoming tcp connect call and open
679 conn_list_t *create_new_connection(int sfd)
682 struct sockaddr_in ci;
683 int len = sizeof(ci);
687 if(getpeername(sfd, &ci, &len) < 0)
689 syslog(LOG_ERR, "Error: getpeername: %m");
693 p->hostname = hostlookup(ci.sin_addr.s_addr);
694 p->real_ip = ntohl(ci.sin_addr.s_addr);
695 p->meta_socket = sfd;
698 syslog(LOG_NOTICE, "Connection from %s:%d", p->hostname, htons(ci.sin_port));
700 if(send_basic_info(p) < 0)
710 put all file descriptors in an fd_set array
712 void build_fdset(fd_set *fs)
718 for(p = conn_list; p != NULL; p = p->next)
721 FD_SET(p->meta_socket, fs);
722 if(p->status.dataopen)
723 FD_SET(p->socket, fs);
726 FD_SET(myself->meta_socket, fs);
727 FD_SET(myself->socket, fs);
732 receive incoming data from the listening
733 udp socket and write it to the ethertap
734 device after being decrypted
736 int handle_incoming_vpn_data(conn_list_t *cl)
740 int x, l = sizeof(x);
743 if(getsockopt(cl->socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
745 syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, cl->socket);
750 syslog(LOG_ERR, "Incoming data socket error: %s", sys_errlist[x]);
755 lenin = recvfrom(cl->socket, &rp, MTU, 0, NULL, NULL);
758 syslog(LOG_ERR, "Receiving data failed: %m");
761 total_socket_in += lenin;
764 f = lookup_conn(rp.from);
766 syslog(LOG_DEBUG, "packet from " IP_ADDR_S " (len %d)",
767 IP_ADDR_V(rp.from), rp.len);
770 syslog(LOG_ERR, "Got packet from unknown source " IP_ADDR_S,
775 if(f->status.validkey)
779 add_queue(&(f->rq), &rp, rp.len);
780 if(!cl->status.waitingforkey)
781 send_key_request(rp.from);
784 if(my_key_expiry <= time(NULL))
792 terminate a connection and notify the other
793 end before closing the sockets
795 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;
823 send out a ping request to all active
826 int send_broadcast_ping(void)
830 for(p = conn_list; p != NULL; p = p->next)
834 if(p->status.active && p->status.meta)
837 terminate_connection(p);
840 p->status.pinged = 1;
841 p->status.got_pong = 0;
846 last_ping_time = time(NULL);
852 end all connections that did not respond
853 to the ping probe in time
855 int check_dead_connections(void)
859 for(p = conn_list; p != NULL; p = p->next)
863 if(p->status.active && p->status.meta && p->status.pinged && !p->status.got_pong)
865 syslog(LOG_INFO, "%s (" IP_ADDR_S ") didn't respond to ping",
866 p->hostname, IP_ADDR_V(p->vpn_ip));
867 p->status.timeout = 1;
868 terminate_connection(p);
876 accept a new tcp connect and create a
879 int handle_new_meta_connection(conn_list_t *cl)
882 struct sockaddr client;
883 int nfd, len = sizeof(struct sockaddr);
885 if((nfd = accept(cl->meta_socket, &client, &len)) < 0)
887 syslog(LOG_ERR, "Accepting a new connection failed: %m");
891 if((ncn = create_new_connection(nfd)) == NULL)
895 syslog(LOG_NOTICE, "Closed attempted connection.");
899 ncn->status.meta = 1;
900 ncn->next = conn_list;
907 dispatch any incoming meta requests
909 int handle_incoming_meta_data(conn_list_t *cl)
911 int x, l = sizeof(x), lenin;
912 unsigned char tmp[1600];
915 if(getsockopt(cl->meta_socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
917 syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, cl->meta_socket);
922 syslog(LOG_ERR, "Metadata socket error: %s", sys_errlist[x]);
926 if((lenin = recv(cl->meta_socket, &tmp, sizeof(tmp), 0)) <= 0)
928 syslog(LOG_ERR, "Receive failed: %m");
932 request = (int)(tmp[0]);
935 syslog(LOG_DEBUG, "got request %d", request);
937 if(request_handlers[request] == NULL)
938 syslog(LOG_ERR, "Unknown request %d.", request);
940 if(request_handlers[request](cl, tmp, lenin) < 0)
947 check all connections to see if anything
948 happened on their sockets
950 void check_network_activity(fd_set *f)
953 int x, l = sizeof(x);
955 for(p = conn_list; p != NULL; p = p->next)
961 if(FD_ISSET(p->socket, f))
964 The only thing that can happen to get us here is apparently an
965 error on this outgoing(!) UDP socket that isn't immediate (i.e.
966 something that will not trigger an error directly on send()).
967 I've once got here when it said `No route to host'.
969 getsockopt(p->socket, SOL_SOCKET, SO_ERROR, &x, &l);
970 syslog(LOG_ERR, "Outgoing data socket error: %s", sys_errlist[x]);
971 terminate_connection(p);
976 if(FD_ISSET(p->meta_socket, f))
977 if(handle_incoming_meta_data(p) < 0)
979 terminate_connection(p);
986 if(FD_ISSET(myself->socket, f))
987 handle_incoming_vpn_data(myself);
989 if(FD_ISSET(myself->meta_socket, f))
990 handle_new_meta_connection(myself);
995 read, encrypt and send data that is
996 available through the ethertap device
998 void handle_tap_input(void)
1002 int ether_type, lenin;
1004 memset(&vp, 0, sizeof(vp));
1005 if((lenin = read(tap_fd, &vp, MTU)) <= 0)
1007 syslog(LOG_ERR, "Error while reading from tapdevice: %m");
1011 total_tap_in += lenin;
1013 ether_type = ntohs(*((unsigned short*)(&vp.data[12])));
1014 if(ether_type != 0x0800)
1017 syslog(LOG_INFO, "Non-IP ethernet frame %04x from " MAC_ADDR_S,
1018 ether_type, MAC_ADDR_V(vp.data[6]));
1025 syslog(LOG_INFO, "Dropping short packet");
1029 from = ntohl(*((unsigned long*)(&vp.data[26])));
1030 to = ntohl(*((unsigned long*)(&vp.data[30])));
1033 syslog(LOG_DEBUG, "An IP packet (%04x) for " IP_ADDR_S " from " IP_ADDR_S,
1034 ether_type, IP_ADDR_V(to), IP_ADDR_V(from));
1036 syslog(LOG_DEBUG, MAC_ADDR_S " to " MAC_ADDR_S,
1037 MAC_ADDR_V(vp.data[0]), MAC_ADDR_V(vp.data[6]));
1039 vp.len = (length_t)lenin - 2;
1041 strip_mac_addresses(&vp);
1043 send_packet(to, &vp);
1048 this is where it al happens...
1050 void main_loop(void)
1056 last_ping_time = time(NULL);
1060 tv.tv_sec = timeout;
1069 if((r = select(FD_SETSIZE, &fset, NULL, NULL, &tv)) < 0)
1071 if(errno == EINTR) /* because of alarm */
1073 syslog(LOG_ERR, "Error while waiting for input: %m");
1078 if(r == 0 || last_ping_time + timeout < time(NULL))
1079 /* Timeout... hm... something might be wrong. */
1081 check_dead_connections();
1082 send_broadcast_ping();
1087 check_network_activity(&fset);
1090 /* local tap data */
1091 if(FD_ISSET(tap_fd, &fset))