fixes for starting and stopping gnunet-helper-nat-server
authorChristian Grothoff <christian@grothoff.org>
Mon, 2 Jan 2017 19:13:38 +0000 (20:13 +0100)
committerChristian Grothoff <christian@grothoff.org>
Mon, 2 Jan 2017 19:13:38 +0000 (20:13 +0100)
src/nat/gnunet-helper-nat-server.c
src/nat/gnunet-service-nat.c
src/nat/gnunet-service-nat_helper.c

index 8c3df749d161314aea51e0aa0107df1bd863cdd9..ef8e97482771d0054713251e7f23c35fc028ed0d 100644 (file)
@@ -264,8 +264,11 @@ send_icmp_echo (const struct in_addr *my_ip)
   ip_pkt.src_ip = my_ip->s_addr;
   ip_pkt.dst_ip = dummy.s_addr;
   ip_pkt.checksum =
-      htons (calc_checksum ((uint16_t *) & ip_pkt, sizeof (struct ip_header)));
-  memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
+      htons (calc_checksum ((uint16_t *) & ip_pkt,
+                           sizeof (struct ip_header)));
+  memcpy (&packet[off],
+         &ip_pkt,
+         sizeof (struct ip_header));
   off += sizeof (struct ip_header);
 
   icmp_echo.type = ICMP_ECHO;
@@ -273,9 +276,12 @@ send_icmp_echo (const struct in_addr *my_ip)
   icmp_echo.checksum = 0;
   icmp_echo.reserved = 0;
   icmp_echo.checksum =
-      htons (calc_checksum
-             ((uint16_t *) & icmp_echo, sizeof (struct icmp_echo_header)));
-  memcpy (&packet[off], &icmp_echo, sizeof (struct icmp_echo_header));
+    htons (calc_checksum
+          ((uint16_t *) & icmp_echo,
+           sizeof (struct icmp_echo_header)));
+  memcpy (&packet[off],
+         &icmp_echo,
+         sizeof (struct icmp_echo_header));
   off += sizeof (struct icmp_echo_header);
 
   memset (&dst, 0, sizeof (dst));
@@ -284,17 +290,24 @@ send_icmp_echo (const struct in_addr *my_ip)
   dst.sin_len = sizeof (struct sockaddr_in);
 #endif
   dst.sin_addr = dummy;
-  err =
-      sendto (rawsock, packet, off, 0, (struct sockaddr *) &dst, sizeof (dst));
+  err = sendto (rawsock,
+               packet,
+               off,
+               0,
+               (struct sockaddr *) &dst,
+               sizeof (dst));
   if (err < 0)
   {
 #if VERBOSE
-    fprintf (stderr, "sendto failed: %s\n", strerror (errno));
+    fprintf (stderr,
+            "sendto failed: %s\n",
+            strerror (errno));
 #endif
   }
   else if (sizeof (packet) != err)
   {
-    fprintf (stderr, "Error: partial send of ICMP message\n");
+    fprintf (stderr,
+            "Error: partial send of ICMP message\n");
   }
 }
 
@@ -315,16 +328,24 @@ send_udp ()
 #endif
   dst.sin_addr = dummy;
   dst.sin_port = htons (NAT_TRAV_PORT);
-  err = sendto (udpsock, NULL, 0, 0, (struct sockaddr *) &dst, sizeof (dst));
+  err = sendto (udpsock,
+               NULL,
+               0,
+               0,
+               (struct sockaddr *) &dst,
+               sizeof (dst));
   if (err < 0)
   {
 #if VERBOSE
-    fprintf (stderr, "sendto failed: %s\n", strerror (errno));
+    fprintf (stderr,
+            "sendto failed: %s\n",
+            strerror (errno));
 #endif
   }
   else if (0 != err)
   {
-    fprintf (stderr, "Error: partial send of ICMP message\n");
+    fprintf (stderr,
+            "Error: partial send of ICMP message\n");
   }
 }
 
