diff --git a/CHANGES b/CHANGES
index 274b8e6..40d247a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -30,6 +30,11 @@ Testing:
 
 	Fixed a few testing issues.
 
+	Added test script sock5server-echo.sh for SOCKS5-CONNECT and
+	SOCKS5-LISTEN, and appropriate tests.
+	SOCKS5 addresses are no longer experimental.
+	Tests: SOCKS5CONNECT_TCP4 SOCKS5LISTEN_TCP4
+
 ####################### V 1.8.0.2:
 
 Security:
diff --git a/Makefile.in b/Makefile.in
index 631d31d..6187393 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -80,7 +80,7 @@ SHFILES = socat-chain.sh socat-mux.sh socat-broker.sh \
 	daemon.sh mail.sh ftp.sh readline.sh \
 	socat_buildscript_for_android.sh
 TESTFILES = test.sh socks4echo.sh proxyecho.sh readline-test.sh \
-	proxy.sh socks4a-echo.sh
+	proxy.sh socks4a-echo.sh socks5server-echo.sh
 
 all: progs doc
 
diff --git a/doc/socat.yo b/doc/socat.yo
index 2574a3f..747f915 100644
--- a/doc/socat.yo
+++ b/doc/socat.yo
@@ -1108,7 +1108,6 @@ dit(bf(tt(SOCKS5-CONNECT:<socks-server>:<target-host>:<target-port>)))
    to <target-host> [link(IPv4 address)(TYPE_IPV4_ADDRESS)]
    on <target-port> [link(TCP service)(TYPE_TCP_SERVICE)],
    using socks version 5 protocol over TCP. Currently no authentication mechanism is provided.nl()
-   This address type is experimental.nl()
    Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET), link(IP4)(GROUP_IP4), link(IP6)(GROUP_IP6), link(TCP)(GROUP_TCP), link(CHILD)(GROUP_CHILD), link(RETRY)(GROUP_RETRY)nl()
    Useful options:
    link(socksport)(OPTION_SOCKSPORT),
@@ -1127,7 +1126,7 @@ dit(bf(tt(SOCKS5-LISTEN:<socks-server>:<listen-host>:<listen-port>)))
    Connects to <socks-server> [link(IP address)(TYPE_IP_ADDRESS)]
    using socks version 5 protocol over TCP
    and makes it listen for incoming connections on <listen-port> [link(TCP service)(TYPE_TCP_SERVICE)], binding to <-listen-host> [link(IPv4 address)(TYPE_IPV4_ADDRESS)]
-   Currently not authentication mechanism is provided. This address type is experimental.
+   Currently not authentication mechanism is provided.nl()
    Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET), link(IP4)(GROUP_IP4), link(IP6)(GROUP_IP6), link(TCP)(GROUP_TCP), link(CHILD)(GROUP_CHILD), link(RETRY)(GROUP_RETRY)nl()
    Useful options:
    link(sourceport)(OPTION_SOURCEPORT),
diff --git a/socks4a-echo.sh b/socks4a-echo.sh
index 7360366..91d255a 100755
--- a/socks4a-echo.sh
+++ b/socks4a-echo.sh
@@ -37,7 +37,7 @@ esac
 if   [ $(echo "x\c") = "x" ]; then E=""
 elif [ $(echo -e "x\c") = "x" ]; then E="-e"
 else
-    echo "cannot suppress trailing newline on echo" >&2
+    echo "$0: cannot suppress trailing newline on echo" >&2
     exit 1
 fi
 ECHO="echo $E"
@@ -58,7 +58,7 @@ else
 fi
 if [ "$vn" != $($ECHO "\04") ]; then
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "invalid socks version requested" >&2
+    echo "$0 invalid socks version requested" >&2
     exit
 fi
 
@@ -69,7 +69,7 @@ else
 fi
 if [ "$cd" != $($ECHO "\01") ]; then
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "invalid socks operation requested" >&2
+    echo "$0: invalid socks operation requested" >&2
     exit
 fi
 
@@ -82,7 +82,7 @@ a=$(dd bs=1 count=6 2>/dev/null)
 if [ "$a" != "$($ECHO "}m\0\0\0\01")" ]; then
     sleep 1
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "wrong socks address or port requested" >&2
+    echo "$0: wrong socks address or port requested" >&2
     exit
 fi
 
@@ -93,7 +93,7 @@ else
 fi
 if [ "$u" != "nobody" ]; then
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "wrong socks user requested" >&2
+    echo "$0: wrong socks user requested" >&2
     exit
 fi
 
