Fix compilation errors when --enable-uml is used.
[tinc] / src / uml_device.c
index 26bcb01..49f26ff 100644 (file)
@@ -1,7 +1,7 @@
 /*
     device.c -- UML network socket
     Copyright (C) 2002-2005 Ivo Timmermans,
-                  2002-2011 Guus Sliepen <guus@tinc-vpn.org>
+                  2002-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -35,7 +35,7 @@ static int request_fd = -1;
 static int data_fd = -1;
 static int write_fd = -1;
 static int state = 0;
-static char *device_info;
+static const char *device_info = "UML network socket";
 
 extern char *identname;
 extern volatile bool running;
@@ -46,10 +46,10 @@ static uint64_t device_total_out = 0;
 enum request_type { REQ_NEW_CONTROL };
 
 static struct request {
-  uint32_t magic;
-  uint32_t version;
-  enum request_type type;
-  struct sockaddr_un sock;
+       uint32_t magic;
+       uint32_t version;
+       enum request_type type;
+       struct sockaddr_un sock;
 } request;
 
 static struct sockaddr_un data_sun;
@@ -64,20 +64,23 @@ static bool setup_device(void) {
        } name;
        struct timeval tv;
 
-       if(!get_config_string(lookup_config(config_tree, "Device"), &device))
-               xasprintf(&device, LOCALSTATEDIR "/run/%s.umlsocket", identname);
+       if(!get_config_string(lookup_config(config_tree, "Device"), &device)) {
+               xasprintf(&device, RUNSTATEDIR "/%s.umlsocket", identname);
+       }
 
        get_config_string(lookup_config(config_tree, "Interface"), &iface);
 
-       device_info = "UML network socket";
-
        if((write_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) {
                logger(LOG_ERR, "Could not open write %s: %s", device_info, strerror(errno));
                running = false;
                return false;
        }
 
-       setsockopt(write_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
+#ifdef FD_CLOEXEC
+       fcntl(write_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
+       setsockopt(write_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
 
        if(fcntl(write_fd, F_SETFL, O_NONBLOCK) < 0) {
                logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno));
@@ -91,7 +94,11 @@ static bool setup_device(void) {
                return false;
        }
 
-       setsockopt(data_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
+#ifdef FD_CLOEXEC
+       fcntl(data_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
+       setsockopt(data_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
 
        if(fcntl(data_fd, F_SETFL, O_NONBLOCK) < 0) {
                logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno));
@@ -104,9 +111,9 @@ static bool setup_device(void) {
        gettimeofday(&tv, NULL);
        name.usecs = tv.tv_usec;
        data_sun.sun_family = AF_UNIX;
-       memcpy(&data_sun.sun_path, &name, sizeof name);
-       
-       if(bind(data_fd, (struct sockaddr *)&data_sun, sizeof data_sun) < 0) {
+       memcpy(&data_sun.sun_path, &name, sizeof(name));
+
+       if(bind(data_fd, (struct sockaddr *)&data_sun, sizeof(data_sun)) < 0) {
                logger(LOG_ERR, "Could not bind data %s: %s", device_info, strerror(errno));
                running = false;
                return false;
@@ -114,11 +121,15 @@ static bool setup_device(void) {
 
        if((listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
                logger(LOG_ERR, "Could not open %s: %s", device_info,
-                          strerror(errno));
+                      strerror(errno));
                return false;
        }
 
-       setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
+#ifdef FD_CLOEXEC
+       fcntl(device_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
+       setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
 
        if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) {
                logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno));
@@ -126,8 +137,9 @@ static bool setup_device(void) {
        }
 
        listen_sun.sun_family = AF_UNIX;
-       strncpy(listen_sun.sun_path, device, sizeof listen_sun.sun_path);
-       if(bind(listen_fd, (struct sockaddr *)&listen_sun, sizeof listen_sun) < 0) {
+       strncpy(listen_sun.sun_path, device, sizeof(listen_sun.sun_path));
+
+       if(bind(listen_fd, (struct sockaddr *)&listen_sun, sizeof(listen_sun)) < 0) {
                logger(LOG_ERR, "Could not bind %s to %s: %s", device_info, device, strerror(errno));
                return false;
        }
@@ -142,122 +154,135 @@ static bool setup_device(void) {
 
        logger(LOG_INFO, "%s is a %s", device, device_info);
 
-       if(routing_mode == RMODE_ROUTER)
+       if(routing_mode == RMODE_ROUTER) {
                overwrite_mac = true;
+       }
 
        return true;
 }
 
 void close_device(void) {
-       if(listen_fd >= 0)
+       if(listen_fd >= 0) {
                close(listen_fd);
+       }
 
-       if(request_fd >= 0)
+       if(request_fd >= 0) {
                close(request_fd);
+       }
 
-       if(data_fd >= 0)
+       if(data_fd >= 0) {
                close(data_fd);
+       }
 
-       if(write_fd >= 0)
+       if(write_fd >= 0) {
                close(write_fd);
+       }
 
        unlink(device);
 
        free(device);
-       if(iface) free(iface);
+
+       if(iface) {
+               free(iface);
+       }
 }
 
 static bool read_packet(vpn_packet_t *packet) {
        int lenin;
 
        switch(state) {
-               case 0: {
-                       struct sockaddr sa;
-                       socklen_t salen = sizeof sa;
-
-                       request_fd = accept(listen_fd, &sa, &salen);
-                       if(request_fd < 0) {
-                               logger(LOG_ERR, "Could not accept connection to %s %s: %s", device_info, device, strerror(errno));
-                               return false;
-                       }
-
-                       if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) {
-                               logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno));
-                               running = false;
-                               return false;
-                       }
-
-                       close(listen_fd);
-                       listen_fd = -1;
-                       device_fd = request_fd;
-                       state = 1;
+       case 0: {
+               struct sockaddr sa;
+               socklen_t salen = sizeof(sa);
+
+               request_fd = accept(listen_fd, &sa, &salen);
+
+               if(request_fd < 0) {
+                       logger(LOG_ERR, "Could not accept connection to %s %s: %s", device_info, device, strerror(errno));
+                       return false;
+               }
+
+#ifdef FD_CLOEXEC
+               fcntl(request_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
+               if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) {
+                       logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno));
+                       running = false;
+                       return false;
+               }
+
+               close(listen_fd);
+               listen_fd = -1;
+               device_fd = request_fd;
+               state = 1;
 
+               return false;
+       }
+
+       case 1: {
+               if((lenin = read(request_fd, &request, sizeof(request))) != sizeof request) {
+                       logger(LOG_ERR, "Error while reading request from %s %s: %s", device_info,
+                              device, strerror(errno));
+                       running = false;
                        return false;
                }
 
-               case 1: {
-                       if((lenin = read(request_fd, &request, sizeof request)) != sizeof request) {
-                               logger(LOG_ERR, "Error while reading request from %s %s: %s", device_info,
-                                          device, strerror(errno));
-                               running = false;
-                               return false;
-                       }
-
-                       if(request.magic != 0xfeedface || request.version != 3 || request.type != REQ_NEW_CONTROL) {
-                               logger(LOG_ERR, "Unknown magic %x, version %d, request type %d from %s %s",
-                                               request.magic, request.version, request.type, device_info, device);
-                               running = false;
-                               return false;
-                       }
-
-                       if(connect(write_fd, &request.sock, sizeof request.sock) < 0) {
-                               logger(LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno));
-                               running = false;
-                               return false;
-                       }
-
-                       write(request_fd, &data_sun, sizeof data_sun);
-                       device_fd = data_fd;
-
-                       logger(LOG_INFO, "Connection with UML established");
-
-                       state = 2;
+               if(request.magic != 0xfeedface || request.version != 3 || request.type != REQ_NEW_CONTROL) {
+                       logger(LOG_ERR, "Unknown magic %x, version %d, request type %d from %s %s",
+                              request.magic, request.version, request.type, device_info, device);
+                       running = false;
                        return false;
                }
 
-               case 2: {
-                       if((lenin = read(data_fd, packet->data, MTU)) <= 0) {
-                               logger(LOG_ERR, "Error while reading from %s %s: %s", device_info,
-                                          device, strerror(errno));
-                               running = false;
-                               return false;
-                       }
+               if(connect(write_fd, (struct sockaddr *)&request.sock, sizeof(request.sock)) < 0) {
+                       logger(LOG_ERR, "Could not bind write %s: %s", device_info, strerror(errno));
+                       running = false;
+                       return false;
+               }
 
-                       packet->len = lenin;
+               write(request_fd, &data_sun, sizeof(data_sun));
+               device_fd = data_fd;
 
-                       device_total_in += packet->len;
+               logger(LOG_INFO, "Connection with UML established");
 
-                       ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len,
-                                          device_info);
+               state = 2;
+               return false;
+       }
 
-                       return true;
+       case 2: {
+               if((lenin = read(data_fd, packet->data, MTU)) <= 0) {
+                       logger(LOG_ERR, "Error while reading from %s %s: %s", device_info,
+                              device, strerror(errno));
+                       running = false;
+                       return false;
                }
 
-               default:
-                       logger(LOG_ERR, "Invalid value for state variable in " __FILE__);
-                       abort();
+               packet->len = lenin;
+
+               device_total_in += packet->len;
+
+               ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len,
+                                       device_info);
+
+               return true;
+       }
+
+       default:
+               logger(LOG_ERR, "Invalid value for state variable in " __FILE__);
+               abort();
        }
 }
 
 static bool write_packet(vpn_packet_t *packet) {
        if(state != 2) {
                ifdebug(TRAFFIC) logger(LOG_DEBUG, "Dropping packet of %d bytes to %s: not connected to UML yet",
-                               packet->len, device_info);
+                                       packet->len, device_info);
                return false;
        }
 
        ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s",
-                          packet->len, device_info);
+                               packet->len, device_info);
 
        if(write(write_fd, packet->data, packet->len) < 0) {
                if(errno != EINTR && errno != EAGAIN) {