From 08b4c1b62d83e941eef14187e058a7e42ad094ac4113eee815670a2d76f8fa9e Mon Sep 17 00:00:00 2001 From: Marcus Meissner Date: Tue, 18 Jun 2024 13:13:44 +0000 Subject: [PATCH] - 0004-udp-listen-bind4.patch: fixed a UDP listen error (bsc#1226459) OBS-URL: https://build.opensuse.org/package/show/network:utilities/socat?expand=0&rev=66 --- 0004-udp-listen-bind4.patch | 275 ++++++++++++++++++++++++++++++++++++ socat.changes | 5 + socat.spec | 2 + 3 files changed, 282 insertions(+) create mode 100644 0004-udp-listen-bind4.patch diff --git a/0004-udp-listen-bind4.patch b/0004-udp-listen-bind4.patch new file mode 100644 index 0000000..07edf4e --- /dev/null +++ b/0004-udp-listen-bind4.patch @@ -0,0 +1,275 @@ +diff --git a/CHANGES b/CHANGES +index 5afbc74..fdc6b04 100644 +--- a/CHANGES ++++ b/CHANGES +@@ -1,4 +1,10 @@ +  ++Corrections: ++ With version 1.8.0.0, the following command failed: ++ socat UDP-LISTEN:1234,fork,reuseaddr,bind=127.0.0.1 - ++ Message: "E xioopen_ipdgram_listen(): unknown address family 0": ++ Thanks to Brian Woo for reporting this issue. ++ + ####################### V 1.8.0.0 + + Security: +diff --git a/test.sh b/test.sh +index f70ad89..1d5298b 100755 +--- a/test.sh ++++ b/test.sh +@@ -2977,19 +2977,21 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" + rc2=$? + kill $pid1 2>/dev/null; wait + if [ $rc2 -ne 0 ]; then +- $PRINTF "$FAILED: $TRACE $SOCAT:\n" ++ $PRINTF "$FAILED (rc2=$rc2)\n" + echo "$CMD1 &" ++ cat "${te}1" >&2 + echo "$CMD2" +- cat "${te}1" "${te}2" ++ cat "${te}2" >&2 + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" + elif ! echo "$da" |diff - "$tf" >"$tdiff"; then +- $PRINTF "$FAILED\n" ++ $PRINTF "$FAILED (diff)\n" + echo "$CMD1 &" +- cat "${te}1" ++ cat "${te}1" >&2 + echo "$CMD2" +- cat "${te}2" +- cat "$tdiff" ++ cat "${te}2" >&2 ++ echo "// diff:" >&2 ++ cat "$tdiff" >&2 + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" + else +@@ -3028,15 +3030,21 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" + rc2=$? + kill $pid1 2>/dev/null; wait + if [ $rc2 -ne 0 ]; then +- $PRINTF "$FAILED: $TRACE $SOCAT:\n" ++ $PRINTF "$FAILED (rc2=$rc2)\n" + echo "$CMD1 &" ++ cat "${te}1" >&2 + echo "$CMD2" +- cat "${te}1" "${te}2" ++ cat "${te}2" >&2 + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" + elif ! echo "$da" |diff - "$tf" >"$tdiff"; then +- $PRINTF "$FAILED\n" +- cat "$tdiff" ++ $PRINTF "$FAILED (diff)\n" ++ echo "$CMD1 &" ++ cat "${te}1" >&2 ++ echo "$CMD2" ++ cat "${te}2" >&2 ++ echo "// diff:" >&2 ++ cat "$tdiff" >&2 + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" + else +@@ -19154,6 +19162,76 @@ esac + N=$((N+1)) + + ++# Test UDP-LISTEN with bind to IPv4 address; this failed with Socat version ++# 1.8.0.0 ++NAME=UDP_LISTEN_BIND4 ++case "$TESTS" in ++*%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%ip4%*|*%udp%*|*%udp4%*|*%listen%*|*%$NAME%*) ++TEST="$NAME: Test UDP-LISTEN with bind to IPv4 addr" ++# Start a listener with UDP-LISTEN and bind to 127.0.0.1; when it starts ++# without error and even processes data the test succeeded ++if ! eval $NUMCOND; then : ++# Remove unneeded checks, adapt lists of the remaining ones ++elif ! cond=$(checkconds \ ++ "" \ ++ "" \ ++ "" \ ++ "IP4 UDP LISTEN STDIO PIPE" \ ++ "UDP-LISTEN PIPE STDIO UDP" \ ++ "bind" \ ++ "udp4" ); then ++ $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N ++ numCANT=$((numCANT+1)) ++ listCANT="$listCANT $N" ++ namesCANT="$namesCANT $NAME" ++else ++ tf="$td/test$N.stdout" ++ te="$td/test$N.stderr" ++ tdiff="$td/test$N.diff" ++ da="test$N $(date) $RANDOM" ++ newport udp4 ++ CMD0="$TRACE $SOCAT $opts UDP-LISTEN:$PORT,bind=$LOCALHOST4 PIPE" ++ CMD1="$TRACE $SOCAT $opts - UDP-CONNECT:$LOCALHOST4:$PORT" ++ printf "test $F_n $TEST... " $N ++ $CMD0 >/dev/null 2>"${te}0" & ++ pid0=$! ++ waitudp4port $PORT 1 ++ echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" ++ rc1=$? ++ kill $pid0 2>/dev/null; wait ++ if [ "$rc1" -ne 0 ]; then ++ $PRINTF "$FAILED (rc1=$rc1)\n" ++ echo "$CMD0 &" ++ cat "${te}0" >&2 ++ echo "$CMD1" ++ cat "${te}1" >&2 ++ numFAIL=$((numFAIL+1)) ++ listFAIL="$listFAIL $N" ++ namesFAIL="$namesFAIL $NAME" ++ elif ! echo "$da" |diff - "${tf}1" >$tdiff; then ++ $PRINTF "$FAILED (diff)\n" ++ echo "$CMD0 &" ++ cat "${te}0" >&2 ++ echo "$CMD1" ++ cat "${te}1" >&2 ++ echo "// diff:" >&2 ++ cat "$tdiff" >&2 ++ numFAIL=$((numFAIL+1)) ++ listFAIL="$listFAIL $N" ++ namesFAIL="$namesFAIL $NAME" ++ else ++ $PRINTF "$OK\n" ++ if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi ++ if [ "$DEBUG" ]; then cat "${te}0" >&2; fi ++ if [ "$VERBOSE" ]; then echo "$CMD1"; fi ++ if [ "$DEBUG" ]; then cat "${te}1" >&2; fi ++ numOK=$((numOK+1)) ++ fi ++fi # NUMCOND ++ ;; ++esac ++N=$((N+1)) ++ + # end of common tests + + ################################################################################## +diff --git a/xio-socket.c b/xio-socket.c +index c869b6d..ed10a99 100644 +--- a/xio-socket.c ++++ b/xio-socket.c +@@ -262,7 +262,7 @@ static int xioopen_socket_connect( + sfd->dtype = XIOREAD_STREAM|XIOWRITE_STREAM; + + socket_init(0, &us); +- if (retropt_bind(opts, 0 /*pf*/, socktype, proto, (struct sockaddr *)&us, &uslen, 3, ++ if (retropt_bind(opts, pf, socktype, proto, (struct sockaddr *)&us, &uslen, 0, + sfd->para.socket.ip.ai_flags) + != STAT_NOACTION) { + needbind = true; +diff --git a/xio-udp.c b/xio-udp.c +index b624281..d511122 100644 +--- a/xio-udp.c ++++ b/xio-udp.c +@@ -277,8 +277,10 @@ int xioopen_ipdgram_listen( + int pf = addrdesc->arg1; + int ipproto = addrdesc->arg2; + union sockaddr_union us; ++ int bind_rc; + int socktype = SOCK_DGRAM; + socklen_t uslen; ++ int result; + + if (argc != 2) { + xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); +@@ -308,12 +310,31 @@ int xioopen_ipdgram_listen( + applyopts(sfd, -1, opts, PH_INIT); + + uslen = socket_init(pf, &us); +- retropt_bind(opts, pf, socktype, ipproto, ++ bind_rc = retropt_bind(opts, pf, socktype, ipproto, + (struct sockaddr *)&us, &uslen, 1, + xfd->stream.para.socket.ip.ai_flags); ++ if (bind_rc == STAT_NORETRY) ++ return STAT_NORETRY; ++ if (pf == PF_UNSPEC && bind_rc == STAT_OK) ++ pf = us.soa.sa_family; + + if (false) { + ; ++#if WITH_IP4 || WITH_IP6 ++ } else if (pf == PF_UNSPEC && bind_rc == STAT_NOACTION) { ++ int ai_flags[2]; ++ ai_flags[0] = sfd->para.socket.ip.ai_flags[0]; ++ ai_flags[1] = sfd->para.socket.ip.ai_flags[1]; ++ if (!(ai_flags[1] & AI_PASSIVE)) ++ ai_flags[0] |= AI_PASSIVE; ++ result = ++ xioresolve(NULL, portname, pf, socktype, ipproto, &us, &uslen, ai_flags); ++ if (result != STAT_OK) { ++ Error("error resolving bind option"); ++ return STAT_NORETRY; ++ } ++ pf = us.soa.sa_family; ++#endif /* WITH_IP4 || WITH_IP6*/ + #if WITH_IP4 + } else if (pf == PF_INET) { + us.ip4.sin_port = parseport(portname, ipproto); +@@ -323,7 +344,9 @@ int xioopen_ipdgram_listen( + us.ip6.sin6_port = parseport(portname, ipproto); + #endif + } else { ++#if 1 + Error1("xioopen_ipdgram_listen(): unknown address family %d", pf); ++#endif + } + + return _xioopen_ipdgram_listen(&xfd->stream, xioflags, &us, uslen, +diff --git a/xioopts.c b/xioopts.c +index 4b651aa..abf4ffe 100644 +--- a/xioopts.c ++++ b/xioopts.c +@@ -3252,6 +3252,7 @@ int retropt_bind(struct opt *opts, + UNIX (or'd): 1..tight + 2..abstract + 4..templatename ++ 0..generic addr spec + */ + const int ai_flags[2]) + { +@@ -3271,10 +3272,13 @@ int retropt_bind(struct opt *opts, + } + bindp = bindname; + +- switch (af) { ++#if WITH_IP4 && WITH_IP6 ++ /* Try to derive address family from string */ ++ if (af == AF_UNSPEC && bindname[0] == '[') ++ af = AF_INET6; ++#endif /* WITH_IP4 && WITH_IP6 */ + +- case AF_UNSPEC: +- { ++ if (feats == 0) { + size_t p = 0; + dalan(bindname, (uint8_t *)sa->sa_data, &p, *salen-sizeof(sa->sa_family), 'i'); + *salen = p + sizeof(sa->sa_family); +@@ -3286,10 +3290,13 @@ int retropt_bind(struct opt *opts, + #if HAVE_STRUCT_SOCKADDR_SALEN + sa->sa_len = *salen; + #endif +- } +- break; ++ return STAT_OK; ++ } ++ ++ switch (af) { + + #if WITH_IP4 || WITH_IP6 || WITH_VSOCK ++ case AF_UNSPEC: + #if WITH_VSOCK + case AF_VSOCK: + #endif +@@ -3324,7 +3331,7 @@ int retropt_bind(struct opt *opts, + ai_flags2[0] = ai_flags[0]; + ai_flags2[1] = ai_flags[1]; + if (!(ai_flags2[1] & AI_PASSIVE)) +- ai_flags2[0] |= AI_PASSIVE; ++ ai_flags2[0] |= AI_PASSIVE; + + if ((result = + xioresolve(hostname[0]!='\0'?hostname:NULL, portp, diff --git a/socat.changes b/socat.changes index 06fbc1e..59582c6 100644 --- a/socat.changes +++ b/socat.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Tue Jun 18 12:42:37 UTC 2024 - Marcus Meissner + +- 0004-udp-listen-bind4.patch: fixed a UDP listen error (bsc#1226459) + ------------------------------------------------------------------- Wed May 1 18:50:03 UTC 2024 - Georg Pfuetzenreuter diff --git a/socat.spec b/socat.spec index 436d171..8c4b959 100644 --- a/socat.spec +++ b/socat.spec @@ -32,6 +32,8 @@ Source2: socat-test-dhparam Patch1: socat-ignore-tests-failure-boo1078346.patch # Support build environments without a TTY Patch2: socat-test-without-tty.patch +# FIX from termux , https://bugzilla.suse.com/show_bug.cgi?id=1226459, https://github.com/termux/termux-packages/issues/18645 +Patch3: 0004-udp-listen-bind4.patch BuildRequires: iputils BuildRequires: net-tools BuildRequires: openssl-devel