From 706e3a6863cca4318097b7f62119f2071d270b01 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Tue, 29 Jan 2008 23:08:52 +0100 Subject: [PATCH] service name resolution failed due to byte order problem --- CHANGES | 7 +++++-- VERSION | 2 +- test.sh | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ xio-ip.c | 13 +++++++------ 4 files changed, 61 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index 06386f4..ae8ab5a 100644 --- a/CHANGES +++ b/CHANGES @@ -6,8 +6,11 @@ new features: corrections: exec:...,pty did not kill child process under some circumstances; fixed - by correcting typo in xio-progcall.c (problem reported by - Ralph Forsythe) + by correcting typo in xio-progcall.c (thanks to Ralph Forsythe for + reporting this problem) + + service name resolution failed due to byte order mistake + (thanks to James Sainsbury for reporting this problem) corrected some print statements and variable names diff --git a/VERSION b/VERSION index 7e4ee98..ccae800 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.0+execpty" +"1.6.0.0+execpty+servres" diff --git a/test.sh b/test.sh index 19e271d..26b2698 100755 --- a/test.sh +++ b/test.sh @@ -7848,6 +7848,54 @@ PORT=$((PORT+1)) N=$((N+1)) +# test if service name resolution works; this was buggy in 1.5 and 1.6.0.0 +NAME=TCP4SERVICE +case "$TESTS" in +*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$NAME%*) +TEST="$NAME: echo via connection to TCP V4 socket" +# select a tcp entry from /etc/services, have a server listen on the port +# number and connect using the service name; with the bug, connection will to a +# wrong port +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +# find a service entry we do not need root for (>=1024; here >=1100 for ease) +SERVENT="$(grep '^[a-z][a-z]* *[1-9][1-9][0-9][0-9]/tcp' /etc/services |head -n 1)" +SERVICE="$(echo $SERVENT |cut -d' ' -f1)" +PORT="$(echo $SERVENT |sed 's/.* \([1-9][0-9]*\).*/\1/')" +tsl="$PORT" +ts="127.0.0.1:$SERVICE" +da=$(date) +CMD1="$SOCAT $opts TCP4-LISTEN:$tsl,reuseaddr PIPE" +CMD2="$SOCAT $opts stdin!!stdout TCP4:$ts" +printf "test $F_n $TEST... " $N +$CMD1 >"$tf" 2>"${te}1" & +pid1=$! +waittcp4port $tsl 1 +echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" +if [ $? -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD1 &" + cat "${te}1" + echo "$CMD2" + cat "${te}2" + numFAIL=$((numFAIL+1)) +elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED\n" + cat "$tdiff" + numFAIL=$((numFAIL+1)) +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi + numOK=$((numOK+1)) +fi +kill $pid1 2>/dev/null +wait ;; +esac +#PORT=$((PORT+1)) +N=$((N+1)) + + echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed" if [ "$numFAIL" -gt 0 ]; then diff --git a/xio-ip.c b/xio-ip.c index 0fc02db..df5a5b6 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -1,5 +1,5 @@ /* source: xio-ip.c */ -/* Copyright Gerhard Rieger 2001-2007 */ +/* Copyright Gerhard Rieger 2001-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for IP related functions */ @@ -113,7 +113,7 @@ int xiogetaddrinfo(const char *node, const char *service, int family, int socktype, int protocol, union sockaddr_union *sau, socklen_t *socklen, unsigned long res_opts0, unsigned long res_opts1) { - int port = -1; + int port = -1; /* port number in network byte order */ char *numnode = NULL; size_t nodelen; unsigned long save_res_opts = 0; @@ -144,7 +144,7 @@ int xiogetaddrinfo(const char *node, const char *service, with NIS), so we handle this specially */ if (service && isdigit(service[0]&0xff)) { char *extra; - port = strtoul(service, &extra, 0); + port = htons(strtoul(service, &extra, 0)); if (*extra != '\0') { Warn2("xiogetaddrinfo(, \"%s\", ...): extra trailing data \"%s\"", service, extra); @@ -230,6 +230,7 @@ int xiogetaddrinfo(const char *node, const char *service, #endif return STAT_RETRYLATER; } + service = NULL; /* do not resolve later again */ record = res; if (family == PF_UNSPEC && xioopts.preferred_ip == '0') { @@ -396,15 +397,15 @@ int xiogetaddrinfo(const char *node, const char *service, #if WITH_TCP || WITH_UDP if (service) { - port = parseport(service, family); + port = parseport(service, protocol); } if (port >= 0) { switch (family) { #if WITH_IP4 - case PF_INET: sau->ip4.sin_port = htons(port); break; + case PF_INET: sau->ip4.sin_port = port; break; #endif /* WITH_IP4 */ #if WITH_IP6 - case PF_INET6: sau->ip6.sin6_port = htons(port); break; + case PF_INET6: sau->ip6.sin6_port = port; break; #endif /* WITH_IP6 */ } }