diff --git a/CHANGES b/CHANGES index 3606959..406c48a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,9 @@ +corrections: + there was a bug in ip*-recv with bind option: it did not bind, and + with the first received packet an error occurred: + socket_init(): unknown address family 0 + ####################### V 1.6.0.1: new features: diff --git a/VERSION b/VERSION index 8821d46..ec9f0dd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.6.0.1" +"1.6.0.1+ip4bind" diff --git a/test.sh b/test.sh index 7876223..05e9957 100755 --- a/test.sh +++ b/test.sh @@ -8141,6 +8141,60 @@ PORT=$((PORT+1)) N=$((N+1)) +# test: there was a bug with ip*-recv and bind option: it would not bind, and +# with the first received packet an error: +# socket_init(): unknown address family 0 +# occurred +NAME=RAWIP4RECVBIND +case "$TESTS" in +*%functions%*|*%ip4%*|*%dgram%*|*%rawip%*|*%rawip4%*|*%recv%*|*%root%*|*%$NAME%*) +TEST="$NAME: raw IPv4 receive with bind" +# idea: start a socat process with ip4-recv:...,bind=... and send it a packet +# if the packet passes the test succeeded +if [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N + numCANT=$((numCANT+1)) +else +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +ts1p=$PROTO; PROTO=$((PROTO+1)) +ts1a="127.0.0.1" +ts1="$ts1a:$ts1p" +da=$(date) +CMD1="$SOCAT $opts -u IP4-RECV:$ts1p,bind=$ts1a,reuseaddr -" +CMD2="$SOCAT $opts -u - IP4-SENDTO:$ts1" +printf "test $F_n $TEST... " $N +$CMD1 >"$tf" 2>"${te}1" & +pid1="$!" +waitip4proto $ts1p 1 +echo "$da" |$CMD2 2>>"${te}2" +rc2="$?" +#ls -l $tf +i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done +kill "$pid1" 2>/dev/null; wait +if [ "$rc2" -ne 0 ]; then + $PRINTF "$FAILED: $SOCAT:\n" + echo "$CMD1 &" + echo "$CMD2" + cat "${te}1" + 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; fi + numOK=$((numOK+1)) +fi +fi # must be root ;; +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-rawip.c b/xio-rawip.c index 1fe7450..d88da13 100644 --- a/xio-rawip.c +++ b/xio-rawip.c @@ -253,6 +253,7 @@ int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, int pf, int socktype, int dummy3) { const char *protname = argv[1]; char *garbage; + bool needbind = false; union sockaddr_union us; socklen_t uslen = sizeof(us); int ipproto; @@ -286,16 +287,18 @@ int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, #endif } - if (retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, 1, + if (retropt_bind(opts, pf, socktype, ipproto, &/*us.soa*/xfd->stream.para.socket.la.soa, &uslen, 1, xfd->stream.para.socket.ip.res_opts[0], - xfd->stream.para.socket.ip.res_opts[1]) != + xfd->stream.para.socket.ip.res_opts[1]) == STAT_OK) { + needbind = true; + } else { /* pf is required during xioread checks */ xfd->stream.para.socket.la.soa.sa_family = pf; } xfd->stream.dtype = XIODATA_RECV_SKIPIP; - result = _xioopen_dgram_recv(&xfd->stream, xioflags, NULL/*&us.soa*/, uslen, + result = _xioopen_dgram_recv(&xfd->stream, xioflags, &/*us.soa*/xfd->stream.para.socket.la.soa, uslen, opts, pf, socktype, ipproto, E_ERROR); _xio_openlate(&xfd->stream, opts); return result;