@@ -104,7 +104,7 @@ else
 fi
 if [ "$h" != "localhost" ]; then
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "wrong socks address requested" >&2
+    echo "$0: wrong socks address requested" >&2
     exit
 fi
 
diff --git a/socks4echo.sh b/socks4echo.sh
index 48ea536..a577b20 100755
--- a/socks4echo.sh
+++ b/socks4echo.sh
@@ -36,7 +36,7 @@ esac
 if   [ $(echo "x\c") = "x" ]; then E=""
 elif [ $(echo -e "x\c") = "x" ]; then E="-e"
 else
-    echo "cannot suppress trailing newline on echo" >&2
+    echo "$0: cannot suppress trailing newline on echo" >&2
     exit 1
 fi
 ECHO="echo $E"
@@ -57,7 +57,7 @@ else
 fi
 if [ "$vn" != $($ECHO "\04") ]; then
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "invalid socks version requested" >&2
+    echo "$0: invalid socks version requested" >&2
     exit
 fi
 
@@ -68,7 +68,7 @@ else
 fi
 if [ "$cd" != $($ECHO "\01") ]; then
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "invalid socks operation requested" >&2
+    echo "$0: invalid socks operation requested" >&2
     exit
 fi
 
@@ -91,7 +91,7 @@ else
 fi
 if [ "$u" != "nobody" ]; then
     $ECHO "$SOCKSREPLY_FAILED"
-    echo "wrong socks user requested (expected \"nobody\")" >&2
+    echo "$0: wrong socks user requested (expected \"nobody\")" >&2
     exit
 fi
 
diff --git a/socks5server-echo.sh b/socks5server-echo.sh
new file mode 100755
index 0000000..04e562a
--- /dev/null
+++ b/socks5server-echo.sh
@@ -0,0 +1,67 @@
+#! /usr/bin/env bash
+# Source: socks5connect-echo.sh
+
+# Copyright Gerhard Rieger and contributors (see file CHANGES)
+# Published under the GNU General Public License V.2, see file COPYING
+
+# Performs primitive simulation of a socks5 server with echo function via stdio.
+# Accepts and answers SOCKS5 CONNECT request without authentication to
+# 8.8.8.8:80, however is does not connect there but just echoes data.
+# It is required for test.sh
+# For TCP, use this script as:
+# socat TCP-L:1080,reuseaddr EXEC:"socks5connect-echo.sh"
+
+#set -vx
+
+if [ "$SOCAT" ]; then
+    :
+elif type socat >/dev/null 2>&1; then
+    SOCAT=socat
+else
+    SOCAT=./socat
+fi
+
+case `uname` in
+HP-UX|OSF1)
+    CAT="$SOCAT -u STDIN STDOUT"
+    ;;
+*)
+    CAT=cat
+    ;;
+esac
+
+A="7f000001"
+P="0050"
+
+# Read and parse SOCKS5 greeting
+read _ v b c _ <<<"$($SOCAT -u -,readbytes=3 - |od -t x1)"
+#echo "$v $b $c" >&2
+if [ "$v" != 05 ]; then echo "$0: Packet1: expected version x05, got \"$v\"" >&2; exit 1; fi
+if [ "$b" != 01 ]; then echo "$0: Packet1: expected 01 auth methods, got \"$b\"" >&2; exit 1; fi
+if [ "$c" != 00 ]; then echo "$0: Packet1: expected auth method 00, got \"$c\"" >&2; exit 1; fi
+# Send answer
+echo -en "\x05\x00"
+
+# Read and parse SOCKS5 connect request
+read _ v b c d a1 a2 a3 a4 p1 p2 _ <<<"$($SOCAT -u -,readbytes=10 - |od -t x1)"
+#echo "$v $b $c $d $a1 $a2 $a3 $a4 $p1 $p2" >&2
+a="$a1$a2$a3$a4"
+p="$p1$p2"
+if [ "$v" != 05 ];   then echo "$0: Packet2: expected version x05, got \"$v\"" >&2; exit 1; fi
+if [ "$b" != 01 ] && [ "$b" != 02 ];   then echo "$0: Packet2: expected connect request 01 or bind request 02, got \"$b\"" >&2; exit 1; fi
+if [ "$c" != 00 ];   then echo "$0: Packet2: expected reserved 00, got \"$c\"" >&2; exit 1; fi
+if [ "$d" != 01 ];   then echo "$0: Packet2: expected address type 01, got \"$d\"" >&2; exit 1; fi
+if [ "$a" != "$A" ]; then echo "$0: Packet2: expected address $A, got \"$a\"" >&2; exit 1; fi
+if [ "$p" != "$P" ]; then echo "$0: Packet2: expected port $P, got \"$p\"" >&2; exit 1; fi
+if [ "$z" != "" ];   then echo "$0: Packet2: trailing data \"$z\"" >&2; exit 1; fi
+# Send answer
+echo -en "\x05\x00\x00\x01\x10\x00\x1f\x64\x1f\x64"
+
+# Bind/listen/passive mode
+if [ "$b" == 02 ]; then
+    sleep 1 	# pretend to be waiting for connection
+    echo -en "\x05\x00\x00\x01\x10\xff\x1f\x64\x23\x28"
+fi
+
+# perform echo function
+$CAT
diff --git a/test.sh b/test.sh
index 1357f1d..9d08236 100755
--- a/test.sh
+++ b/test.sh
@@ -66,6 +66,7 @@ VERBOSE=
 DEBUG=
 DEFS=
 INTERNET=
