[Top][All Lists]
[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: