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 = htonl(myself->vpn_ip);
97 rp.data->len = htons(rp.data->len);
98 rp.len = htons(rp.data->len);
101 syslog(LOG_ERR, "Sent %d bytes to %lx", ntohs(rp.len), cl->vpn_ip);
103 if((r = send(cl->socket, (char*)&rp, ntohs(rp.len), 0)) < 0)
105 syslog(LOG_ERR, "Error sending data: %m");
109 total_socket_out += r;
114 int xrecv(conn_list_t *cl, void *packet)
119 packet->data->len = ntohs(packet->data->len);
120 packet->len = ntohs(packet->len);
121 packet->from = ntohl(packet->from);
123 do_decrypt((real_packet_t*)packet, &vp, cl->key);
124 add_mac_addresses(&vp);
126 if((lenin = write(tap_fd, &vp, vp.len + sizeof(vp.len))) < 0)
127 syslog(LOG_ERR, "Can't write to tap device: %m");
129 total_tap_out += lenin;
135 add the given packet of size s to the
136 queue q, be it the send or receive queue
138 void add_queue(packet_queue_t **q, void *packet, size_t s)
143 syslog(LOG_DEBUG, "packet to queue: %d", s);
145 e = xmalloc(sizeof(*e));
146 e->packet = xmalloc(s);
147 memcpy(e->packet, packet, s);
151 *q = xmalloc(sizeof(**q));
152 (*q)->head = (*q)->tail = NULL;
155 e->next = NULL; /* We insert at the tail */
157 if((*q)->tail) /* Do we have a tail? */
159 (*q)->tail->next = e;
160 e->prev = (*q)->tail;
162 else /* No tail -> no head too */
172 /* Remove a queue element */
173 void del_queue(packet_queue_t **q, queue_element_t *e)
178 if(e->next) /* There is a successor, so we are not tail */
180 if(e->prev) /* There is a predecessor, so we are not head */
182 e->next->prev = e->prev;
183 e->prev->next = e->next;
185 else /* We are head */
187 e->next->prev = NULL;
188 (*q)->head = e->next;
191 else /* We are tail (or all alone!) */
193 if(e->prev) /* We are not alone :) */
195 e->prev->next = NULL;
196 (*q)->tail = e->prev;
210 flush a queue by calling function for
211 each packet, and removing it when that
212 returned a zero exit code
214 void flush_queue(conn_list_t *cl, packet_queue_t **pq,
215 int (*function)(conn_list_t*,void*))
217 queue_element_t *p, *next = NULL;
219 for(p = (*pq)->head; p != NULL; )
223 if(!function(cl, p->packet))
230 syslog(LOG_DEBUG, "queue flushed");
235 flush the send&recv queues
236 void because nothing goes wrong here, packets
237 remain in the queue if something goes wrong
239 void flush_queues(conn_list_t *cl)
245 syslog(LOG_DEBUG, "Flushing send queue for " IP_ADDR_S,
246 IP_ADDR_V(cl->vpn_ip));
247 flush_queue(cl, &(cl->sq), xsend);
253 syslog(LOG_DEBUG, "Flushing receive queue for " IP_ADDR_S,
254 IP_ADDR_V(cl->vpn_ip));
255 flush_queue(cl, &(cl->rq), xrecv);
261 send a packet to the given vpn ip.
263 int send_packet(ip_t to, vpn_packet_t *packet)
267 if((cl = lookup_conn(to)) == NULL)
271 syslog(LOG_NOTICE, "trying to look up " IP_ADDR_S " in connection list failed.",
274 for(cl = conn_list; cl != NULL && !cl->status.outgoing; cl = cl->next);
276 { /* No open outgoing connection has been found. */
278 syslog(LOG_NOTICE, "There is no remote host I can send this packet to.");
283 if(my_key_expiry <= time(NULL))
286 if(!cl->status.dataopen)
287 if(setup_vpn_connection(cl) < 0)
290 if(!cl->status.validkey)
292 add_queue(&(cl->sq), packet, packet->len + 2);
293 if(!cl->status.waitingforkey)
294 send_key_request(cl->vpn_ip); /* Keys should be sent to the host running the tincd */
298 if(!cl->status.active)
300 add_queue(&(cl->sq), packet, packet->len + 2);
302 syslog(LOG_INFO, IP_ADDR_S " is not ready, queueing packet.", IP_ADDR_V(cl->vpn_ip));
303 return 0; /* We don't want to mess up, do we? */
306 /* can we send it? can we? can we? huh? */
308 return xsend(cl, packet);
311 int send_broadcast(conn_list_t *cl, vpn_packet_t *packet)
315 for(p = cl; p != NULL; p = p->next)
316 if(send_packet(p->real_ip, packet) < 0)
318 syslog(LOG_ERR, "Could not send a broadcast packet to %08lx (%08lx): %m",
319 p->vpn_ip, p->real_ip);
320 break; /* FIXME: should retry later, and send a ping over the metaconnection. */
327 open the local ethertap device
329 int setup_tap_fd(void)
332 const char *tapfname;
335 if((cfg = get_config_val(tapdevice)) == NULL)
336 tapfname = "/dev/tap0";
338 tapfname = cfg->data.ptr;
340 if((nfd = open(tapfname, O_RDWR | O_NONBLOCK)) < 0)
342 syslog(LOG_ERR, "Could not open %s: %m", tapfname);
352 set up the socket that we listen on for incoming
355 int setup_listen_meta_socket(int port)
358 struct sockaddr_in a;
361 if((nfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
363 syslog(LOG_ERR, "Creating metasocket failed: %m");
367 if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
369 syslog(LOG_ERR, "setsockopt: %m");
373 flags = fcntl(nfd, F_GETFL);
374 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
376 syslog(LOG_ERR, "fcntl: %m");
380 memset(&a, 0, sizeof(a));
381 a.sin_family = AF_INET;
382 a.sin_port = htons(port);
383 a.sin_addr.s_addr = htonl(INADDR_ANY);
385 if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
387 syslog(LOG_ERR, "Can't bind to port %hd/tcp: %m", port);
393 syslog(LOG_ERR, "listen: %m");
401 setup the socket for incoming encrypted
404 int setup_vpn_in_socket(int port)
407 struct sockaddr_in a;
410 if((nfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
412 syslog(LOG_ERR, "Creating socket failed: %m");
416 if(setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)))
418 syslog(LOG_ERR, "setsockopt: %m");
422 flags = fcntl(nfd, F_GETFL);
423 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
425 syslog(LOG_ERR, "fcntl: %m");
429 memset(&a, 0, sizeof(a));
430 a.sin_family = AF_INET;
431 a.sin_port = htons(port);
432 a.sin_addr.s_addr = htonl(INADDR_ANY);
434 if(bind(nfd, (struct sockaddr *)&a, sizeof(struct sockaddr)))
436 syslog(LOG_ERR, "Can't bind to port %hd/udp: %m", port);
444 setup an outgoing meta (tcp) socket
446 int setup_outgoing_meta_socket(conn_list_t *cl)
449 struct sockaddr_in a;
452 if((cfg = get_config_val(upstreamport)) == NULL)
455 cl->port = cfg->data.val;
457 cl->meta_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
458 if(cl->meta_socket == -1)
460 syslog(LOG_ERR, "Creating socket failed: %m");
464 a.sin_family = AF_INET;
465 a.sin_port = htons(cl->port);
466 a.sin_addr.s_addr = htonl(cl->real_ip);
468 if(connect(cl->meta_socket, (struct sockaddr *)&a, sizeof(a)) == -1)
470 syslog(LOG_ERR, IP_ADDR_S ":%d: %m", IP_ADDR_V(cl->real_ip), cl->port);
474 flags = fcntl(cl->meta_socket, F_GETFL);
475 if(fcntl(cl->meta_socket, F_SETFL, flags | O_NONBLOCK) < 0)
477 syslog(LOG_ERR, "fcntl: %m");
481 cl->hostname = hostlookup(htonl(cl->real_ip));
483 syslog(LOG_INFO, "Connected to %s:%hd" , cl->hostname, cl->port);
489 setup an outgoing connection. It's not
490 necessary to also open an udp socket as
491 well, because the other host will initiate
492 an authentication sequence during which
493 we will do just that.
495 int setup_outgoing_connection(ip_t ip)
499 ncn = new_conn_list();
502 if(setup_outgoing_meta_socket(ncn) < 0)
504 syslog(LOG_ERR, "Could not set up a meta connection.");
505 free_conn_element(ncn);
509 ncn->status.meta = 1;
510 ncn->status.outgoing = 1;
511 ncn->next = conn_list;
518 set up the local sockets (listen only)
520 int setup_myself(void)
524 myself = new_conn_list();
526 if(!(cfg = get_config_val(myvpnip)))
528 syslog(LOG_ERR, "No value for my VPN IP given");
532 myself->vpn_ip = cfg->data.ip->ip;
533 myself->vpn_mask = cfg->data.ip->mask;
535 if(!(cfg = get_config_val(listenport)))
538 myself->port = cfg->data.val;
540 if((myself->meta_socket = setup_listen_meta_socket(myself->port)) < 0)
542 syslog(LOG_ERR, "Unable to set up a listening socket");
546 if((myself->socket = setup_vpn_in_socket(myself->port)) < 0)
548 syslog(LOG_ERR, "Unable to set up an incoming vpn data socket");
549 close(myself->meta_socket);
553 myself->status.active = 1;
555 syslog(LOG_NOTICE, "Ready: listening on port %d.", myself->port);
561 setup all initial network connections
563 int setup_network_connections(void)
567 if((cfg = get_config_val(pingtimeout)) == NULL)
570 timeout = cfg->data.val;
572 if(setup_tap_fd() < 0)
575 if(setup_myself() < 0)
578 if((cfg = get_config_val(upstreamip)) == NULL)
579 /* No upstream IP given, we're listen only. */
582 if(setup_outgoing_connection(cfg->data.ip->ip))
589 sigalrm_handler(int a)
592 static int seconds_till_retry;
594 cfg = get_config_val(upstreamip);
596 if(!setup_outgoing_connection(cfg->data.ip->ip))
598 signal(SIGALRM, SIG_IGN);
599 seconds_till_retry = 5;
603 signal(SIGALRM, sigalrm_handler);
604 seconds_till_retry += 5;
605 alarm(seconds_till_retry);
606 syslog(LOG_ERR, "Still failed to connect to other. Will retry in %d seconds.",
613 close all open network connections
615 void close_network_connections(void)
619 for(p = conn_list; p != NULL; p = p->next)
621 if(p->status.dataopen)
623 shutdown(p->socket, 0); /* No more receptions */
629 shutdown(p->meta_socket, 0); /* No more receptions */
630 close(p->meta_socket);
635 if(myself->status.active)
637 close(myself->meta_socket);
638 close(myself->socket);
644 syslog(LOG_NOTICE, "Terminating.");
650 create a data (udp) socket
652 int setup_vpn_connection(conn_list_t *cl)
655 struct sockaddr_in a;
658 syslog(LOG_DEBUG, "Opening UDP socket to " IP_ADDR_S, IP_ADDR_V(cl->real_ip));
660 nfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
663 syslog(LOG_ERR, "Creating data socket failed: %m");
667 a.sin_family = AF_INET;
668 a.sin_port = htons(cl->port);
669 a.sin_addr.s_addr = htonl(cl->real_ip);
671 if(connect(nfd, (struct sockaddr *)&a, sizeof(a)) == -1)
673 syslog(LOG_ERR, "Create connection to %08lx:%d failed: %m", ntohs(cl->real_ip),
678 flags = fcntl(nfd, F_GETFL);
679 if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
681 syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, nfd);
686 cl->status.dataopen = 1;
692 handle an incoming tcp connect call and open
695 conn_list_t *create_new_connection(int sfd)
698 struct sockaddr_in ci;
699 int len = sizeof(ci);
703 if(getpeername(sfd, &ci, &len) < 0)
705 syslog(LOG_ERR, "Error: getpeername: %m");
709 p->hostname = hostlookup(ci.sin_addr.s_addr);
710 p->real_ip = ntohl(ci.sin_addr.s_addr);
711 p->meta_socket = sfd;
715 syslog(LOG_NOTICE, "Connection from %s:%d", p->hostname, htons(ci.sin_port));
717 if(send_basic_info(p) < 0)
727 put all file descriptors in an fd_set array
729 void build_fdset(fd_set *fs)
735 for(p = conn_list; p != NULL; p = p->next)
738 FD_SET(p->meta_socket, fs);
739 if(p->status.dataopen)
740 FD_SET(p->socket, fs);
743 FD_SET(myself->meta_socket, fs);
744 FD_SET(myself->socket, fs);
750 receive incoming data from the listening
751 udp socket and write it to the ethertap
752 device after being decrypted
754 int handle_incoming_vpn_data(conn_list_t *cl)
758 int x, l = sizeof(x);
761 if(getsockopt(cl->socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
763 syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, cl->socket);
768 syslog(LOG_ERR, "Incoming data socket error: %s", sys_errlist[x]);
773 lenin = recvfrom(cl->socket, &rp, MTU, 0, NULL, NULL);
776 syslog(LOG_ERR, "Receiving data failed: %m");
779 total_socket_in += lenin;
782 f = lookup_conn(rp.from);
784 syslog(LOG_DEBUG, "packet from " IP_ADDR_S " (len %d)",
785 IP_ADDR_V(rp.from), rp.len);
788 syslog(LOG_ERR, "Got packet from unknown source " IP_ADDR_S,
793 if(f->status.validkey)
797 add_queue(&(f->rq), &rp, rp.len);
798 if(!cl->status.waitingforkey)
799 send_key_request(rp.from);
802 if(my_key_expiry <= time(NULL))
810 terminate a connection and notify the other
811 end before closing the sockets
813 void terminate_connection(conn_list_t *cl)
816 if(cl->status.remove)
820 syslog(LOG_NOTICE, "Closing connection with %s.", cl->hostname);
822 if(cl->status.timeout)
824 else if(!cl->status.termreq)
829 close(cl->meta_socket);
831 if(cl->status.outgoing)
834 signal(SIGALRM, sigalrm_handler);
835 syslog(LOG_NOTICE, "Try to re-establish outgoing connection in 5 seconds.");
838 cl->status.remove = 1;
843 send out a ping request to all active
846 int send_broadcast_ping(void)
850 for(p = conn_list; p != NULL; p = p->next)
854 if(p->status.active && p->status.meta)
857 terminate_connection(p);
860 p->status.pinged = 1;
861 p->status.got_pong = 0;
866 last_ping_time = time(NULL);
872 end all connections that did not respond
873 to the ping probe in time
875 int check_dead_connections(void)
879 for(p = conn_list; p != NULL; p = p->next)
883 if(p->status.active && p->status.meta && p->status.pinged && !p->status.got_pong)
885 syslog(LOG_INFO, "%s (" IP_ADDR_S ") didn't respond to ping",
886 p->hostname, IP_ADDR_V(p->vpn_ip));
887 p->status.timeout = 1;
888 terminate_connection(p);
896 accept a new tcp connect and create a
899 int handle_new_meta_connection(conn_list_t *cl)
902 struct sockaddr client;
903 int nfd, len = sizeof(client);
905 if((nfd = accept(cl->meta_socket, &client, &len)) < 0)
907 syslog(LOG_ERR, "Accepting a new connection failed: %m");
911 if((ncn = create_new_connection(nfd)) == NULL)
915 syslog(LOG_NOTICE, "Closed attempted connection.");
919 ncn->status.meta = 1;
920 ncn->next = conn_list;
927 dispatch any incoming meta requests
929 int handle_incoming_meta_data(conn_list_t *cl)
931 int x, l = sizeof(x);
932 int request, oldlen, p, i;
935 if(getsockopt(cl->meta_socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
937 syslog(LOG_ERR, "This is a bug: %s:%d: %d:%m", __FILE__, __LINE__, cl->meta_socket);
942 syslog(LOG_ERR, "Metadata socket error: %s", sys_errlist[x]);
946 if(cl->buflen >= MAXBUFSIZE)
948 syslog(LOG_ERR, "Metadata read buffer full! Discarding contents.");
952 lenin = read(cl->meta_socket, cl->buffer, MAXBUFSIZE-cl->buflen);
956 syslog(LOG_ERR, "Metadata socket read error: %m");
967 for(i = oldlen; i < cl->buflen; i++)
969 if(cl->buffer[i] == '\n')
971 cl->buffer[i] = 0; /* replace end-of-line by end-of-string so we can use sscanf */
979 if(sscanf(cl->buffer, "%d", &request) == 1)
981 if(request_handlers[request] == NULL)
983 syslog(LOG_ERR, "Unknown request: %s", cl->buffer);
988 syslog(LOG_DEBUG, "Got request: %s", cl->buffer);
990 request_handlers[request](cl);
994 syslog(LOG_ERR, "Bogus data received: %s", cl->buffer);
997 cl->buflen -= cl->reqlen;
998 memmove(cl->buffer, cl->buffer + cl->reqlen, cl->buflen);
1011 check all connections to see if anything
1012 happened on their sockets
1014 void check_network_activity(fd_set *f)
1017 int x, l = sizeof(x);
1019 for(p = conn_list; p != NULL; p = p->next)
1021 if(p->status.remove)
1024 if(p->status.dataopen)
1025 if(FD_ISSET(p->socket, f))
1028 The only thing that can happen to get us here is apparently an
1029 error on this outgoing(!) UDP socket that isn't immediate (i.e.
1030 something that will not trigger an error directly on send()).
1031 I've once got here when it said `No route to host'.
1033 getsockopt(p->socket, SOL_SOCKET, SO_ERROR, &x, &l);
1034 syslog(LOG_ERR, "Outgoing data socket error: %s", sys_errlist[x]);
1035 terminate_connection(p);
1040 if(FD_ISSET(p->meta_socket, f))
1041 if(handle_incoming_meta_data(p) < 0)
1043 terminate_connection(p);
1048 if(FD_ISSET(myself->socket, f))
1049 handle_incoming_vpn_data(myself);
1051 if(FD_ISSET(myself->meta_socket, f))
1052 handle_new_meta_connection(myself);
1057 read, encrypt and send data that is
1058 available through the ethertap device
1060 void handle_tap_input(void)
1064 int ether_type, lenin;
1066 memset(&vp, 0, sizeof(vp));
1067 if((lenin = read(tap_fd, &vp, MTU)) <= 0)
1069 syslog(LOG_ERR, "Error while reading from tapdevice: %m");
1073 total_tap_in += lenin;
1075 ether_type = ntohs(*((unsigned short*)(&vp.data[12])));
1076 if(ether_type != 0x0800)
1079 syslog(LOG_INFO, "Non-IP ethernet frame %04x from " MAC_ADDR_S,
1080 ether_type, MAC_ADDR_V(vp.data[6]));
1087 syslog(LOG_INFO, "Dropping short packet");
1091 from = ntohl(*((unsigned long*)(&vp.data[26])));
1092 to = ntohl(*((unsigned long*)(&vp.data[30])));
1095 syslog(LOG_DEBUG, "An IP packet (%04x) for " IP_ADDR_S " from " IP_ADDR_S,
1096 ether_type, IP_ADDR_V(to), IP_ADDR_V(from));
1098 syslog(LOG_DEBUG, MAC_ADDR_S " to " MAC_ADDR_S,
1099 MAC_ADDR_V(vp.data[0]), MAC_ADDR_V(vp.data[6]));
1101 vp.len = (length_t)lenin - 2;
1103 strip_mac_addresses(&vp);
1105 send_packet(to, &vp);
1110 this is where it all happens...
1112 void main_loop(void)
1118 last_ping_time = time(NULL);
1122 tv.tv_sec = timeout;
1128 if((r = select(FD_SETSIZE, &fset, NULL, NULL, &tv)) < 0)
1130 if(errno == EINTR) /* because of alarm */
1132 syslog(LOG_ERR, "Error while waiting for input: %m");
1136 if(r == 0 || last_ping_time + timeout < time(NULL))
1137 /* Timeout... hm... something might be wrong. */
1139 check_dead_connections();
1140 send_broadcast_ping();
1144 check_network_activity(&fset);
1146 /* local tap data */
1147 if(FD_ISSET(tap_fd, &fset))