+EXPERIMENTAL=
 OPT_EXPECT_FAIL= EXPECT_FAIL=
 while [ "$1" ]; do
     case "X$1" in
@@ -4295,46 +4296,62 @@ esac
 N=$((N+1))
 
 
+# Test the SOCKS address with IPv4
 NAME=SOCKS4CONNECT_TCP4
 case "$TESTS" in
 *%$N%*|*%functions%*|*%socks%*|*%socks4%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
 TEST="$NAME: socks4 connect over TCP/IPv4"
 if ! eval $NUMCOND; then :;
-elif ! testfeats socks4 >/dev/null; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N
-    cant
-elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
+elif ! cond=$(checkconds \
+		  "" \
+		  "" \
+		  "socks4echo.sh" \
+		  "SOCKS4 IP4 TCP LISTEN STDIO" \
+		  "TCP4-LISTEN EXEC STDIN SOCKS4" \
+		  "so-reuseaddr" \
+		  "tcp4" ); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
     cant
 else
-tf="$td/test$N.stdout"
-te="$td/test$N.stderr"
-tdiff="$td/test$N.diff"
-da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
-# we have a normal tcp echo listening - so the socks header must appear in answer
-newport tcp4 	# provide free port number in $PORT
-CMD2="$TRACE $SOCAT $opts TCP4-L:$PORT,$REUSEADDR EXEC:\"./socks4echo.sh\""
-CMD="$TRACE $SOCAT $opts - SOCKS4:$LOCALHOST:32.98.76.54:32109,pf=ip4,socksport=$PORT",socksuser="nobody"
-printf "test $F_n $TEST... " $N
-eval "$CMD2 2>\"${te}1\" &"
-pid=$!	# background process id
-waittcp4port $PORT 1
-echo "$da" |$CMD >$tf 2>"${te}2"
-if ! echo "$da" |diff - "$tf" >"$tdiff"; then
-    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
-    echo "$CMD2 &"
-    echo "$CMD"
-    cat "${te}1"
-    cat "${te}2"
-    cat "$tdiff"
-    failed
-else
-   $PRINTF "$OK\n"
-   if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   ok
-fi
-kill $pid 2>/dev/null
-wait
+    tf="$td/test$N.stdout"
+    te="$td/test$N.stderr"
+    tdiff="$td/test$N.diff"
+    da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
+    newport tcp4 	# provide free port number in $PORT
+    CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,$REUSEADDR EXEC:\"./socks4echo.sh\""
+    CMD1="$TRACE $SOCAT $opts STDIO SOCKS4:$LOCALHOST:32.98.76.54:32109,pf=ip4,socksport=$PORT",socksuser="nobody"
+    printf "test $F_n $TEST... " $N
+    eval "$CMD0 2>\"${te}0\" &"
+    pid0=$!	# background process id
+    waittcp4port $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
+	failed
+    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
+	failed
+    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
+	ok
+    fi
 fi ;; # NUMCOND, feats
 esac
 N=$((N+1))
@@ -19292,6 +19309,86 @@ fi # NUMCOND
 esac
 N=$((N+1))
 
