bug-inetutils
[Top][All Lists]
Advanced

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

Re: [bug-inetutils] [patch] inetd: set environment variables for remote


From: Dirk Jagdmann
Subject: Re: [bug-inetutils] [patch] inetd: set environment variables for remote host, ip and local port
Date: Wed, 26 Jul 2006 16:38:51 +0200
User-agent: Thunderbird 1.5.0.4 (X11/20060516)

I wonder if it would be better to use the same environment variables as
"tcpserver" from ucspi-tcp by Dan Bernstein. See:
  http://cr.yp.to/ucspi-tcp/environment.html

A good suggestion. I have revised my patch to use those variables djb choose. However while looking over the code I found one flaw with those variables, because TCPLOCALHOST and TCPREMOTEHOST require a DNS lookup for each connection which can hurt performance seriously. So if something like my patch would go into an official inetd release at least those to variables should be configurable.

Now while I'm not afraid to add some more code, I'd like to hear some more comments on this patch and if there would be any chance of being included in the mainline inet-utils. If so, what configuration options should be used to control setting of those environment vars.

Whatever I have attached the current state of my patch to this email.

--
---> Dirk Jagdmann ^ doj / cubic
----> http://cubic.org/~doj
-----> http://llg.cubic.org
Index: inetutils-1.4.2/inetd/ChangeLog
===================================================================
--- inetutils-1.4.2.orig/inetd/ChangeLog
+++ inetutils-1.4.2/inetd/ChangeLog
@@ -1,3 +1,10 @@
+2006-07-25  Dirk Jagdmann  <address@hidden>
+
+       * inetd.8: added section about environment variables.
+
+       * inetd.c (main): set environment variables with local and remote
+       hostname, ip and port for TCP connections.
+
 2002-04-29  Alfred M. Szmidt  <address@hidden>
 
        * inetd.c: <version.h>: Include removed.
Index: inetutils-1.4.2/inetd/inetd.c
===================================================================
--- inetutils-1.4.2.orig/inetd/inetd.c
+++ inetutils-1.4.2/inetd/inetd.c
@@ -462,7 +462,9 @@ main (int argc, char *argv[], char *envp
              fprintf (stderr, "someone wants %s\n", sep->se_service);
            if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
              {
-               ctrl = accept (sep->se_fd, (struct sockaddr *)0, (int *)0);
+               struct sockaddr_in sa_client;
+               int len = sizeof(sa_client);
+               ctrl = accept (sep->se_fd, (struct sockaddr *)&sa_client, &len);
                if (debug)
                  fprintf (stderr, "accept, ctrl %d\n", ctrl);
                if (ctrl < 0)
@@ -472,6 +474,78 @@ main (int argc, char *argv[], char *envp
                              sep->se_service);
                    continue;
                  }
+
+               /* set TCP environment variables.
+                  modelled after djb's ucspi-tcp tools:
+                  http://cr.yp.to/ucspi-tcp/environment.html */
+               {
+                 char str[16];
+                 char *ip;
+                 struct hostent *host;
+                 struct sockaddr_in sa_server;
+                 len=sizeof(sa_server);
+
+                 setenv("PROTO", "TCP", 1);
+
+                 if(getsockname(ctrl, (struct sockaddr*)&sa_server, &len) < 0)
+                   {
+                     syslog(LOG_WARNING, "getsockname():%s\n", 
strerror(errno));
+                     unsetenv("TCPLOCALIP");
+                     unsetenv("TCPLOCALHOST");
+                     unsetenv("TCPLOCALPORT");
+                   }
+                 else
+                   {
+                     ip=inet_ntoa(sa_server.sin_addr);
+                     if(ip)
+                       {
+                         if(setenv("TCPLOCALIP", ip, 1) < 0)
+                           syslog(LOG_WARNING, "setenv(TCPLOCALIP):%s\n", 
strerror(errno));
+                       }
+                     else
+                       unsetenv("TCPLOCALIP");
+
+                     snprintf(str, sizeof(str), "%i", 
ntohs(sa_server.sin_port));
+                     setenv("TCPLOCALPORT", str, 1);
+
+                     if ((host = gethostbyaddr((char *) &sa_server.sin_addr,
+                                               sizeof(sa_server.sin_addr),
+                                               AF_INET)) == NULL)
+                       {
+                         syslog(LOG_WARNING, "gethostbyaddr:%s\n", 
strerror(errno));
+                         unsetenv("TCPLOCALHOST");
+                       }
+                     else
+                       if(setenv("TCPLOCALHOST", host->h_name, 1) < 0)
+                         syslog(LOG_WARNING, "setenv(TCPLOCALHOST):%s\n", 
strerror(errno));
+                   }
+
+                 ip=inet_ntoa(sa_client.sin_addr);
+                 if(ip)
+                   {
+                     if(setenv("TCPREMOTEIP", ip, 1) < 0)
+                       syslog(LOG_WARNING, "setenv(TCPREMOTEIP):%s\n", 
strerror(errno));
+                   }
+                 else
+                   unsetenv("TCPREMOTEIP");
+
+                 snprintf(str, sizeof(str), "%i", ntohs(sa_client.sin_port));
+                 if(setenv("TCPREMOTEPORT", str, 1) < 0)
+                   syslog(LOG_WARNING, "setenv(TCPREMOTEPORT):%s\n", 
strerror(errno));
+
+                 if ((host = gethostbyaddr((char *) &sa_client.sin_addr,
+                                           sizeof(sa_client.sin_addr),
+                                           AF_INET)) == NULL)
+                   {
+                     syslog(LOG_WARNING, "gethostbyaddr:%s\n", 
strerror(errno));
+                     unsetenv("TCPREMOTEHOST");
+                   }
+                 else
+                   {
+                     if(setenv("TCPREMOTEHOST", host->h_name, 1) < 0)
+                       syslog(LOG_WARNING, "setenv(TCPREMOTEHOST):%s\n", 
strerror(errno));
+                   }
+               }
              }
            else
              ctrl = sep->se_fd;
Index: inetutils-1.4.2/inetd/inetd.8
===================================================================
--- inetutils-1.4.2.orig/inetd/inetd.8
+++ inetutils-1.4.2/inetd/inetd.8
@@ -305,6 +305,23 @@ causes
 to list TCPMUX services in
 .Pa inetd.conf .
 .ne 1i
+.Sh "ENVIRONMENT"
+If a connection is made with a streaming protocol (TCP), inetd will set
+the following environment variables before starting the program:
+.Pp
+\fBPROTO\fP: always "TCP".
+.Pp
+\fBTCPLOCALIP\fP: the local IP address of the interface which accepted the 
connection.
+.Pp
+\fBTCPLOCALHOST\fP: the DNS name of \fITCPLOCALIP\fR.
+.Pp
+\fBTCPLOCALPORT\fP: the port number on which the TCP connection was 
established.
+.Pp
+\fBTCPREMOTEIP\fP: the IP address of the remote client.
+.Pp
+\fBTCPREMOTEHOST\fP: the DNS name of \fITCPREMOTEIP\fR.
+.Pp
+\fBTCPREMOTEPORT\fP: the port number on the client side of the TCP connection.
 .Sh "EXAMPLES"
 .Pp
 Here are several example service entries for the various types of services:

reply via email to

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