@@ -348,11 +369,15 @@ process_icmp_response ()
   have = read (icmpsock, buf, sizeof (buf));
   if (-1 == have)
   {
-    fprintf (stderr, "Error reading raw socket: %s\n", strerror (errno));
+    fprintf (stderr,
+            "Error reading raw socket: %s\n",
+            strerror (errno));
     return;
   }
 #if VERBOSE
-  fprintf (stderr, "Received message of %u bytes\n", (unsigned int) have);
+  fprintf (stderr,
+          "Received message of %u bytes\n",
+          (unsigned int) have);
 #endif
   if (have <
       (ssize_t) (sizeof (struct ip_header) +
@@ -433,15 +458,27 @@ setup_raw_socket ()
   const int one = 1;
 
   if (-1 ==
-      setsockopt (rawsock, SOL_SOCKET, SO_BROADCAST, (char *) &one, sizeof (one)))
+      setsockopt (rawsock,
+                 SOL_SOCKET,
+                 SO_BROADCAST,
+                 (char *) &one,
+                 sizeof (one)))
   {
-    fprintf (stderr, "setsockopt failed: %s\n", strerror (errno));
+    fprintf (stderr,
+            "setsockopt failed: %s\n",
+            strerror (errno));
     return -1;
   }
   if (-1 ==
-      setsockopt (rawsock, IPPROTO_IP, IP_HDRINCL, (char *) &one, sizeof (one)))
+      setsockopt (rawsock,
+                 IPPROTO_IP,
+                 IP_HDRINCL,
+                 (char *) &one,
+                 sizeof (one)))
   {
-    fprintf (stderr, "setsockopt failed: %s\n", strerror (errno));
+    fprintf (stderr,
+            "setsockopt failed: %s\n",
+            strerror (errno));
     return -1;
   }
   return 0;
@@ -492,7 +529,8 @@ make_udp_socket (const struct in_addr *my_ip)
 
 
 int
-main (int argc, char *const *argv)
+main (int argc,
+      char *const *argv)
 {
   struct in_addr external;
   fd_set rs;
@@ -504,11 +542,15 @@ main (int argc, char *const *argv)
   int global_ret;
 
   /* Create an ICMP raw socket for reading (we'll check errors later) */
-  icmpsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
+  icmpsock = socket (AF_INET,
+                    SOCK_RAW,
+                    IPPROTO_ICMP);
   icmp_eno = errno;
 
   /* Create an (ICMP) raw socket for writing (we'll check errors later) */
-  rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
+  rawsock = socket (AF_INET,
+                   SOCK_RAW,
+                   IPPROTO_RAW);
   raw_eno = errno;
   udpsock = -1;
 
@@ -517,14 +559,18 @@ main (int argc, char *const *argv)
 #ifdef HAVE_SETRESUID
   if (0 != setresuid (uid, uid, uid))
   {
-    fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
+    fprintf (stderr,
+            "Failed to setresuid: %s\n",
+            strerror (errno));
     global_ret = 1;
     goto error_exit;
   }
 #else
   if (0 != (setuid (uid) | seteuid (uid)))
   {
-    fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
+    fprintf (stderr,
+            "Failed to setuid: %s\n",
+            strerror (errno));
     global_ret = 2;
     goto error_exit;
   }
@@ -540,13 +586,16 @@ main (int argc, char *const *argv)
   }
   if (1 != inet_pton (AF_INET, argv[1], &external))
   {
-    fprintf (stderr, "Error parsing IPv4 address: %s\n", strerror (errno));
+    fprintf (stderr,
+            "Error parsing IPv4 address: %s\n",
+            strerror (errno));
     global_ret = 4;
     goto error_exit;
   }
   if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
   {
-    fprintf (stderr, "Internal error converting dummy IP to binary.\n");
+    fprintf (stderr,
+            "Internal error converting dummy IP to binary.\n");
     global_ret = 5;
     goto error_exit;
   }
