commit-inetutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Inetutils branch, master, updated. inetutils-1_8-81-g0f4eb73


From: Mats Erik Andersson
Subject: [SCM] GNU Inetutils branch, master, updated. inetutils-1_8-81-g0f4eb73
Date: Tue, 25 Jan 2011 11:32:27 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Inetutils ".

The branch, master has been updated
       via  0f4eb73a2f578cf73c7648181ed8aab927a8ecea (commit)
      from  d9788a7d3521e97d3f341dfd0be6fc78325f4387 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/inetutils.git/commit/?id=0f4eb73a2f578cf73c7648181ed8aab927a8ecea


commit 0f4eb73a2f578cf73c7648181ed8aab927a8ecea
Author: Mats Erik Andersson <address@hidden>
Date:   Tue Jan 25 12:28:39 2011 +0100

    logger: Implement support for transport via IPv6.

diff --git a/ChangeLog b/ChangeLog
index c474101..b77093a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2011-01-25  Mats Erik Andersson <address@hidden>
+
+       * src/logger.c (host_family) [HAVE_DECL_GETADDRINFO]: New variable.
+       (struct logger_sockaddr) [HAVE_IPV6]: New component SINET6.
+       (open_socket) [HAVE_DECL_GETADDRINFO]: Implement new code based
+       on getaddrinfo.  Reorganize old handler of port specification.
+       (argp_options): New options `--ipv4' and `--ipv6`.
+       (parse_opt): Implement parsing of new options.
+       * doc/inetutils.texi (logger): Describe implications of
+       IPv6-support and fallback.  Small corrections to example usage.
+
 2010-12-21  Mats Erik Andersson <address@hidden>
 
        * src/inetd.c (pidfile_option): New variable.
diff --git a/doc/inetutils.texi b/doc/inetutils.texi
index 7249bbf..19e5f88 100644
--- a/doc/inetutils.texi
+++ b/doc/inetutils.texi
@@ -287,6 +287,25 @@ logger address@hidden@dots{}] address@hidden
 @end example
 
 @table @option
address@hidden -4
address@hidden --ipv4
address@hidden -4
address@hidden --ipv4
+Use IPv4 as transport when logging to a host.  The default behaviour
+is to use whatever IP version that matches the host.
+
address@hidden -6
address@hidden --ipv6
address@hidden -6
address@hidden --ipv6
+Use IPv6 as transport when logging to a host.  The option is present
+also on systems without support for IPv6, but will then issue a warning
+and then fall back to IPv4 when delivering the message.
+
+Both options are most influencial when the target host is named using
+a symbolic name, but numerical addresses for host or source must also
+match if either of @option{--ipv4} or @option{--ipv6} is stated.
+
 @item address@hidden
 @itemx address@hidden
 @opindex -i
@@ -303,26 +322,29 @@ must be separated from it by exactly one equals sign.
 @opindex -h
 @opindex --host
 Send messages to the given host or socket.  The @var{host} argument
-can be either a local UNIX socket name (always starting with a
address@hidden/} or:
+can be either a local UNIX socket name (starting with a dash @samp{/}),
+or:
 
 @smallexample
 @var{host}[:@var{port}]
 @end smallexample
 
 @noindent
-where @var{host} is the remote host name or IP address (only IPv4 is
-supported so far), and optional @var{port} is a decimal port number or
-symbolic service name from @file{/etc/services}.  If @var{port} is not
-specified, the port number corresponding to the @samp{syslog} service
-is used.
+where @var{host} is the remote host name or IP address, and the
+optional @var{port} is a decimal port number or symbolic service
+name from @file{/etc/services}.  If @var{port} is not specified,
+the port number corresponding to the @samp{syslog} service is used.
+If a numerical IPv6 address is given without a port specification,
+then the address must be enclosed within brackets (like [::1]).
 
 @item -S @var{addr}
 @itemx address@hidden
 @opindex -S
 @opindex --source
 Supply the source IP address for INET connections.  This option is
-useful in conjunction with @option{--host} (see above).
+useful in conjunction with @option{--host} (see above).  The kind of
+address specified here (IPv4 or IPv6) will propagate to influence
+the resolution of the host address, if it is a symbolic name.
 
 @item -s
 @itemx --stderr
@@ -366,23 +388,23 @@ The following examples illustrate the usage of the 
@command{logger}
 command:
 
 @enumerate 1
address@hidden Log the @samp{System rebooted} message to the local syslog. Use
-the default facility and priority:
address@hidden Log the message @samp{System rebooted} to the local syslog.
+Use default facility and priority:
 
 @example
 logger System rebooted
 @end example
 
 @item Run command and send its error output to the channel
address@hidden channel.  Mark each message with tag @samp{cmd}:
address@hidden  Mark each message with tag @samp{cmd}:
 
 @example
 command 2>&1 | logger -p local0.notice -t cmd
 @end example
 
address@hidden Log each line from file @file{warnings} to @samp{daemon.warn}
-channel on host @samp{logger.runasimi.org}, using the source IP
address@hidden:
address@hidden Log each line from file @file{warnings} to channel
address@hidden on host @samp{logger.runasimi.org},
+using the source IP @samp{10.10.10.1}:
 
 @example
 logger -p daemon.warn -h logger.runasimi.org -S 10.10.10.1 --file
diff --git a/src/logger.c b/src/logger.c
index f112334..c268276 100644
--- a/src/logger.c
+++ b/src/logger.c
@@ -56,6 +56,15 @@ static char *host = PATH_LOG;
 static char *source;
 static char *pidstr;
 
+#if HAVE_DECL_GETADDRINFO
+# if HAVE_IPV6
+static int host_family = AF_UNSPEC;
+# else
+/* Fall back to only IPv4.  */
+static int host_family = AF_INET;
+# endif /* !HAVE_IPV6 */
+#endif /* HAVE_DECL_GETADDRINFO */
+
 
 
 int
@@ -104,6 +113,9 @@ union logger_sockaddr
   {
     struct sockaddr sa;
     struct sockaddr_in sinet;
+#if HAVE_IPV6
+    struct sockaddr_in6 sinet6;
+#endif
     struct sockaddr_un sunix;
 };
 
@@ -115,6 +127,9 @@ open_socket (void)
   union logger_sockaddr sockaddr;
   socklen_t socklen;
   int family;
+#if HAVE_DECL_GETADDRINFO
+  int ret;
+#endif
 
   if (host[0] == '/')
     {
@@ -128,14 +143,129 @@ open_socket (void)
     }
   else
     {
+#if HAVE_DECL_GETADDRINFO
+      struct addrinfo hints, *ai, *res;
+#else
       struct hostent *hp;
       struct servent *sp;
       unsigned short port;
+#endif /* !HAVE_DECL_GETADDRINFO */
       char *p;
 
+#if HAVE_IPV6
+      /* Bare, numeric IPv6 addresses must be contained
+       * in brackets in order that an appended port not
+       * be read by mistake.  */
+      if (*host == '[')
+       {
+         ++host;
+         p = strchr (host, ']');
+         if (p)
+           {
+             *p++ = '\0';
+             if (*p == ':')
+               ++p;
+             else
+               p = NULL;
+           }
+       }
+      else
+        {
+         /* When no bracket was detected, then seek the
+          * right-most colon character in order to correctly
+          * parse IPv6 addresses.  */
+         p = strrchr (host, ':');
+         if (p)
+           *p++ = 0;
+       }
+#else /* !HAVE_IPV6 */
       p = strchr (host, ':');
       if (p)
        *p++ = 0;
+#endif /* !HAVE_IPV6 */
+
+      if (!p)
+       p = "syslog";
+
+#if HAVE_DECL_GETADDRINFO
+      memset (&hints, 0, sizeof (hints));
+      hints.ai_socktype = SOCK_DGRAM;
+
+      /* This falls back to AF_INET if compilation
+       * was made with !HAVE_IPV6.  */
+      hints.ai_family = host_family;
+
+# ifdef AI_ADDRCONFIG
+      hints.ai_flags = AI_ADDRCONFIG;
+# endif
+
+      /* The complete handshake is attempted within
+       * a single while-loop, since the answers from
+       * getaddrinfo() need to be checked in detail.  */
+      ret = getaddrinfo (host, p, &hints, &res);
+      if (ret < 0)
+       error (EXIT_FAILURE, 0, "%s:%s, %s", host, p, gai_strerror(ret));
+
+      for (ai = res; ai; ai = ai->ai_next)
+        {
+         fd = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+         if (fd < 0)
+           continue;
+
+         if (source)
+           {
+             /* Make the assumption that the source address
+              * encodes a desired domain family and that it
+              * be numeric.  */
+             int ret;
+             struct addrinfo tips, *a;
+
+             memset (&tips, 0, sizeof (tips));
+             tips.ai_family = ai->ai_family;
+             tips.ai_flags = AI_NUMERICHOST;
+
+             ret = getaddrinfo(source, NULL, &tips, &a);
+             if (ret)
+               {
+                 close (fd);
+                 continue;
+               }
+
+             if (bind (fd, a->ai_addr, a->ai_addrlen))
+               {
+                 freeaddrinfo (a);
+                 close (fd);
+                 continue;
+               }
+
+             freeaddrinfo (a);
+           }
+
+         if (connect (fd, ai->ai_addr, ai->ai_addrlen))
+           {
+             close (fd);
+             continue;
+           }
+
+         /* Socket standing, bound and connected.  */
+         break;
+       }
+
+      if (res)
+       freeaddrinfo (res);
+
+      if (ai == NULL)
+       error (EXIT_FAILURE, EADDRNOTAVAIL, "%s:%s", host, p);
+
+      /* Existing socket can be returned now.
+       * This handles AF_INET and AF_INET6 in case
+       * HAVE_DECL_GETADDRINFO is true.  */
+      return;
+
+#else /* !HAVE_DECL_GETADDRINFO */
+
+      sockaddr.sinet.sin_family = AF_INET;
+      family = PF_INET;
 
       hp = gethostbyname (host);
       if (hp)
@@ -144,11 +274,6 @@ open_socket (void)
               != 1)
        error (EXIT_FAILURE, 0, "unknown host name");
 
-      sockaddr.sinet.sin_family = AF_INET;
-      family = PF_INET;
-      if (!p)
-       p = "syslog";
-
       if (isdigit (*p))
        {
          char *end;
@@ -163,9 +288,14 @@ open_socket (void)
        error (EXIT_FAILURE, 0, "%s: unknown service name", p);
 
       sockaddr.sinet.sin_port = port;
+#endif /* !HAVE_DECL_GETADDRINFO */
+
       socklen = sizeof (sockaddr.sinet);
     }
 
+  /* Execution arrives here for AF_UNIX and for
+   * situations with !HAVE_DECL_GETADDRINFO.  */
+
   fd = socket (family, SOCK_DGRAM, 0);
   if (fd < 0)
     error (EXIT_FAILURE, errno, "cannot create socket");
@@ -244,6 +374,8 @@ const char args_doc[] = "[MESSAGE]";
 const char doc[] = "Send messages to syslog";
 
 static struct argp_option argp_options[] = {
+  {"ipv4", '4', NULL, 0, "use IPv4 for logging to host" },
+  {"ipv6", '6', NULL, 0, "use IPv6 with a host target" },
   { "host", 'h', "HOST", 0,
     "log to host instead of the default " PATH_LOG },
   { "source", 'S', "IP", 0,
@@ -264,6 +396,23 @@ parse_opt (int key, char *arg, struct argp_state *state)
 {
   switch (key)
     {
+    case '4':
+      host_family = AF_INET;
+      break;
+
+    case '6':
+#if HAVE_IPV6
+      host_family = AF_INET6;
+      break;
+
+#else /* !HAVE_IPV6 */
+      /* Print a warning but continue with IPv4.  */
+      error (0, 0, "Warning: Falling back to IPv4, "
+               "since IPv6 is disabled");
+      /* AF_INET is set by default in this case.  */
+      break;
+#endif /* !HAVE_IPV6 */
+
     case 'h':
       host = arg;
       break;

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog          |   11 ++++
 doc/inetutils.texi |   50 ++++++++++++-----
 src/logger.c       |  159 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 201 insertions(+), 19 deletions(-)


hooks/post-receive
-- 
GNU Inetutils 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]