+
+# Above test introduced with 1.8.0.2
+# Below tests introduced with 1.8.0.3 (or later)
+
+
+# Test the SOCKS5-CONNECT and SOCKS5-LISTEN addresses with IPv4
+for SUFFIX in CONNECT LISTEN; do
+
+suffix=$(tolower $SUFFIX)
+if [ "$SUFFIX" = LISTEN ]; then
+    test=listen
+    LISTEN=LISTEN
+    listen=listen
+else
+    test=dont
+    LISTEN=
+    listen=
+fi
+NAME=SOCKS5${SUFFIX}_TCP4
+case "$TESTS" in
+*%$N%*|*%functions%*|*%socks%*|*%socks5%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$test%*|*%$NAME%*)
+TEST="$NAME: SOCKS5-$SUFFIX over TCP/IPv4"
+if ! eval $NUMCOND; then :;
+elif ! cond=$(checkconds \
+		  "" \
+		  "" \
+		  "od ./socks5server-echo.sh" \
+		  "SOCKS5 IP4 TCP $LISTEN STDIO" \
+		  "TCP4-LISTEN EXEC STDIN SOCKS5-$SUFFIX" \
+		  "so-reuseaddr readbytes" \
+		  "tcp4" ); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
+    cant
+else
+    tf="$td/test$N.stdout"
+    te="$td/test$N.stderr"
+    tdiff="$td/test$N.diff"
+    da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
+    newport tcp4 	# provide free port number in $PORT
+    CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,$REUSEADDR EXEC:\"./socks5server-echo.sh\""
+    CMD1="$TRACE $SOCAT $opts STDIO SOCKS5-$SUFFIX:$LOCALHOST:127.0.0.1:80,pf=ip4,socksport=$PORT"
+    printf "test $F_n $TEST... " $N
+    eval "$CMD0 2>\"${te}0\" &"
+    pid0=$!	# background process id
+    waittcp4port $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
+	failed
+    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
+	failed
+    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
+	ok
+    fi
+fi ;; # NUMCOND, feats
+esac
+N=$((N+1))
+
+done 	# CONNECT LISTEN
+
+
 # end of common tests
 
 ##################################################################################
diff --git a/xio-socks5.c b/xio-socks5.c
index 8d8ffc5..d931961 100644
--- a/xio-socks5.c
+++ b/xio-socks5.c
@@ -53,7 +53,7 @@ static int xioopen_socks5(int argc, const char *argv[], struct opt *opts, int xi
 
 const struct addrdesc xioaddr_socks5_connect = { "SOCKS5-CONNECT", 1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_CONNECT, 0, 0 HELP(":<socks-server>[:<socks-port>]:<target-host>:<target-port>") };
 
-const struct addrdesc xioaddr_socks5_listen  = { "SOCKS5-LISTEN",  1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_BIND,    0, 0 HELP(":<socks-server>[:<socks-port>]:<listen-host>:<listen-port>") };
+const struct addrdesc xioaddr_socks5_listen  = { "SOCKS5-LISTEN",  1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_BIND,    0, 0 HELP(":<socks-server>[:<socks-port>]:<listen-host>:<listen-port>") };
 
 static const char * _xioopen_socks5_strerror(uint8_t r)
 {
@@ -188,6 +188,8 @@ static int _xioopen_socks5_handshake(struct single *sfd, int level)
 		return STAT_RETRYLATER;
 	}
 
+	Debug2("received SOCKS5 server hello %02x %02x",
+	       server_hello_ptr[0], server_hello_ptr[1]);
 	Info2("received SOCKS5 server hello version=%d method=%d",
 		server_hello.version,
 		server_hello.method);
@@ -332,6 +334,12 @@ static int _xioopen_socks5_read_reply(
 			}
 			return STAT_RETRYLATER;
 		}
+		Debug5("received SOCKS5 reply %02x %02x %02x %02x %02x",
+		       ((unsigned char *)reply+bytes_read)[0],
+		       ((unsigned char *)reply+bytes_read)[1],
+		       ((unsigned char *)reply+bytes_read)[2],
+		       ((unsigned char *)reply+bytes_read)[3],
+		       ((unsigned char *)reply+bytes_read)[4]);
 		bytes_read += result;
 
 		/* Once we've read 5 bytes, figure out total message length and
@@ -518,10 +526,6 @@ static int xioopen_socks5(
 	bool lowport = false;
 	char infobuff[256];
 
-	if (!xioparms.experimental) {
-		Error1("%s: use option --experimental to acknowledge unmature state", argv[0]);
-		return STAT_NORETRY;
-	}
 	if (argc < 4 || argc > 5) {
 		xio_syntax(argv[0], 4, argc-1, addrdesc->syntax);
 		return STAT_NORETRY;