@@ -554,7 +603,9 @@ main (int argc, char *const *argv)
   /* error checking icmpsock */
   if (-1 == icmpsock)
   {
-    fprintf (stderr, "Error opening RAW socket: %s\n", strerror (icmp_eno));
+    fprintf (stderr,
+            "Error opening RAW socket: %s\n",
+            strerror (icmp_eno));
     global_ret = 6;
     goto error_exit;
   }
@@ -562,7 +613,9 @@ main (int argc, char *const *argv)
   {
     /* this could happen if we were started with a large number of already-open
        file descriptors... */
-    fprintf (stderr, "Socket number too large (%d > %u)\n", icmpsock,
+    fprintf (stderr,
+            "Socket number too large (%d > %u)\n",
+            icmpsock,
              (unsigned int) FD_SETSIZE);
     global_ret = 7;
     goto error_exit;
@@ -571,7 +624,9 @@ main (int argc, char *const *argv)
   /* error checking rawsock */
   if (-1 == rawsock)
   {
-    fprintf (stderr, "Error opening RAW socket: %s\n", strerror (raw_eno));
+    fprintf (stderr,
+            "Error opening RAW socket: %s\n",
+            strerror (raw_eno));
     global_ret = 8;
     goto error_exit;
   }
@@ -601,7 +656,9 @@ main (int argc, char *const *argv)
     {
       if (errno == EINTR)
         continue;
-      fprintf (stderr, "select failed: %s\n", strerror (errno));
+      fprintf (stderr,
+              "select failed: %s\n",
+              strerror (errno));
       break;
     }
     if (1 == getppid ())        /* Check the parent process id, if 1 the parent has died, so we should die too */
index f432eca186de070c8d5314994a9c1664e84cba9c..e29f371083ba1055de1158d4fb882709766036ee 100644 (file)
@@ -395,6 +395,31 @@ static struct GNUNET_NAT_ExternalHandle *probe_external_ip_op;
 static struct in_addr mini_external_ipv4;
 
 
+/**
+ * Remove and free an entry from the #lal_head DLL.
+ *
+ * @param lal entry to free
+ */
+static void
+free_lal (struct LocalAddressList *lal)
+{
+  GNUNET_CONTAINER_DLL_remove (lal_head,
+                              lal_tail,
+                              lal);
+  if (NULL != lal->hc)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+               "Lost NATed local address %s, stopping NAT server\n",
+               GNUNET_a2s ((const struct sockaddr *) &lal->addr,
+                           sizeof (struct sockaddr_in)));
+
+    GN_stop_gnunet_nat_server_ (lal->hc);
+    lal->hc = NULL;
+  }
+  GNUNET_free (lal);
+}
+
+
 /**
  * Free the DLL starting at #lal_head.
  */ 
@@ -404,17 +429,7 @@ destroy_lal ()
   struct LocalAddressList *lal;
 
   while (NULL != (lal = lal_head))
-  {
-    GNUNET_CONTAINER_DLL_remove (lal_head,
-                                lal_tail,
-                                lal);
-    if (NULL != lal->hc)
-    {
-      GN_stop_gnunet_nat_server_ (lal->hc);
-      lal->hc = NULL;
-    }
-    GNUNET_free (lal);
-  }
+    free_lal (lal);
 }
 
 
@@ -1099,6 +1114,7 @@ run_scan (void *cls)
   struct IfcProcContext ifc_ctx;
   int found;
   int have_nat;
+  struct LocalAddressList *lnext;
   
   scan_task = GNUNET_SCHEDULER_add_delayed (SCAN_FREQ,
                                            &run_scan,
@@ -1111,8 +1127,9 @@ run_scan (void *cls)
   /* remove addresses that disappeared */
   for (struct LocalAddressList *lal = lal_head;
        NULL != lal;
-       lal = lal->next)
+       lal = lnext)
   {
+    lnext = lal->next;
     found = GNUNET_NO;
     for (struct LocalAddressList *pos = ifc_ctx.lal_head;
         NULL != pos;
@@ -1126,20 +1143,21 @@ run_scan (void *cls)
                         : sizeof (struct sockaddr_in6))) )
       {
        found = GNUNET_YES;
-       pos->hc = lal->hc;
-       lal->hc = NULL;
       }
     }
     if (GNUNET_NO == found)
+    {
       notify_clients (lal,
                      GNUNET_NO);
+      free_lal (lal);
+    }
   }
 
   /* add addresses that appeared */
   have_nat = GNUNET_NO;
   for (struct LocalAddressList *pos = ifc_ctx.lal_head;
        NULL != pos;
-       pos = pos->next)
+       pos = ifc_ctx.lal_head)
   {
     found = GNUNET_NO;
     if (GNUNET_NAT_AC_LAN == (GNUNET_NAT_AC_LAN & pos->ac))
@@ -1156,19 +1174,34 @@ run_scan (void *cls)
                         : sizeof (struct sockaddr_in6))) )
        found = GNUNET_YES;
     }
-    if (GNUNET_NO == found)
+    GNUNET_CONTAINER_DLL_remove (ifc_ctx.lal_head,
+                                ifc_ctx.lal_tail,
+                                pos);
+    if (GNUNET_YES == found)
+    {
+      GNUNET_free (pos);
+    }
+    else
+    {
       notify_clients (pos,
                      GNUNET_YES);
-    if ( (AF_INET == pos->af) &&
-        (NULL == pos->hc) &&
-        (0 != (GNUNET_NAT_AC_LAN & pos->ac)) )
-    {
-      const struct sockaddr_in *s4
-       = (const struct sockaddr_in *) &pos->addr;
-      
-      pos->hc = GN_start_gnunet_nat_server_ (&s4->sin_addr,
-                                            &reversal_callback,
-                                            pos);
+      GNUNET_CONTAINER_DLL_insert (lal_head,
+                                  lal_tail,
+                                  pos);
+      if ( (AF_INET == pos->af) &&
+          (NULL == pos->hc) &&
+          (0 != (GNUNET_NAT_AC_LAN & pos->ac)) )
+      {
+       const struct sockaddr_in *s4
+         = (const struct sockaddr_in *) &pos->addr;
+       
+       GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+                   "Found NATed local address %s, starting NAT server\n",
+                   GNUNET_a2s ((void *) &pos->addr, sizeof (*s4)));
+       pos->hc = GN_start_gnunet_nat_server_ (&s4->sin_addr,
+                                              &reversal_callback,
+                                              pos);
+      }
     }
   }
   if ( (GNUNET_YES == have_nat) &&
@@ -1194,10 +1227,6 @@ run_scan (void *cls)
       probe_external_ip_op = NULL;
     }
   }
-  
-  destroy_lal ();
-  lal_head = ifc_ctx.lal_head;
-  lal_tail = ifc_ctx.lal_tail;
 }
 
 
index febc3c2dd4db570198fc1250c4b5e4c2bd8413f7..7e5051d6571305d43d1006c2912f4a78cf568077 100644 (file)
@@ -28,7 +28,6 @@
 #include "gnunet_util_lib.h"
 #include "gnunet-service-nat_helper.h"
 
-#define LOG(kind,...) GNUNET_log_from (kind, "nat", __VA_ARGS__)
 
 /**
  * Information we keep per NAT helper process.
@@ -133,11 +132,11 @@ nat_server_read (void *cls)
                             sizeof (mybuf));
   if (bytes < 1)
   {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Finished reading from server stdout with code: %d\n",
-         bytes);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+               "Finished reading from server stdout with code: %d\n",
+               bytes);
     if (0 != GNUNET_OS_process_kill (h->server_proc,
--                                   GNUNET_TERM_SIG))
+                                    GNUNET_TERM_SIG))
       GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING,
                                "nat",
                                "kill");
@@ -183,10 +182,9 @@ nat_server_read (void *cls)
                         &sin_addr.sin_addr)))
   {
     /* should we restart gnunet-helper-nat-server? */
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-        "nat",
-         _("gnunet-helper-nat-server generated malformed address `%s'\n"),
-         mybuf);
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+               _("gnunet-helper-nat-server generated malformed address `%s'\n"),
+               mybuf);
     h->server_read_task 
       = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                         h->server_stdout_handle,
@@ -195,10 +193,10 @@ nat_server_read (void *cls)
     return;
   }
   sin_addr.sin_port = htons ((uint16_t) port);
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "gnunet-helper-nat-server read: %s:%d\n",
-       mybuf,
-       port);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "gnunet-helper-nat-server read: %s:%d\n",
+             mybuf,
+             port);
   h->cb (h->cb_cls,
         &sin_addr);
   h->server_read_task 
@@ -238,10 +236,10 @@ restart_nat_server (void *cls)
                            &h->internal_address,
                            ia,
                            sizeof (ia)));
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Starting `%s' at `%s'\n",
-       "gnunet-helper-nat-server",
-       ia);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Starting `%s' at `%s'\n",
+             "gnunet-helper-nat-server",
+             ia);
   /* Start the server process */
   binary
     = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server");
@@ -258,10 +256,9 @@ restart_nat_server (void *cls)
   GNUNET_free (binary);
   if (NULL == h->server_proc)
   {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-        "nat",
-        _("Failed to start %s\n"),
-        "gnunet-helper-nat-server");
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+               _("Failed to start %s\n"),
+               "gnunet-helper-nat-server");
     GNUNET_DISK_pipe_close (h->server_stdout);
     h->server_stdout = NULL;
     try_again (h);
@@ -301,6 +298,7 @@ GN_start_gnunet_nat_server_ (const struct in_addr *internal_address,
   h->cb = cb;
   h->cb_cls = cb_cls;
   h->internal_address = *internal_address;
+  restart_nat_server (h);
   if (NULL == h->server_stdout)
   {
     GN_stop_gnunet_nat_server_ (h);
@@ -328,9 +326,8 @@ GN_stop_gnunet_nat_server_ (struct HelperContext *h)
   {
     if (0 != GNUNET_OS_process_kill (h->server_proc,
                                      GNUNET_TERM_SIG))
-      GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING,
-                                "nat",
-                                "kill");
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                          "kill");
     GNUNET_OS_process_wait (h->server_proc);
     GNUNET_OS_process_destroy (h->server_proc);
     h->server_proc = NULL;
@@ -375,9 +372,8 @@ GN_request_connection_reversal (const struct in_addr *internal_address,
                         intv4,
                         INET_ADDRSTRLEN))
   {
-    GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING,
-                              "nat",
-                              "inet_ntop");
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                        "inet_ntop");
     return GNUNET_SYSERR;
   }
   if (NULL == inet_ntop (AF_INET,
@@ -385,20 +381,19 @@ GN_request_connection_reversal (const struct in_addr *internal_address,
                         remv4,
                         INET_ADDRSTRLEN))
   {
-    GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING,
-                              "nat",
-                              "inet_ntop");
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                        "inet_ntop");
     return GNUNET_SYSERR;
   }  
   GNUNET_snprintf (port_as_string,
                    sizeof (port_as_string),
                    "%d",
                    internal_port);
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       _("Running gnunet-helper-nat-client %s %s %u\n"),
-       intv4,
-       remv4,
-       internal_port);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             _("Running gnunet-helper-nat-client %s %s %u\n"),
+             intv4,
+             remv4,
+             internal_port);
   binary
     = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-client");
   proc