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);
260 syslog(LOG_ERR, "zxnrbl");
266 if(my_key_expiry <= time(NULL))
270 if(!cl->status.dataopen)
271 if(setup_vpn_connection(cl) < 0)
275 if(!cl->status.validkey)
277 add_queue(&(cl->sq), packet, packet->len + 2);
278 if(!cl->status.waitingforkey)
279 send_key_request(to);
284 if(!cl->status.active)
286 add_queue(&(cl->sq), packet, packet->len + 2);
288 syslog(LOG_INFO, IP_ADDR_S " is not ready, queueing packet.", IP_ADDR_V(cl->vpn_ip));
289 return 0; /* We don't want to mess up, do we? */
292 /* can we send it? can we? can we? huh? */
294 return xsend(cl, packet);
297 int send_broadcast(conn_list_t *cl, vpn_packet_t *packet)
301 for(p = cl; p != NULL; p = p->next)
302 if(send_packet(p->real_ip, packet) < 0)
304 syslog(LOG_ERR, "Could not send a broadcast packet to %08lx (%08lx): %m",
305 p->vpn_ip, p->real_ip);
306 break; /* FIXME: should retry later, and send a ping over the metaconnection. */
313 open the local ethertap device
315 int setup_tap_fd(void)
318 const char *tapfname;
321 if((cfg = get_config_val(tapdevice)) == NULL)
322 tapfname = "/dev/tap0";
324 tapfname = cfg->data.ptr;
326 if((nfd = open(tapfname, O_RDWR | O_NONBLOCK)) < 0)
328 syslog(LOG_ERR, "Could not open %s: %m", tapfname);
337 set up the socket that we listen on for incoming
340 int setup_listen_meta_socket(int port)
343 struct sockaddr_in a;
346 if((nfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
348 syslog(LOG_ERR, "Creating metasocket failed: %m");
352 if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
354 syslog(LOG_ERR, "setsockopt: %m");
358 flags = fcntl(nfd, F_GETFL);
359 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
361 syslog(LOG_ERR, "fcntl: %m");
365 memset(&a, 0, sizeof(a));
366 a.sin_family = AF_INET;
367 a.sin_port = htons(port);
368 a.sin_addr.s_addr = htonl(INADDR_ANY);
370 if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
372 syslog(LOG_ERR, "Can't bind to port %hd/tcp: %m", port);
378 syslog(LOG_ERR, "listen: %m");
386 setup the socket for incoming encrypted
389 int setup_vpn_in_socket(int port)
392 struct sockaddr_in a;
395 if((nfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
397 syslog(LOG_ERR, "Creating socket failed: %m");
401 if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
403 syslog(LOG_ERR, "setsockopt: %m");
407 flags = fcntl(nfd, F_GETFL);
408 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
410 syslog(LOG_ERR, "fcntl: %m");
414 memset(&a, 0, sizeof(a));
415 a.sin_family = AF_INET;
416 a.sin_port = htons(port);
417 a.sin_addr.s_addr = htonl(INADDR_ANY);
419 if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
421 syslog(LOG_ERR, "Can't bind to port %hd/udp: %m", port);
429 setup an outgoing meta (tcp) socket
431 int setup_outgoing_meta_socket(conn_list_t *cl)
434 struct sockaddr_in a;
437 if((cfg = get_config_val(upstreamport)) == NULL)
440 cl->port = cfg->data.val;
442 cl->meta_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
443 if(cl->meta_socket == -1)
445 syslog(LOG_ERR, "Creating socket failed: %m");
449 a.sin_family = AF_INET;
450 a.sin_port = htons(cl->port);
451 a.sin_addr.s_addr = htonl(cl->real_ip);
453 if(connect(cl->meta_socket, (struct sockaddr *)&a, sizeof(a)) == -1)
455 syslog(LOG_ERR, IP_ADDR_S ":%d: %m", IP_ADDR_V(cl->real_ip), cl->port);
459 flags = fcntl(cl->meta_socket, F_GETFL);
460 if(fcntl(cl->meta_socket, F_SETFL, flags | O_NONBLOCK) < 0)
462 syslog(LOG_ERR, "fcntl: %m");
466 cl->hostname = hostlookup(htonl(cl->real_ip));
468 syslog(LOG_INFO, "Connected to %s:%hd" , cl->hostname, cl->port);
474 setup an outgoing connection. It's not
475 necessary to also open an udp socket as
476 well, because the other host will initiate
477 an authentication sequence during which
478 we will do just that.
480 int setup_outgoing_connection(ip_t ip)
484 ncn = new_conn_list();
487 if(setup_outgoing_meta_socket(ncn) < 0)
489 syslog(LOG_ERR, "Could not set up a meta connection.");
490 free_conn_element(ncn);
494 ncn->status.meta = 1;
495 ncn->status.outgoing = 1;
496 ncn->next = conn_list;
503 set up the local sockets (listen only)
505 int setup_myself(void)
509 myself = new_conn_list();
511 if(!(cfg = get_config_val(myvpnip)))
513 syslog(LOG_ERR, "No value for my VPN IP given");
517 myself->vpn_ip = cfg->data.ip->ip;
518 myself->vpn_mask = cfg->data.ip->mask;
520 if(!(cfg = get_config_val(listenport)))
523 myself->port = cfg->data.val;
525 if((myself->meta_socket = setup_listen_meta_socket(myself->port)) < 0)
527 syslog(LOG_ERR, "Unable to set up a listening socket");
531 if((myself->socket = setup_vpn_in_socket(myself->port)) < 0)
533 syslog(LOG_ERR, "Unable to set up an incoming vpn data socket");
534 close(myself->meta_socket);
538 myself->status.active = 1;
540 syslog(LOG_NOTICE, "Ready: listening on port %d.", myself->port);
546 setup all initial network connections
548 int setup_network_connections(void)
552 if((cfg = get_config_val(pingtimeout)) == NULL)
555 timeout = cfg->data.val;
557 if(setup_tap_fd() < 0)
560 if(setup_myself() < 0)
563 if((cfg = get_config_val(upstreamip)) == NULL)
564 /* No upstream IP given, we're listen only. */
567 if(setup_outgoing_connection(cfg->data.ip->ip))
574 sigalrm_handler(int a)
577 static int seconds_till_retry;
579 cfg = get_config_val(upstreamip);
581 if(!setup_outgoing_connection(cfg->data.ip->ip))
583 signal(SIGALRM, SIG_IGN);
584 seconds_till_retry = 5;
588 signal(SIGALRM, sigalrm_handler);
589 seconds_till_retry += 5;
590 alarm(seconds_till_retry);
591 syslog(LOG_ERR, "Still failed to connect to other. Will retry in %d seconds.",
597 close all open network connections
599 void close_network_connections(void)
603 for(p = conn_list; p != NULL; p = p->next)
605 if(p->status.dataopen)
607 shutdown(p->socket, 0); /* No more receptions */
613 shutdown(p->meta_socket, 0); /* No more receptions */
614 close(p->meta_socket);
619 if(myself->status.active)
621 close(myself->meta_socket);
622 close(myself->socket);
628 syslog(LOG_NOTICE, "Terminating.");
633 create a data (udp) socket
635 int setup_vpn_connection(conn_list_t *cl)
638 struct sockaddr_in a;
641 syslog(LOG_DEBUG, "Opening UDP socket to " IP_ADDR_S, IP_ADDR_V(cl->real_ip));
643 nfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
646 syslog(LOG_ERR, "Creating data socket failed: %m");
650 a.sin_family = AF_INET;
651 a.sin_port = htons(cl->port);
652 a.sin_addr.s_addr = htonl(cl->real_ip);
654 if(connect(nfd, (struct sockaddr *)&a, sizeof(a)) == -1)
656 syslog(LOG_ERR, "Create connection to %08lx:%d failed: %m", ntohs(cl->real_ip),
661 flags = fcntl(nfd, F_GETFL);
662 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
664 syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, nfd);
669 cl->status.dataopen = 1;
675 handle an incoming tcp connect call and open
678 conn_list_t *create_new_connection(int sfd)
681 struct sockaddr_in ci;
682 int len = sizeof(ci);
686 if(getpeername(sfd, &ci, &len) < 0)
688 syslog(LOG_ERR, "Error: getpeername: %m");
692 p->hostname = hostlookup(ci.sin_addr.s_addr);
693 p->real_ip = ntohl(ci.sin_addr.s_addr);
694 p->meta_socket = sfd;
697 syslog(LOG_NOTICE, "Connection from %s:%d", p->hostname, htons(ci.sin_port));
699 if(send_basic_info(p) < 0)
709 put all file descriptors in an fd_set array
711 void build_fdset(fd_set *fs)
717 for(p = conn_list; p != NULL; p = p->next)
720 FD_SET(p->meta_socket, fs);
721 if(p->status.dataopen)
722 FD_SET(p->socket, fs);
725 FD_SET(myself->meta_socket, fs);
726 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)
796 if(cl->status.remove)
800 syslog(LOG_NOTICE, "Closing connection with %s.", cl->hostname);
802 if(cl->status.timeout)
804 else if(!cl->status.termreq)
809 close(cl->meta_socket);
811 if(cl->status.outgoing)
814 signal(SIGALRM, sigalrm_handler);
815 syslog(LOG_NOTICE, "Try to re-establish outgoing connection in 5 seconds.");
818 cl->status.remove = 1;
822 send out a ping request to all active
825 int send_broadcast_ping(void)
829 for(p = conn_list; p != NULL; p = p->next)
833 if(p->status.active && p->status.meta)
836 terminate_connection(p);
839 p->status.pinged = 1;
840 p->status.got_pong = 0;
845 last_ping_time = time(NULL);
851 end all connections that did not respond
852 to the ping probe in time
854 int check_dead_connections(void)
858 for(p = conn_list; p != NULL; p = p->next)
862 if(p->status.active && p->status.meta && p->status.pinged && !p->status.got_pong)
864 syslog(LOG_INFO, "%s (" IP_ADDR_S ") didn't respond to ping",
865 p->hostname, IP_ADDR_V(p->vpn_ip));
866 p->status.timeout = 1;
867 terminate_connection(p);
875 accept a new tcp connect and create a
878 int handle_new_meta_connection(conn_list_t *cl)
881 struct sockaddr client;
882 int nfd, len = sizeof(struct sockaddr);
884 if((nfd = accept(cl->meta_socket, &client, &len)) < 0)
886 syslog(LOG_ERR, "Accepting a new connection failed: %m");
890 if((ncn = create_new_connection(nfd)) == NULL)
894 syslog(LOG_NOTICE, "Closed attempted connection.");
898 ncn->status.meta = 1;
899 ncn->next = conn_list;
906 dispatch any incoming meta requests
908 int handle_incoming_meta_data(conn_list_t *cl)
910 int x, l = sizeof(x), lenin;
911 unsigned char tmp[1600];
914 if(getsockopt(cl->meta_socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
916 syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, cl->meta_socket);
921 syslog(LOG_ERR, "Metadata socket error: %s", sys_errlist[x]);
925 if((lenin = recv(cl->meta_socket, &tmp, sizeof(tmp), 0)) <= 0)
927 syslog(LOG_ERR, "Receive failed: %m");
931 request = (int)(tmp[0]);
934 syslog(LOG_DEBUG, "got request %d", request);
936 if(request_handlers[request] == NULL)
937 syslog(LOG_ERR, "Unknown request %d.", request);
939 if(request_handlers[request](cl, tmp, lenin) < 0)
946 check all connections to see if anything
947 happened on their sockets
949 void check_network_activity(fd_set *f)
952 int x, l = sizeof(x);
954 for(p = conn_list; p != NULL; p = p->next)
960 if(FD_ISSET(p->socket, f))
963 The only thing that can happen to get us here is apparently an
964 error on this outgoing(!) UDP socket that isn't immediate (i.e.
965 something that will not trigger an error directly on send()).
966 I've once got here when it said `No route to host'.
968 getsockopt(p->socket, SOL_SOCKET, SO_ERROR, &x, &l);
969 syslog(LOG_ERR, "Outgoing data socket error: %s", sys_errlist[x]);
970 terminate_connection(p);
975 if(FD_ISSET(p->meta_socket, f))
976 if(handle_incoming_meta_data(p) < 0)
978 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;
1068 if((r = select(FD_SETSIZE, &fset, NULL, NULL, &tv)) < 0)
1070 if(errno == EINTR) /* because of alarm */
1072 syslog(LOG_ERR, "Error while waiting for input: %m");
1077 if(r == 0 || last_ping_time + timeout < time(NULL))
1078 /* Timeout... hm... something might be wrong. */
1080 check_dead_connections();
1081 send_broadcast_ping();
1086 check_network_activity(&fset);
1089 /* local tap data */
1090 if(FD_ISSET(tap_fd, &fset))