aboutsummaryrefslogtreecommitdiff
path: root/net/socat
diff options
context:
space:
mode:
authorPav Lucistnik <pav@FreeBSD.org>2007-06-06 13:46:45 +0000
committerPav Lucistnik <pav@FreeBSD.org>2007-06-06 13:46:45 +0000
commit83521b52d030d78daee3bf73adb511de267d3f51 (patch)
tree3924d4ac5c1247de87ba6b0814c39f3b673fdcc5 /net/socat
parent9cb65ef1329a9fc6fbc9670e1d31f3f3ef365ff8 (diff)
Notes
Diffstat (limited to 'net/socat')
-rw-r--r--net/socat/Makefile1
-rw-r--r--net/socat/files/patch-socat-maxfds442
-rw-r--r--net/socat/files/patch-socat-servicenames31
3 files changed, 474 insertions, 0 deletions
diff --git a/net/socat/Makefile b/net/socat/Makefile
index 36b5413ed3d7..5fe7f40889ab 100644
--- a/net/socat/Makefile
+++ b/net/socat/Makefile
@@ -8,6 +8,7 @@
PORTNAME= socat
PORTVERSION= 1.6.0.0
+PORTREVISION= 1
CATEGORIES= net
MASTER_SITES= http://www.dest-unreach.org/socat/download/
diff --git a/net/socat/files/patch-socat-maxfds b/net/socat/files/patch-socat-maxfds
new file mode 100644
index 000000000000..424a5942ea27
--- /dev/null
+++ b/net/socat/files/patch-socat-maxfds
@@ -0,0 +1,442 @@
+diff -r -N -U 3 socat-1.6.0.0/procan.c socat-1.6.0.0+maxfds/procan.c
+--- procan.c.orig 2006-12-28 08:25:01.000000000 +0100
++++ procan.c 2007-04-05 12:41:26.000000000 +0200
+@@ -161,6 +161,10 @@
+ #endif
+ }
+
++ /* C defines */
++ fprintf(outfile, "#define FD_SETSIZE %u\n", FD_SETSIZE);
++ fprintf(outfile, "#define FOPEN_MAX %u\n", FOPEN_MAX);
++
+ /* file descriptors */
+
+ /* what was this for?? */
+diff -r -N -U 3 socat-1.6.0.0/socat.c socat-1.6.0.0+maxfds/socat.c
+--- socat.c.orig 2007-03-06 22:03:28.000000000 +0100
++++ socat.c 2007-03-31 22:24:37.000000000 +0200
+@@ -642,8 +642,8 @@
+ returns >0 if child died and left data
+ */
+ int childleftdata(xiofile_t *xfd) {
+- fd_set in, out, expt;
+- int retval;
++ fd_set *in = NULL, *out = NULL, *expt = NULL;
++ int max, retval;
+ /* have to check if a child process died before, but left read data */
+ if (XIO_READABLE(xfd) &&
+ (XIO_RDSTREAM(xfd)->howtoend == END_KILL ||
+@@ -652,25 +652,59 @@
+ XIO_RDSTREAM(xfd)->para.exec.pid == 0) {
+ struct timeval time0 = { 0,0 };
+
+- FD_ZERO(&in); FD_ZERO(&out); FD_ZERO(&expt);
++#ifndef howmany
++#define howmany(x, y) (((x) + ((y) - 1)) / (y))
++#endif
++
++#ifndef NFDBITS
++# ifndef HAVE_FDS_BITS
++# define NFDBITS (sizeof(__fd_mask) * 8)
++# else
++# define NFDBITS (sizeof(fd_mask) * 8)
++# endif
++#endif
++
++#ifndef HAVE_FDS_BITS
++# define FD_MASK_SIZE (sizeof(__fd_mask))
++#else
++# define FD_MASK_SIZE (sizeof(fd_mask))
++#endif
++
++ max = XIO_GETRDFD(xfd);
++ in = (fd_set *)Calloc(howmany(max+1, NFDBITS), FD_MASK_SIZE);
++ out = (fd_set *)Calloc(howmany(max+1, NFDBITS), FD_MASK_SIZE);
++ expt = (fd_set *)Calloc(howmany(max+1, NFDBITS), FD_MASK_SIZE);
++ if (in == NULL || out == NULL || expt == NULL) {
++ Error2("select(%d): %s", max+1, strerror(errno));
++ if (in != NULL)
++ free(in);
++ if (out != NULL)
++ free(out);
++ if (expt != NULL)
++ free(expt);
++ return -1;
++ }
+ if (XIO_READABLE(xfd) && !(XIO_RDSTREAM(xfd)->eof >= 2 && !XIO_RDSTREAM(xfd)->ignoreeof)) {
+- FD_SET(XIO_GETRDFD(xfd), &in);
++ FD_SET(XIO_GETRDFD(xfd), in);
+ /*0 FD_SET(XIO_GETRDFD(xfd), &expt);*/
+ }
+ do {
+- retval = Select(FOPEN_MAX, &in, &out, &expt, &time0);
++ retval = Select(max+1, in, out, expt, &time0);
+ } while (retval < 0 && errno == EINTR);
+
+ if (retval < 0) {
+ #if HAVE_FDS_BITS
+ Error5("select(%d, &0x%lx, &0x%lx, &0x%lx, {0}): %s",
+- FOPEN_MAX, in.fds_bits[0], out.fds_bits[0],
+- expt.fds_bits[0], strerror(errno));
++ max+1, in->fds_bits[0], out->fds_bits[0],
++ expt->fds_bits[0], strerror(errno));
+ #else
+ Error5("select(%d, &0x%lx, &0x%lx, &0x%lx, {0}): %s",
+- FOPEN_MAX, in.__fds_bits[0], out.__fds_bits[0],
+- expt.__fds_bits[0], strerror(errno));
++ max+1, in->__fds_bits[0], out->__fds_bits[0],
++ expt->__fds_bits[0], strerror(errno));
+ #endif
++ free(in);
++ free(out);
++ free(expt);
+ return -1;
+ } else if (retval == 0) {
+ Info("terminated child did not leave data for us");
+@@ -679,6 +713,9 @@
+ closing = MAX(closing, 1);
+ }
+ }
++ free(in);
++ free(out);
++ free(expt);
+ return 0;
+ }
+
+@@ -694,14 +731,34 @@
+ and their options are set/applied
+ returns -1 on error or 0 on success */
+ int _socat(void) {
+- fd_set in, out, expt;
+- int retval;
++ fd_set *in, *out, *expt;
++ int max, retval;
+ unsigned char *buff;
+ ssize_t bytes1, bytes2;
+ int polling = 0; /* handling ignoreeof */
+ int wasaction = 1; /* last select was active, do NOT sleep before next */
+ struct timeval total_timeout; /* the actual total timeout timer */
+
++#ifndef MAX
++# define MAX(x, y) (((y) > (x)) ? (y) : (x))
++#endif
++
++ max = MAX(
++ MAX(XIO_GETRDFD(sock1), XIO_GETWRFD(sock1)),
++ MAX(XIO_GETRDFD(sock2), XIO_GETWRFD(sock2)));
++ in = (fd_set *)Calloc(howmany(max+1, NFDBITS), FD_MASK_SIZE);
++ out = (fd_set *)Calloc(howmany(max+1, NFDBITS), FD_MASK_SIZE);
++ expt = (fd_set *)Calloc(howmany(max+1, NFDBITS), FD_MASK_SIZE);
++ if (in == NULL || out == NULL || expt == NULL) {
++ Error2("select(%d): %s", max+1, strerror(errno));
++ if (in != NULL)
++ free(in);
++ if (out != NULL)
++ free(out);
++ if (expt != NULL)
++ free(expt);
++ return -1;
++ }
+ #if WITH_FILAN
+ if (socat_opts.debug) {
+ int fdi, fdo;
+@@ -733,7 +790,7 @@
+
+ /* when converting nl to crnl, size might double */
+ buff = Malloc(2*socat_opts.bufsiz+1);
+- if (buff == NULL) return -1;
++ if (buff == NULL) { free(in); free(out); free(expt); return -1; }
+
+ if (socat_opts.logopt == 'm' && xioinqopt('l', NULL, 0) == 'm') {
+ Info("switching to syslog");
+@@ -772,6 +829,9 @@
+ if (total_timeout.tv_sec < 0 ||
+ total_timeout.tv_sec == 0 && total_timeout.tv_usec < 0) {
+ Notice("inactivity timeout triggered");
++ free(in);
++ free(out);
++ free(expt);
+ return 0;
+ }
+ }
+@@ -803,7 +863,9 @@
+
+ do {
+ int _errno;
+- FD_ZERO(&in); FD_ZERO(&out); FD_ZERO(&expt);
++ memset(in, 0, howmany(max+1, NFDBITS) * FD_MASK_SIZE);
++ memset(out, 0, howmany(max+1, NFDBITS) * FD_MASK_SIZE);
++ memset(expt, 0, howmany(max+1, NFDBITS) * FD_MASK_SIZE);
+
+ childleftdata(sock1);
+ childleftdata(sock2);
+@@ -819,23 +881,23 @@
+ !(XIO_RDSTREAM(sock1)->eof > 1 && !XIO_RDSTREAM(sock1)->ignoreeof) &&
+ !socat_opts.righttoleft) {
+ if (!mayrd1) {
+- FD_SET(XIO_GETRDFD(sock1), &in);
++ FD_SET(XIO_GETRDFD(sock1), in);
+ }
+ if (!maywr2) {
+- FD_SET(XIO_GETWRFD(sock2), &out);
++ FD_SET(XIO_GETWRFD(sock2), out);
+ }
+ }
+ if (XIO_READABLE(sock2) &&
+ !(XIO_RDSTREAM(sock2)->eof > 1 && !XIO_RDSTREAM(sock2)->ignoreeof) &&
+ !socat_opts.lefttoright) {
+ if (!mayrd2) {
+- FD_SET(XIO_GETRDFD(sock2), &in);
++ FD_SET(XIO_GETRDFD(sock2), in);
+ }
+ if (!maywr1) {
+- FD_SET(XIO_GETWRFD(sock1), &out);
++ FD_SET(XIO_GETWRFD(sock1), out);
+ }
+ }
+- retval = Select(FOPEN_MAX, &in, &out, &expt, to);
++ retval = Select(max+1, in, out, expt, to);
+ _errno = errno;
+ if (retval < 0 && errno == EINTR) {
+ Info1("select(): %s", strerror(errno));
+@@ -851,15 +913,18 @@
+ if (retval < 0) {
+ #if HAVE_FDS_BITS
+ Error7("select(%d, &0x%lx, &0x%lx, &0x%lx, %s%lu): %s",
+- FOPEN_MAX, in.fds_bits[0], out.fds_bits[0],
+- expt.fds_bits[0], to?"&":"NULL/", to?to->tv_sec:0,
++ max+1, in->fds_bits[0], out->fds_bits[0],
++ expt->fds_bits[0], to?"&":"NULL/", to?to->tv_sec:0,
+ strerror(errno));
+ #else
+ Error7("select(%d, &0x%lx, &0x%lx, &0x%lx, %s%lu): %s",
+- FOPEN_MAX, in.__fds_bits[0], out.__fds_bits[0],
+- expt.__fds_bits[0], to?"&":"NULL/", to?to->tv_sec:0,
++ max+1, in->__fds_bits[0], out->__fds_bits[0],
++ expt->__fds_bits[0], to?"&":"NULL/", to?to->tv_sec:0,
+ strerror(errno));
+ #endif
++ free(in);
++ free(out);
++ free(expt);
+ return -1;
+ } else if (retval == 0) {
+ Info2("select timed out (no data within %ld.%06ld seconds)",
+@@ -872,6 +937,9 @@
+ socat_opts.total_timeout.tv_usec != 0) {
+ /* there was a total inactivity timeout */
+ Notice("inactivity timeout triggered");
++ free(in);
++ free(out);
++ free(expt);
+ return 0;
+ }
+
+@@ -884,17 +952,17 @@
+ }
+
+ if (XIO_READABLE(sock1) && XIO_GETRDFD(sock1) >= 0 &&
+- FD_ISSET(XIO_GETRDFD(sock1), &in)) {
++ FD_ISSET(XIO_GETRDFD(sock1), in)) {
+ mayrd1 = true;
+ }
+ if (XIO_READABLE(sock2) && XIO_GETRDFD(sock2) >= 0 &&
+- FD_ISSET(XIO_GETRDFD(sock2), &in)) {
++ FD_ISSET(XIO_GETRDFD(sock2), in)) {
+ mayrd2 = true;
+ }
+- if (XIO_GETWRFD(sock1) >= 0 && FD_ISSET(XIO_GETWRFD(sock1), &out)) {
++ if (XIO_GETWRFD(sock1) >= 0 && FD_ISSET(XIO_GETWRFD(sock1), out)) {
+ maywr1 = true;
+ }
+- if (XIO_GETWRFD(sock2) >= 0 && FD_ISSET(XIO_GETWRFD(sock2), &out)) {
++ if (XIO_GETWRFD(sock2) >= 0 && FD_ISSET(XIO_GETWRFD(sock2), out)) {
+ maywr2 = true;
+ }
+
+@@ -989,6 +1057,10 @@
+ xioclose(sock1);
+ xioclose(sock2);
+
++ free(in);
++ free(out);
++ free(expt);
++
+ return 0;
+ }
+
+diff -r -N -U 3 socat-1.6.0.0/test.sh socat-1.6.0.0+maxfds/test.sh
+--- test.sh.orig 2007-03-06 22:06:20.000000000 +0100
++++ test.sh 2007-04-06 10:16:30.000000000 +0200
+@@ -1425,7 +1425,8 @@
+ local arg1="$3"; [ -z "$arg1" ] && arg1="-"
+ local arg2="$4"; [ -z "$arg2" ] && arg2="echo"
+ local opts="$5"
+- local T="$6"; [ -z "$T" ] && T=0
++ local redir="$6"
++ local T="$7"; [ -z "$T" ] && T=0
+ local tf="$td/test$N.stdout"
+ local te="$td/test$N.stderr"
+ local tdiff="$td/test$N.diff"
+@@ -1435,14 +1436,16 @@
+ $PRINTF "test $F_n %s... " $num "$title"
+ #echo "$da" |$cmd >"$tf" 2>"$te"
+ #set -vx
+- (echo "$da"; sleep $T) |$SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te" &
++# (echo "$da"; sleep $T) |($SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"; echo $? >"$td/test$N.rc") &
++# echo eval $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te" $redir
++ (echo "$da"; sleep $T) |(eval $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te" $redir; echo $? >"$td/test$N.rc") &
+ export rc1=$!
+ #sleep 5 && kill $rc1 2>/dev/null &
+ # rc2=$!
+ wait $rc1
+ # kill $rc2 2>/dev/null
+-#set +vx
+- if [ "$?" != 0 ]; then
++set +vx
++ if [ "$(cat "$td/test$N.rc")" != 0 ]; then
+ $PRINTF "$FAILED: $SOCAT:\n"
+ echo "$SOCAT $opts $arg1 $arg2"
+ cat "$te"
+@@ -4129,7 +4132,7 @@
+ case "$TESTS" in
+ *%functions%*|*%$NAME%*)
+ TEST="$NAME: inheritance of stdout to single exec with socketpair"
+-testecho "$N" "$TEST" "-!!exec:cat" "" "$opts" 1
++testecho "$N" "$TEST" "-!!exec:cat" "" "$opts" "" 1
+ esac
+ N=$((N+1))
+
+@@ -4137,7 +4140,7 @@
+ case "$TESTS" in
+ *%functions%*|*%$NAME%*)
+ TEST="$NAME: inheritance of stdout to single exec with pipe"
+-testecho "$N" "$TEST" "-!!exec:cat,pipes" "" "$opts" 1
++testecho "$N" "$TEST" "-!!exec:cat,pipes" "" "$opts" "" 1
+ esac
+ N=$((N+1))
+
+@@ -4149,7 +4152,7 @@
+ $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
+ numCANT=$((numCANT+1))
+ else
+-testecho "$N" "$TEST" "-!!exec:cat,pty,raw" "" "$opts" 1
++testecho "$N" "$TEST" "-!!exec:cat,pty,raw" "" "$opts" "" 1
+ fi
+ esac
+ N=$((N+1))
+@@ -4178,7 +4181,7 @@
+ $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
+ numCANT=$((numCANT+1))
+ else
+-testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" $MISCDELAY
++testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" "" $MISCDELAY
+ fi
+ esac
+ N=$((N+1))
+@@ -5662,7 +5665,7 @@
+ case "$TESTS" in
+ *%parse%*|*%functions%*|*%$NAME%*)
+ TEST="$NAME: does lexical analysis work sensibly (exec)"
+-testecho "$N" "$TEST" "" "exec:'$SOCAT - exec:$CAT,pipes'" "$opts" 1
++testecho "$N" "$TEST" "" "exec:'$SOCAT - exec:$CAT,pipes'" "$opts" "" 1
+ esac
+ N=$((N+1))
+
+@@ -5670,7 +5673,7 @@
+ case "$TESTS" in
+ *%parse%*|*%functions%*|*%$NAME%*)
+ TEST="$NAME: does lexical analysis work sensibly (system)"
+-testecho "$N" "$TEST" "" "system:\"$SOCAT - exec:$CAT,pipes\"" "$opts" 1
++testecho "$N" "$TEST" "" "system:\"$SOCAT - exec:$CAT,pipes\"" "$opts" "" 1
+ esac
+ N=$((N+1))
+
+@@ -7737,6 +7740,81 @@
+ esac
+ N=$((N+1))
+
++
++# test: up to socat 1.6.0.0, the highest file descriptor supported in socats
++# transfer engine was FOPEN_MAX-1; this usually worked fine but would fail when
++# socat was invoked with many file descriptors already opened. socat would
++# just hang in the select() call. Daniel Lucq found this problem and provided a
++# patch that replaced the FOPEN_MAX limit: this patch not only allows FDs to be
++# up to NFDBITS-1, but should work even when the processes maximum number of
++# open files is increased with ulimit -n.
++# FOPEN_MAX on different OS's:
++# OS FOPEN_ ulimit ulimit FD_
++# MAX -H -n -S -n SETSIZE
++# Linux 2.6: 16 1024 1024 1024
++# HP-UX 11.11: 60 2048 2048 2048
++# FreeBSD: 20 11095 11095 1024
++# Cygwin: 20 unlimit 256 64
++# AIX: 32767 65534 65534
++NAME=EXCEED_FOPEN_MAX
++case "$TESTS" in
++*%functions%*|*%maxfds%*|*%$NAME%*)
++TEST="$NAME: more than FOPEN_MAX FDs in use"
++# this test opens a number of FDs before socat is invoked. socat will have to
++# allocate higher FD numbers and thus hang if it cannot handle them.
++REDIR=
++FOPEN_MAX=$($PROCAN |grep '^#define FOPEN_MAX' |awk '{print($3);}')
++OPEN_FILES=$FOPEN_MAX # more than the highest FOPEN_MAX
++i=3; while [ "$i" -lt "$OPEN_FILES" ]; do
++ REDIR="$REDIR $i>&2"
++ i=$((i+1))
++done
++#echo $REDIR
++#testecho "$N" "$TEST" "" "pipe" "$opts -T 3" "" 1
++#set -vx
++testecho "$N" "$TEST" "" "pipe" "$opts -T 1" "$REDIR" 1
++#set +vx
++esac
++N=$((N+1))
++
++OPEN_FILES="$(ulimit -n)"
++NAME=EXCEED_FD_SETSIZE
++case "$TESTS" in
++*%functions%*|*%maxfds%*|*%root%*|*%$NAME%*)
++TEST="$NAME: more than FD_SETSIZE FDs in use"
++# this test opens a number of FDs before socat is invoked. This number exceeds
++# the size of the fd_set type proposed for use with select(). socat will have
++# to allocate space for a larger record and will hang or crash if it cannot
++# handle this.
++# ulimit -n must be above FD_SETSIZE which might require root
++REDIR=
++FD_SETSIZE=$($PROCAN |grep '^#define FD_SETSIZE' |awk '{print($3);}')
++OPEN_FILES=$(($FD_SETSIZE+2)) # more than the highest FD_SETSIZE
++while true; do # just go once; so we can break inside
++ if [ $(ulimit -S -n) -lt $OPEN_FILES ]; then
++ # if it increases, -H must be first
++ if [ $(ulimit -H -n) -lt $OPEN_FILES ]; then
++ if ! ulimit -H -n $((OPEN_FILES)); then
++ $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
++ numCANT=$((numCANT+1))
++ break;
++ fi
++ fi
++ ulimit -S -n $((OPEN_FILES))
++ fi
++ i=3; while [ "$i" -lt "$FD_SETSIZE" ]; do
++ REDIR="$REDIR $i>&2"
++ i=$((i+1))
++ done
++ testecho "$N" "$TEST" "" "pipe" "$opts -T 1" "$REDIR" 1
++ set +vx
++break
++done
++;;
++esac
++N=$((N+1))
++
++
+ echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed"
+
+ if [ "$numFAIL" -gt 0 ]; then
+diff -r -N -U 3 socat-1.6.0.0/VERSION socat-1.6.0.0+maxfds/VERSION
+--- VERSION.orig 2007-03-06 21:58:44.000000000 +0100
++++ VERSION 2007-04-06 23:20:11.000000000 +0200
+@@ -1 +1 @@
+-"1.6.0.0"
++"1.6.0.0_1"
diff --git a/net/socat/files/patch-socat-servicenames b/net/socat/files/patch-socat-servicenames
new file mode 100644
index 000000000000..f00d72c743af
--- /dev/null
+++ b/net/socat/files/patch-socat-servicenames
@@ -0,0 +1,31 @@
+--- xio-ip.c.orig Wed Mar 7 08:08:02 2007
++++ xio-ip.c Fri Apr 27 17:10:02 2007
+@@ -144,7 +144,7 @@
+ 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);
+@@ -396,15 +396,16 @@
+
+ #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 */
+ }
+ }