03_resolve-port-names.diff
authorGerrit Renker <grenker@cscs.ch>
Thu, 25 Feb 2010 16:05:45 +0000 (17:05 +0100)
committerAndre Noll <maan@systemlinux.org>
Thu, 25 Feb 2010 16:05:45 +0000 (17:05 +0100)
This patch allows to resolve port numbers into names defined
in the services(5) /etc/services database:
 (a) it provides a standalone function which will fall back to
     stringifying a port number;
 (b) it resets the 'numeric service' flag of getnameinfo(3) to
     analogously consider a lookup in /etc/services.

Assuming the following had been added to /etc/services:
para_server_control 2990/tcp # para_server control
paraslash_http_service 8000/tcp        # paraslash http sender
paraslash_dccp_service 8000/dccp       # paraslash dccp sender
paraslash_udp_service 8000/udp        # paraslash udp sender,

then the output of 'para_client si' would look like:

http sender:
        status: on
        port: paraslash_http_service
        ...
dccp sender:
        status: on
        port: paraslash_dccp_service
        ...
udp sender:
        status: on
        port: paraslash_udp_service
        ...

Note: On some systems the service lookup may involve LDAP or NIS lookups,
depending on the 'services' configuration in /etc/nsswitch.conf. This does
not seem to cause a problem, as it implies a working network connection.

net.c
net.h
send_common.c
udp_send.c

diff --git a/net.c b/net.c
index 126b514..6ab9621 100644 (file)
--- a/net.c
+++ b/net.c
@@ -187,6 +187,31 @@ failed:
        return NULL;
 }
 
+/**
+ * Stringify port number, resolve into service name where defined.
+ * \param port 2-byte port number, in host-byte-order.
+ * \param transport Transport protocol name (e.g. "udp", "tcp"), or NULL.
+ * \return Pointer to static result buffer.
+ *
+ * \sa getservent(3), services(5), nsswitch.conf(5)
+ */
+const char *stringify_port(int port, const char *transport)
+{
+       static char service[NI_MAXSERV];
+
+       if (port < 0 || port > 0xFFFF) {
+               snprintf(service, sizeof(service), "undefined (%d)", port);
+       } else {
+               struct servent *se = getservbyport(htons(port), transport);
+
+               if (se == NULL)
+                       snprintf(service, sizeof(service), "%u", port);
+               else
+                       snprintf(service, sizeof(service), "%s", se->s_name);
+       }
+       return service;
+}
+
 /**
  * Determine the socket type for a given layer-4 protocol.
  *
@@ -412,7 +437,7 @@ normalize_ip_address(const struct sockaddr_storage *ss)
  *
  * \param sa The IPv4/IPv6 socket address to use.
  *
- * \sa getnameinfo(3).
+ * \sa getnameinfo(3), services(5), nsswitch.conf(5)
  */
 static char *host_and_port(const struct sockaddr_storage *ss)
 {
@@ -424,7 +449,7 @@ static char *host_and_port(const struct sockaddr_storage *ss)
        ret = getnameinfo(sa, salen(sa),
                          hbuf, sizeof(hbuf),
                          sbuf, sizeof(sbuf),
-                         NI_NUMERICHOST | NI_NUMERICSERV);
+                         NI_NUMERICHOST);
        if (ret == 0) {
                snprintf(output, sizeof(output), "%s#%s", hbuf, sbuf);
        } else {
diff --git a/net.h b/net.h
index 1541258..1f2ebc6 100644 (file)
--- a/net.h
+++ b/net.h
@@ -33,6 +33,7 @@ extern char *parse_cidr(const char *cidr,
                        char *addr, ssize_t addrlen, int32_t *netmask);
 extern char *parse_url(const char *url,
                       char *host, ssize_t hostlen, int32_t *port);
+extern const char *stringify_port(int port, const char *transport);
 /**
  * Ensure that string conforms to the IPv4 address format.
  *
index 2af6a8d..bc6892c 100644 (file)
@@ -231,14 +231,14 @@ char *get_sender_info(struct sender_status *ss, const char *name)
        ret = make_message(
                "%s sender:\n"
                "\tstatus: %s\n"
-               "\tport: %d\n"
+               "\tport: %s\n"
                "\tnumber of connected clients: %d\n"
                "\tmaximal number of clients: %d%s\n"
                "\tconnected clients: %s\n"
                "\taccess %s list: %s\n",
                name,
                (ss->listen_fd >= 0)? "on" : "off",
-               ss->port,
+               stringify_port(ss->port, strcmp(name, "http") ? "dccp" : "tcp"),
                ss->num_clients,
                ss->max_clients,
                ss->max_clients > 0? "" : " (unlimited)",
index 77b5819..7c4a840 100644 (file)
@@ -303,10 +303,10 @@ static char *udp_info(void)
        ret = make_message(
                "udp sender:\n"
                "\tstatus: %s\n"
-               "\tport: %d\n"
+               "\tport: %s\n"
                "\ttargets: %s\n",
                (sender_status == SENDER_ON)? "on" : "off",
-               conf.udp_default_port_arg,
+               stringify_port(conf.udp_default_port_arg, "udp"),
                tgts? tgts : "(none)"
        );
        free(tgts);