Mechanism for ai-* options; new option ai-addrconfig
diff --git a/CHANGES b/CHANGES
index 19006c7..9de7304 100644
--- a/CHANGES
+++ b/CHANGES
@@ -78,6 +78,12 @@
 	configure option --with-default-ipv allows to specify at build time if
 	IPv4, IPv6, or none of these is the preferred default.
 
+	Socat options -4 and -6 have been reworked.
+	Tests: TCP_ENV6 TCP_DASH6
+
+	New option ai-addrconfig disables name resolution to protocol families
+	that are not configured on the computer (e.g. IPv6)
+
 Corrections:
 	When a sub process (EXEC, SYSTEM) terminated with exit code other than
 	0, its last sent data might have been lost depending on timing of read/
diff --git a/VERSION b/VERSION
index ceaf471..576e205 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-"1.7.4.5+"
+"1.7.4.5+conn-over"
diff --git a/doc/socat.yo b/doc/socat.yo
index 6ca5159..38dc481 100644
--- a/doc/socat.yo
+++ b/doc/socat.yo
@@ -218,10 +218,10 @@
    If lockfile exists, waits until it disappears. When lockfile does not exist,
    creates it and continues, unlinks lockfile on exit.
 label(option_4)dit(bf(tt(-4)))
-   Use IP version 4 in case that the addresses do not implicitly or explicitly
+   Use IP version 4 in case the addresses do not implicitly or explicitly
    specify a version; this is the default.
 label(option_6)dit(bf(tt(-6)))
-   Use IP version 6 in case that the addresses do not implicitly or explicitly
+   Use IP version 6 in case the addresses do not implicitly or explicitly
    specify a version.
 label(option_statistics)dit(bf(tt(--statistics)))
    Logs transfer statistics (bytes and blocks counters for both directions)
@@ -2240,6 +2240,11 @@
 dit(bf(tt(ip-transparent)))
    Sets the IP_TRANSPARENT socket option.
    This option might require root privilege.
+label(OPTION_AI_ADDRCONFIG)
+dit(bf(tt(ai-addrconfig[=0|1]))), dit(bf(tt(addrconfig[=0|1])))
+   Sets or unsets the AI_ADDRCONFIG flag to prevent name resolution to address
+   families that are not configured (e.g. IPv6). Default value is 1 in case the
+   resolver does not get an address family hint.
 label(OPTION_RES_DEBUG)dit(bf(tt(res-debug)))
 label(OPTION_RES_AAONLY)dit(bf(tt(res-aaonly)))
 label(OPTION_RES_USEVC)dit(bf(tt(res-usevc)))
@@ -2249,10 +2254,10 @@
 label(OPTION_RES_DEFNAMES)dit(bf(tt(res-defnames)))
 label(OPTION_RES_STAYOPEN)dit(bf(tt(res-stayopen)))
 label(OPTION_RES_DNSRCH)dit(bf(tt(res-dnsrch)))
-   These options set the corresponding resolver (name resolution) option flags.
-   Append "=0" to clear a default option. See man NOEXPAND(resolver(5)) for more
-   information on these options. Note: these options are valid only for the
-   address they are applied to.
+   These options temporarily set the corresponding resolver (name resolution)
+   option flags. Append "=0" to clear a default option. See man
+   NOEXPAND(resolver(5)) for more information on these options. These flags are
+   per process, however socat() restores the old values after name resolution.
    
 enddit()
 
diff --git a/sycls.c b/sycls.c
index eba9d01..e6cd8db 100644
--- a/sycls.c
+++ b/sycls.c
@@ -1445,7 +1445,7 @@
 int Getaddrinfo(const char *node, const char *service,
 		const struct addrinfo *hints, struct addrinfo **res) {
    int result;
-   Debug15("getaddrinfo(%s%s%s, %s%s%s, {%d,%d,%d,%d,"F_socklen",%p,%p,%p}, %p)",
+   Debug15("getaddrinfo(%s%s%s, %s%s%s, {0x%02x,%d,%d,%d,"F_socklen",%p,%p,%p}, %p)",
 	   node?"\"":"", node?node:"NULL", node?"\"":"",
 	   service?"\"":"", service?service:"NULL", service?"\"":"",
 	   hints->ai_flags, hints->ai_family, hints->ai_socktype,
diff --git a/test.sh b/test.sh
index 439a2c2..dd80bc1 100755
--- a/test.sh
+++ b/test.sh
@@ -173,6 +173,7 @@
 SO_REUSEADDR="$($PROCAN -c |grep "^#define[[:space:]]*SO_REUSEADDR[[:space:]]" |cut -d' ' -f3)"
 TCP_MAXSEG="$($PROCAN -c |grep "^#define[[:space:]]*TCP_MAXSEG[[:space:]]" |cut -d' ' -f3)"
 SIZE_T=$($PROCAN |grep size_t |awk '{print($3);}')
+#AI_ADDRCONFIG=; if [ "$($SOCAT -hhh |grep ai-addrconfig)" ]; then AI_ADDRCONFIG="ai-addrconfig=0"; fi
 
 # SSL certificate contents
 TESTCERT_CONF=testcert.conf
@@ -2089,8 +2090,20 @@
 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
 TEST="$NAME: echo via connection to TCP V6 socket"
 if ! eval $NUMCOND; then :;
-elif ! testfeats tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
+elif ! F=$(testfeats IP6 TCP LISTEN STDIO PIPE); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
+    numCANT=$((numCANT+1))
+    listCANT="$listCANT $N"
+elif ! A=$(testaddrs - TCP6-LISTEN PIPE STDIN STDOUT TCP6-CONNECT); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
+    numCANT=$((numCANT+1))
+    listCANT="$listCANT $N"
+elif ! o=$(testoptions so-reuseaddr ) >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
+    numCANT=$((numCANT+1))
+    listCANT="$listCANT $N"
+elif ! runsip6 >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N
     numCANT=$((numCANT+1))
     listCANT="$listCANT $N"
 else
@@ -2101,27 +2114,36 @@
 ts="[::1]:$tsl"
 da="test$N $(date) $RANDOM"
 CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,$REUSEADDR PIPE"
-CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP6:$ts"
+CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts"
 printf "test $F_n $TEST... " $N
 $CMD1 >"$tf" 2>"${te}1" &
 pid=$!	# background process id
 waittcp6port $tsl 1
 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
-   echo "$CMD1 &"
-   echo "$CMD2"
-   cat "$te"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\n"
+    echo "$CMD1 &"
+    cat "${te}1" >&2
+    echo "$CMD2"
+    cat "${te}2" >&2
+    numFAIL=$((numFAIL+1))
+    listFAIL="$listFAIL $N"
 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
-   $PRINTF "$FAILED: diff:\n"
-   cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+    $PRINTF "$FAILED: diff:\n"
+    echo "$CMD1 &"
+    cat "${te}1" >&2
+    echo "$CMD2"
+    cat "${te}2" >&2
+    echo diff:
+    cat "$tdiff"
+    numFAIL=$((numFAIL+1))
+    listFAIL="$listFAIL $N"
 else
    $PRINTF "$OK\n"
-   if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
+    if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
+    if [ "$DEBUG" ];   then cat "${te}1" >&2; fi
+    if [ "$VERBOSE" ]; then echo "$CMD2"; fi
+    if [ "$DEBUG" ];   then cat "${te}2" >&2; fi
    numOK=$((numOK+1))
 fi
 kill $pid 2>/dev/null
@@ -2131,17 +2153,26 @@
 #set +vx
 
 
+# Test if TCP client with IPv4 address connects to IPv4 port
 NAME=TCPX4
 case "$TESTS" in
 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
 TEST="$NAME: echo via connection to TCP socket, v4 by target"
 if ! eval $NUMCOND; then :;
-elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
+elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
     numCANT=$((numCANT+1))
     listCANT="$listCANT $N"
-elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
+elif ! A=$(testaddrs TCP TCP-LISTEN STDIN STDOUT PIPE); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
+    numCANT=$((numCANT+1))
+    listCANT="$listCANT $N"
+elif ! o=$(testoptions pf) >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
+    numCANT=$((numCANT+1))
+    listCANT="$listCANT $N"
+elif ! runsip4 >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
     numCANT=$((numCANT+1))
     listCANT="$listCANT $N"
 else
@@ -2151,29 +2182,39 @@
 newport tcp4; tsl=$PORT
 ts="127.0.0.1:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,pf=ip4,$REUSEADDR PIPE"
-CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP:$ts"
+CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,pf=ip4,$REUSEADDR PIPE"
+CMD1="$TRACE $SOCAT $opts STDIN!!STDOUT TCP:$ts"
 printf "test $F_n $TEST... " $N
-$CMD1 >"$tf" 2>"${te}1" &
+$CMD0 >"$tf" 2>"${te}0" &
 pid=$!	# background process id
 waittcp4port $tsl 1
-echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
+echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
-   echo "$CMD1 &"
-   echo "$CMD2"
-   cat "$te"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\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" >"$tdiff"; then
-   $PRINTF "$FAILED: diff:\n"
-   cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+    $PRINTF "$FAILED: diff:\n"
+    cat "$tdiff"
+    echo "$CMD0 &"
+    cat "${te}0" >&2
+    echo "$CMD1"
+    cat "${te}1" >&2
+    numFAIL=$((numFAIL+1))
+    listFAIL="$listFAIL $N"
+    namesFAIL="$namesFAIL $NAME"
 else
-   $PRINTF "$OK\n"
-   if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
+    $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
 kill $pid 2>/dev/null
 fi
@@ -2181,17 +2222,26 @@
 N=$((N+1))
 
 
+# Test if TCP client with IPv6 address connects to IPv6 port
 NAME=TCPX6
 case "$TESTS" in
 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
 TEST="$NAME: echo via connection to TCP socket, v6 by target"
 if ! eval $NUMCOND; then :;
-elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
+elif ! F=$(testfeats STDIO PIPE IP6 TCP LISTEN); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
     numCANT=$((numCANT+1))
     listCANT="$listCANT $N"
-elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
+elif ! A=$(testaddrs TCP TCP-LISTEN STDIN STDOUT PIPE); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
+    numCANT=$((numCANT+1))
+    listCANT="$listCANT $N"
+elif ! o=$(testoptions pf) >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
+    numCANT=$((numCANT+1))
+    listCANT="$listCANT $N"
+elif ! runsip6 >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N
     numCANT=$((numCANT+1))
     listCANT="$listCANT $N"
 else
@@ -2201,29 +2251,39 @@
 newport tcp6; tsl=$PORT
 ts="[::1]:$tsl"
 da="test$N $(date) $RANDOM"
-CMD1="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,pf=ip6,$REUSEADDR PIPE"
-CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP:$ts"
+CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,pf=ip6,$REUSEADDR PIPE"
+CMD1="$TRACE $SOCAT $opts STDIN!!STDOUT TCP:$ts"
 printf "test $F_n $TEST... " $N
-$CMD1 >"$tf" 2>"${te}1" &
+$CMD0 >"$tf" 2>"${te}0" &
 pid=$!	# background process id
 waittcp6port $tsl 1
-echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
+echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
 if [ $? -ne 0 ]; then
-   $PRINTF "$FAILED: $TRACE $SOCAT:\n"
-   echo "$CMD1 &"
-   echo "$CMD2"
-   cat "$te"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+    $PRINTF "$FAILED: $TRACE $SOCAT:\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" >"$tdiff"; then
-   $PRINTF "$FAILED: diff:\n"
-   cat "$tdiff"
-   numFAIL=$((numFAIL+1))
-   listFAIL="$listFAIL $N"
+    $PRINTF "$FAILED: diff:\n"
+    cat "$tdiff"
+    echo "$CMD0 &"
+    cat "${te}0" >&2
+    echo "$CMD1"
+    cat "${te}1" >&2
+    numFAIL=$((numFAIL+1))
+    listFAIL="$listFAIL $N"
+    namesFAIL="$namesFAIL $NAME"
 else
-   $PRINTF "$OK\n"
-   if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
-   numOK=$((numOK+1))
+    $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
 kill $pid 2>/dev/null
 fi
@@ -8298,7 +8358,7 @@
 if1="$MCINTERFACE"
 ts1a="[::1]"
 da="test$N $(date) $RANDOM"
-CMD1="$TRACE $SOCAT -u $opts UDP6-RECV:$ts1p,reuseaddr,ipv6-join-group=[ff02::2]:$if1 -"
+CMD1="$TRACE $SOCAT -u $opts UDP6-RECV:$ts1p,$REUSEADDR,ipv6-join-group=[ff02::2]:$if1 -"
 #CMD2="$TRACE $SOCAT -u $opts - UDP6-SENDTO:[ff02::2]:$ts1p,bind=$ts1a"
 CMD2="$TRACE $SOCAT -u $opts - UDP6-SENDTO:[ff02::2]:$ts1p"
 printf "test $F_n $TEST... " $N
@@ -13589,7 +13649,7 @@
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$TRACE $SOCAT $opts FILE:/dev/null OPENSSL-CONNECT:$SNISERVER:443"
+CMD0="$TRACE $SOCAT $opts FILE:/dev/null OPENSSL-CONNECT:$SNISERVER:443,pf=ip4"
 printf "test $F_n $TEST... " $N
 $CMD0 >/dev/null 2>"${te}0"
 rc0=$?
@@ -15177,7 +15237,7 @@
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$TRACE $SOCAT $opts -t 3 $PROTO-RECVFROM:$tsl,fork SYSTEM:'read t x; sleep \$t; echo \$x >>'\"$tf\""
+CMD0="$TRACE $SOCAT $opts -t 3 $PROTO-RECVFROM:$tsl,fork SYSTEM:'read t x; sleep \$t; echo \\\"\$x\\\" >>'\"$tf\""
 CMD1="$TRACE $SOCAT $opts -t 3 - $PROTO-SENDTO:$tsc"
 printf "test $F_n $TEST... " $N
 eval $CMD0 </dev/null 2>"${te}0" &
@@ -15947,6 +16007,7 @@
 CMD0a="$TRACE $SOCAT $opts -lp server1 -6 OPENSSL-LISTEN:$PORT,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
 CMD0b="$TRACE $SOCAT $opts -lp server2 -6 OPENSSL-LISTEN:$PORT,accept-timeout=.01,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
 CMD1="$TRACE $SOCAT $opts -lp client -6 -T 0.1 PIPE OPENSSL-CONNECT:$LOCALHOST6:$PORT,verify=0"
+printf "test $F_n $TEST... " $N
 $CMD0a >/dev/null 2>"${te}0a" &
 pid0=$!
 waittcp6port $PORT 1
@@ -16077,8 +16138,8 @@
 # that is closed on both addresses.
 # The test succeeded when the log shows that Socat tried to connect two times.
 if ! eval $NUMCOND; then :;
-elif [ -z "$FOREIGN" ]; then
-    $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option -foreign${NORMAL}\n" $N
+elif ! $(type nslookup >/dev/null 2>&1); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}nslookup not available${NORMAL}\n" $N
     numCANT=$((numCANT+1))
     listCANT="$listCANT $N"
 #elif ! $(type nslookup >/dev/null 2>&1) && ! $(type host >/dev/null 2>&1); then
@@ -16097,6 +16158,10 @@
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
     numCANT=$((numCANT+1))
     listCANT="$listCANT $N"
+elif [ -z "$FOREIGN" ]; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option -foreign${NORMAL}\n" $N
+    numCANT=$((numCANT+1))
+    listCANT="$listCANT $N"
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -16162,7 +16227,7 @@
 #    $PRINTF "test $F_n $TEST... ${YELLOW}nslookup and host not available${NORMAL}\n" $N
 #    numCANT=$((numCANT+1))
 #    listCANT="$listCANT $N"
-elif ! F=$(testfeats ip4 ip6 tcp); then
+elif ! F=$(testfeats IP4 IP6 TCP); then
     $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
     numCANT=$((numCANT+1))
     listCANT="$listCANT $N"
@@ -16178,6 +16243,10 @@
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available or not routable${NORMAL}\n" $N
     numCANT=$((numCANT+1))
     listCANT="$listCANT $N"
+elif [ -z "$FOREIGN" ]; then	# only needs Internet DNS
+    $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option -foreign${NORMAL}\n" $N
+    numCANT=$((numCANT+1))
+    listCANT="$listCANT $N"
 else
 tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
@@ -16185,10 +16254,18 @@
 da="test$N $(date) $RANDOM"
 LOCALHOST_4_6=localhost-4-6.dest-unreach.net
 if type nslookup >/dev/null 2>&1; then
-    ADDRS=$(nslookup server-4.dest-unreach.net. |sed -n '/^$/,$ p' |grep ^Address |awk '{print($2);}')
+    ADDRS=$(nslookup $LOCALHOST_4_6 |sed -n '/^$/,$ p' |grep ^Address |awk '{print($2);}')
 elif type host >/dev/null 2>&1; then
-    ADDRS=$(host server-4.dest-unreach.net. |sed 's/.*address //')
+    ADDRS=$(host $LOCALHOST_4_6 |sed 's/.*address //')
 fi
+# Specific config: on Ubuntu-12.04: getaddrinfo(...AI_ADDRCONFIG) does not
+# resolve to IPv6 addresses even when there are link local IPv6 addresses
+if test -f /etc/os-release &&
+	grep -q '^NAME="Ubuntu"' /etc/os-release &&
+	grep -q '^VERSION="12\.04' /etc/os-release; then
+    AI_ADDRCONFIG="ai-addrconfig=0,"
+fi
+# Check if PORT is really closed on both addresses
 while true; do
     OPEN=
     for addr in $ADDRS; do
@@ -16196,7 +16273,7 @@
 	    *.*) ;;
 	    *:*) addr="[$addr]" ;
 	esac
-	if $SOCAT /dev/null TCP:$addr:$PORT 2>/dev/null; then
+	if $SOCAT /dev/null TCP:$addr:$PORT,$AI_ADDRCONFIG 2>/dev/null; then
 	    # port is open :-(
 	    OPEN=1
 	    break
@@ -16207,7 +16284,7 @@
     fi
     newport tcp4
 done
-CMD="$TRACE $SOCAT $opts -d -d /dev/null TCP:localhost-4-6.dest-unreach.net:$PORT"
+CMD="$TRACE $SOCAT $opts -d -d /dev/null TCP:$LOCALHOST_4_6:$PORT,$AI_ADDRCONFIG"
 printf "test $F_n $TEST... " $N
 $CMD >/dev/null 2>"${te}"
 rc=$?
@@ -16378,8 +16455,8 @@
     $PRINTF "test $F_n $TEST... ${YELLOW}Must be root${NORMAL}\n" $N
     numCANT=$((numCANT+1))
     listCANT="$listCANT $N"
-elif ! $(type systemd-socket-activate >/dev/null 2>&1); then
-    $PRINTF "test $F_n $TEST... ${YELLOW}systemd-socket-activate not available${NORMAL}\n" $N
+elif ! $(type nslookup >/dev/null 2>&1); then
+    $PRINTF "test $F_n $TEST... ${YELLOW}nslookup not available${NORMAL}\n" $N
     numCANT=$((numCANT+1))
     listCANT="$listCANT $N"
 elif ! F=$(testfeats STDIO IP4 TCP PIPE); then
@@ -16398,6 +16475,10 @@
     $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
     numCANT=$((numCANT+1))
     listCANT="$listCANT $N"
+elif ! runsip4 >/dev/null; then
+    $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
+    numCANT=$((numCANT+1))
+    listCANT="$listCANT $N"
 elif [ -z "$FOREIGN" ]; then
     $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option -foreign${NORMAL}\n" $N
     numCANT=$((numCANT+1))
diff --git a/xio-ip.c b/xio-ip.c
index 0d68338..cb5a88a 100644
--- a/xio-ip.c
+++ b/xio-ip.c
@@ -81,6 +81,10 @@
 const struct optdesc opt_ip_recvif = { "ip-recvif", "recvdstaddrif",OPT_IP_RECVIF, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_RECVIF };
 #endif
 
+#ifdef AI_ADDRCONFIG
+const struct optdesc opt_ai_addrconfig = { "ai-addrconfig", "addrconfig", OPT_AI_ADDRCONFIG, GROUP_SOCK_IP, PH_INIT, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.socket.ip.ai_flags), XIO_SIZEOF(para.socket.ip.ai_flags), AI_ADDRCONFIG };
+#endif
+
 #if WITH_RES_DEPRECATED
 #  define WITH_RES_AAONLY 1
 #  define WITH_RES_PRIMARY 1
@@ -153,8 +157,8 @@
 */
 int xiogetaddrinfo(const char *node, const char *service,
 		   int family, int socktype, int protocol,
-		   struct addrinfo **res,
-		   unsigned long res_opts0, unsigned long res_opts1) {
+		   struct addrinfo **res, const int ai_flags[2],
+		   const unsigned long res_opts[2]) {
    char *numnode = NULL;
    size_t nodelen;
    unsigned long save_res_opts = 0;
@@ -166,13 +170,13 @@
    int error_num;
 
 #if HAVE_RESOLV_H
-   if (res_opts0 | res_opts1) {
+   if (res_opts[0] | res_opts[1]) {
       if (!(_res.options & RES_INIT)) {
          Res_init();	/*!!! returns -1 on error */
       }
       save_res_opts = _res.options;
-      _res.options &= ~res_opts0;
-      _res.options |= res_opts1;
+      _res.options |= res_opts[0];
+      _res.options &= ~res_opts[1];
       Debug2("changed _res.options from 0x%lx to 0x%lx",
 	     save_res_opts, _res.options);
    }
@@ -203,9 +207,8 @@
    } else if (node && node[0] == '[' && node[(nodelen=strlen(node))-1]==']') {
       if ((numnode = Malloc(nodelen-1)) == NULL) {
 #if HAVE_RESOLV_H
-	 if (res_opts0 | res_opts1) {
-	    _res.options = (_res.options & (~res_opts0&~res_opts1) |
-			    save_res_opts& ( res_opts0| res_opts1));
+	 if (res_opts[0] | res_opts[1]) {
+	    _res.options = save_res_opts;
 	 }
 #endif
 	 return STAT_NORETRY;
@@ -219,12 +222,17 @@
       if (family == PF_UNSPEC)  family = PF_INET6;
 #endif /* WITH_IP6 */
    }
-
+   if (family == 0)
+      hints.ai_flags |= AI_ADDRCONFIG;
+   hints.ai_flags |= AI_PASSIVE 	/* important for IPv4+IPv6 listen */;
 #if HAVE_GETADDRINFO
    if (node != NULL || service != NULL) {
       struct addrinfo *record;
 
-      hints.ai_flags |= AI_PASSIVE; 	/* important for IPv4+IPv6 listen */
+      if (ai_flags != NULL) {
+	 hints.ai_flags |= ai_flags[0];
+	 hints.ai_flags &= ~ai_flags[1];
+      }
       hints.ai_family = family;
       hints.ai_socktype = socktype;
       hints.ai_protocol = protocol;
@@ -256,7 +264,7 @@
 	   continue;
 	}
       if ((error_num = Getaddrinfo(node, service, &hints, res)) != 0) {
-	 Error7("getaddrinfo(\"%s\", \"%s\", {%d,%d,%d,%d}, {}): %s",
+	 Error7("getaddrinfo(\"%s\", \"%s\", {0x%02x,%d,%d,%d}, {}): %s",
 		node?node:"NULL", service?service:"NULL",
 		hints.ai_flags, hints.ai_family,
 		hints.ai_socktype, hints.ai_protocol,
@@ -265,9 +273,8 @@
 	 if (numnode)  free(numnode);
 
 #if HAVE_RESOLV_H
-	 if (res_opts0 | res_opts1) {
-	    _res.options = (_res.options & (~res_opts0&~res_opts1) |
-			    save_res_opts& ( res_opts0| res_opts1));
+	 if (res_opts[0] | res_opts[1]) {
+	    _res.options = save_res_opts;
 	 }
 #endif
 	 return STAT_RETRYLATER;
@@ -364,9 +371,8 @@
 		h_errno == NETDB_INTERNAL ? strerror(errno) :
 		hstrerror(h_errno));
 #if HAVE_RESOLV_H
-	 if (res_opts0 | res_opts1) {
-	    _res.options = (_res.options & (~res_opts0&~res_opts1) |
-			    save_res_opts& ( res_opts0| res_opts1));
+	 if (res_opts[0] | res_opts[1]) {
+	    _res.options = save_res_opts;
 	 }
 #endif
 	 return STAT_RETRYLATER;
@@ -399,9 +405,8 @@
    if (numnode)  free(numnode);
 
 #if HAVE_RESOLV_H
-   if (res_opts0 | res_opts1) {
-      _res.options = (_res.options & (~res_opts0&~res_opts1) |
-		      save_res_opts& ( res_opts0| res_opts1));
+   if (res_opts[0] | res_opts[1]) {
+      _res.options = save_res_opts;
    }
 #endif /* HAVE_RESOLV_H */
    return STAT_OK;
@@ -423,12 +428,13 @@
 int xioresolve(const char *node, const char *service,
 	       int family, int socktype, int protocol,
 	       union sockaddr_union *addr, socklen_t *addrlen,
-	       unsigned long res_opts0, unsigned long res_opts1) {
+	       const int ai_flags[2], const unsigned long res_opts[2])
+{
    struct addrinfo *res = NULL;
    int rc;
 
    rc = xiogetaddrinfo(node, service, family, socktype, protocol,
-		       &res, res_opts0, res_opts1);
+		       &res, ai_flags, res_opts);
    if (rc != 0) {
       xiofreeaddrinfo(res);
       return -1;
@@ -760,12 +766,12 @@
 	union sockaddr_union sockaddr2;
 	socklen_t socklen2 = sizeof(sockaddr2.ip4);
 
-	/* first parameter is alway multicast address */
+	/* First parameter is always multicast address */
 	/*! result */
 	xioresolve(opt->value.u_string/*multiaddr*/, NULL,
-		       xfd->para.socket.la.soa.sa_family,
-		       SOCK_DGRAM, IPPROTO_IP,
-		   &sockaddr1, &socklen1, 0, 0);
+		   xfd->para.socket.la.soa.sa_family,
+		   SOCK_DGRAM, IPPROTO_IP, &sockaddr1, &socklen1,
+		   xfd->para.socket.ip.ai_flags, xfd->para.socket.ip.res_opts);
 	ip4_mreqn.mreq.imr_multiaddr = sockaddr1.ip4.sin_addr;
 	if (0) {
 		;	/* for canonical reasons */
@@ -774,9 +780,10 @@
 		/* three parameters */
 		/* second parameter is interface address */
 		xioresolve(opt->value2.u_string/*param2*/, NULL,
-			       xfd->para.socket.la.soa.sa_family,
-			       SOCK_DGRAM, IPPROTO_IP,
-			       &sockaddr2, &socklen2, 0, 0);
+			   xfd->para.socket.la.soa.sa_family,
+			   SOCK_DGRAM, IPPROTO_IP, &sockaddr2, &socklen2,
+			   xfd->para.socket.ip.ai_flags,
+			   xfd->para.socket.ip.res_opts);
 		ip4_mreqn.mreq.imr_interface = sockaddr2.ip4.sin_addr;
 		/* third parameter is interface */
 		if (ifindex(opt->value3.u_string/*ifindex*/,
@@ -802,9 +809,11 @@
 		} else {
 			/*! result */
 			xioresolve(opt->value2.u_string/*param2*/, NULL,
-				       xfd->para.socket.la.soa.sa_family,
-				       SOCK_DGRAM, IPPROTO_IP,
-				       &sockaddr2, &socklen2, 0, 0);
+				   xfd->para.socket.la.soa.sa_family,
+				   SOCK_DGRAM, IPPROTO_IP,
+				   &sockaddr2, &socklen2,
+				   xfd->para.socket.ip.ai_flags,
+				   xfd->para.socket.ip.res_opts);
 			ip4_mreqn.mreq.imr_interface = sockaddr2.ip4.sin_addr;
 		}
 	}
@@ -953,27 +962,30 @@
 
    /* first parameter is always multicast address */
    rc = xioresolve(opt->value.u_string/*mcaddr*/, NULL,
-		  xfd->para.socket.la.soa.sa_family,
-		  SOCK_DGRAM, IPPROTO_IP,
-		  &sockaddr1, &socklen1, 0, 0);
+		   xfd->para.socket.la.soa.sa_family,
+		   SOCK_DGRAM, IPPROTO_IP,
+		   &sockaddr1, &socklen1, xfd->para.socket.ip.ai_flags,
+		   xfd->para.socket.ip.res_opts);
    if (rc < 0) {
       return -1;
    }
    ip4_mreq_src.imr_multiaddr = sockaddr1.ip4.sin_addr;
    /* second parameter is interface address */
    rc = xioresolve(opt->value.u_string/*ifaddr*/, NULL,
-		  xfd->para.socket.la.soa.sa_family,
-		  SOCK_DGRAM, IPPROTO_IP,
-		  &sockaddr2, &socklen2, 0, 0);
+		   xfd->para.socket.la.soa.sa_family,
+		   SOCK_DGRAM, IPPROTO_IP,
+		   &sockaddr2, &socklen2, xfd->para.socket.ip.ai_flags,
+		   xfd->para.socket.ip.res_opts);
    if (rc < 0) {
       return -1;
    }
    ip4_mreq_src.imr_interface = sockaddr2.ip4.sin_addr;
    /* third parameter is source address */
    rc = xioresolve(opt->value.u_string/*srcaddr*/, NULL,
-		  xfd->para.socket.la.soa.sa_family,
-		  SOCK_DGRAM, IPPROTO_IP,
-		  &sockaddr3, &socklen3, 0, 0);
+		   xfd->para.socket.la.soa.sa_family,
+		   SOCK_DGRAM, IPPROTO_IP,
+		   &sockaddr3, &socklen3, xfd->para.socket.ip.ai_flags,
+		   xfd->para.socket.ip.res_opts);
    if (rc < 0) {
       return -1;
    }
diff --git a/xio-ip.h b/xio-ip.h
index 6869b45..2777461 100644
--- a/xio-ip.h
+++ b/xio-ip.h
@@ -29,6 +29,8 @@
 extern const struct optdesc opt_ip_recvif;
 extern const struct optdesc opt_ip_transparent;
 
+extern const struct optdesc opt_ai_addrconfig;
+
 extern const struct optdesc opt_res_debug;
 extern const struct optdesc opt_res_aaonly;
 extern const struct optdesc opt_res_usevc;
@@ -39,9 +41,11 @@
 extern const struct optdesc opt_res_stayopen;
 extern const struct optdesc opt_res_dnsrch;
 
-extern int xiogetaddrinfo(const char *node, const char *service, int family, int socktype, int protocol, struct addrinfo **res, unsigned long res_opts0, unsigned long res_opts1);
+extern int xioinit_ip(struct single *sfd, int *pf);
+
+extern int xiogetaddrinfo(const char *node, const char *service, int family, int socktype, int protocol, struct addrinfo **res, const int ai_flags[2], const unsigned long res_opts[2]);
 extern void xiofreeaddrinfo(struct addrinfo *res);
-extern int xioresolve(const char *node, const char *service, int family, int socktype, int protocol, union sockaddr_union *addr, socklen_t *addrlen, unsigned long res_opts0, unsigned long res_opts1);
+extern int xioresolve(const char *node, const char *service, int family, int socktype, int protocol, union sockaddr_union *addr, socklen_t *addrlen, const int ai_flags[2], const unsigned long res_opts[2]);
 extern int xiolog_ancillary_ip(struct single *sfd, struct cmsghdr *cmsg, int *num, char *typbuff, int typlen, char *nambuff, int namlen, char *envbuff, int envlen, char *valbuff, int vallen);
 extern int xiotype_ip_add_membership(char *token, const struct optname *ent, struct opt *opt);
 extern int xioapply_ip_add_membership(xiosingle_t *xfd, struct opt *opt);
diff --git a/xio-ip4.c b/xio-ip4.c
index 264a00d..d4efbbe 100644
--- a/xio-ip4.c
+++ b/xio-ip4.c
@@ -14,7 +14,12 @@
 #include "xio-ip4.h"
 
 
-int xioparsenetwork_ip4(const char *rangename, struct xiorange *range) {
+int xioparsenetwork_ip4(
+	const char *rangename,
+	struct xiorange *range,
+	const int ai_flags[2],
+	const unsigned long res_opts[2])
+{
    struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr;
    struct in_addr *netmask_in = &range->netmask.ip4.sin_addr;
    char *rangename1;	/* a copy of rangename with writing allowed */
@@ -46,7 +51,7 @@
       }
    } else if (delimpos = strchr(rangename1, ':')) {
       if ((rc = xioresolve(delimpos+1, NULL, PF_INET, 0, 0,
-			       &sau, &socklen, 0, 0))
+			   &sau, &socklen, ai_flags, res_opts))
 	  != STAT_OK) {
 	 return rc;
       }
@@ -59,7 +64,7 @@
    {
       *delimpos = 0;
       if ((rc = xioresolve(rangename1, NULL, PF_INET, 0, 0,
-			       &sau, &socklen, 0, 0))
+			   &sau, &socklen, ai_flags, res_opts))
 	  != STAT_OK) {
 	 return rc;
       }
diff --git a/xio-ip4.h b/xio-ip4.h
index 5d4e277..94d5e86 100644
--- a/xio-ip4.h
+++ b/xio-ip4.h
@@ -7,7 +7,7 @@
 
 extern const struct optdesc opt_ip4_add_membership;
 
-int xioparsenetwork_ip4(const char *rangename, struct xiorange *range);
+extern int xioparsenetwork_ip4(const char *rangename, struct xiorange *range, const int ai_flags[2], const unsigned long res_opts[2]);
 extern
 int xiocheckrange_ip4(struct sockaddr_in *pa, struct xiorange *range);
 extern int
diff --git a/xio-ip6.c b/xio-ip6.c
index 195e706..b5e8073 100644
--- a/xio-ip6.c
+++ b/xio-ip6.c
@@ -82,7 +82,12 @@
 /* Returns canonical form of IPv6 address.
    IPv6 address may bei enclose in brackets.
    Returns STAT_OK on success, STAT_NORETRY on failure. */
-int xioip6_pton(const char *src, struct in6_addr *dst) {
+int xioip6_pton(
+	const char *src,
+	struct in6_addr *dst,
+	const int ai_flags[2],
+	const unsigned long res_opts[2])
+{
    union sockaddr_union sockaddr;
    socklen_t sockaddrlen = sizeof(sockaddr);
 
@@ -94,10 +99,10 @@
       plainaddr[INET6_ADDRSTRLEN-1] = '\0';
       if ((clos = strchr(plainaddr, ']')) != NULL)
 	 *clos = '\0';
-      return xioip6_pton(plainaddr, dst);
+      return xioip6_pton(plainaddr, dst, ai_flags, res_opts);
    }
    if (xioresolve(src, NULL, PF_INET6, 0, 0, &sockaddr, &sockaddrlen,
-		      0, 0)
+		  ai_flags, res_opts)
        != STAT_OK) {
       return STAT_NORETRY;
    }
@@ -105,7 +110,12 @@
    return STAT_OK;
 }
 
-int xioparsenetwork_ip6(const char *rangename, struct xiorange *range) {
+int xioparsenetwork_ip6(
+	const char *rangename,
+	struct xiorange *range,
+	const int ai_flags[2],
+	const unsigned long res_opts[2])
+{
    char *delimpos;	/* absolute address of delimiter */
    size_t delimind;	/* index of delimiter in string */
    unsigned int bits;	/* netmask bits */
@@ -135,7 +145,7 @@
    }
    baseaddr[delimind-2] = '\0';
    if (xioresolve(baseaddr, NULL, PF_INET6, 0, 0, &sockaddr, &sockaddrlen,
-		      0, 0)
+		  ai_flags, res_opts)
        != STAT_OK) {
       return STAT_NORETRY;
    }
@@ -480,9 +490,12 @@
 	/* First parameter is multicast address */
 	if ((res =
 	     xioresolve(opt->value.u_string/*multiaddr*/, NULL,
-			    xfd->para.socket.la.soa.sa_family,
-			    SOCK_DGRAM, IPPROTO_IP,
-			    &sockaddr1, &socklen1, 0, 0)) != STAT_OK) {
+			xfd->para.socket.la.soa.sa_family,
+			SOCK_DGRAM, IPPROTO_IP,
+			&sockaddr1, &socklen1,
+			xfd->para.socket.ip.ai_flags,
+			xfd->para.socket.ip.res_opts))
+	    != STAT_OK) {
 	   return res;
 	}
 	ip6_mreq.ipv6mr_multiaddr = sockaddr1.ip6.sin6_addr;
@@ -619,9 +632,10 @@
    /* First parameter is always multicast address */
    if ((res =
 	xioresolve(opt->value.u_string/*mcaddr*/, NULL,
-		       xfd->para.socket.la.soa.sa_family,
-		       SOCK_DGRAM, IPPROTO_IP,
-		       &sockaddr1, &socklen1, 0, 0)) != STAT_OK) {
+		   xfd->para.socket.la.soa.sa_family,
+		   SOCK_DGRAM, IPPROTO_IP, &sockaddr1, &socklen1,
+		   xfd->para.socket.ip.ai_flags, xfd->para.socket.ip.res_opts))
+       != STAT_OK) {
       return res;
    }
    memcpy(&ip6_gsr.gsr_group, &sockaddr1.ip6, socklen1);
@@ -636,9 +650,10 @@
    /* Third parameter is source address */
    if ((res =
 	xioresolve(opt->value3.u_string/*srcaddr*/, NULL,
-		       xfd->para.socket.la.soa.sa_family,
-		       SOCK_DGRAM, IPPROTO_IP,
-		       &sockaddr2, &socklen2, 0, 0)) != STAT_OK) {
+		   xfd->para.socket.la.soa.sa_family,
+		   SOCK_DGRAM, IPPROTO_IP, &sockaddr2, &socklen2,
+		   xfd->para.socket.ip.ai_flags, xfd->para.socket.ip.res_opts))
+       != STAT_OK) {
       return res;
    }
    memcpy(&ip6_gsr.gsr_source, &sockaddr2.ip6, socklen2);
diff --git a/xio-ip6.h b/xio-ip6.h
index fb25cb5..22d9e9b 100644
--- a/xio-ip6.h
+++ b/xio-ip6.h
@@ -32,9 +32,8 @@
 extern const struct optdesc opt_ipv6_recvtclass;
 extern const struct optdesc opt_ipv6_recvpathmtu;
 
-extern int xioip6_pton(const char *src, struct in6_addr *dst);
-extern
-int xioparsenetwork_ip6(const char *rangename, struct xiorange *range);
+extern int xioip6_pton(const char *src, struct in6_addr *dst, const int ai_flags[2], const unsigned long res_opts[2]);
+extern int xioparsenetwork_ip6(const char *rangename, struct xiorange *range, const int ai_flags[2], const unsigned long res_opts[2]);
 extern int xiorange_ip6andmask(struct xiorange *range);
 
 extern
diff --git a/xio-ipapp.c b/xio-ipapp.c
index c0a6b59..fabc7b7 100644
--- a/xio-ipapp.c
+++ b/xio-ipapp.c
@@ -42,6 +42,7 @@
       Error2("%s: wrong number of parameters (%d instead of 2)", argv[0], argc-1);
    }
 
+   xioinit_ip(xfd, &pf);
    xfd->howtoend = END_SHUTDOWN;
 
    if (applyopts_single(xfd, opts, PH_INIT) < 0)  return -1;
@@ -50,8 +51,8 @@
    retropt_bool(opts, OPT_FORK, &dofork);
 
    if (_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto,
-			      xfd->para.socket.ip.res_opts[1],
-			      xfd->para.socket.ip.res_opts[0],
+			      xfd->para.socket.ip.ai_flags,
+			      xfd->para.socket.ip.res_opts,
 			      &themlist, us, &uslen, &needbind, &lowport,
 			      socktype) != STAT_OK) {
       return STAT_NORETRY;
@@ -170,16 +171,21 @@
    OPT_PROTOCOL_FAMILY, OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT
  */
 int
-   _xioopen_ipapp_prepare(struct opt *opts, struct opt **opts0,
-			   const char *hostname,
-			   const char *portname,
-			   int *pf,
-			   int protocol,
-			   unsigned long res_opts0, unsigned long res_opts1,
-			  struct addrinfo **themlist,
-			   union sockaddr_union *us, socklen_t *uslen,
-			   bool *needbind, bool *lowport,
-			   int socktype) {
+   _xioopen_ipapp_prepare(
+	   struct opt *opts,
+	   struct opt **opts0,
+	   const char *hostname,
+	   const char *portname,
+	   int *pf,
+	   int protocol,
+	   const int ai_flags[2],
+	   const unsigned long res_opts[2],
+	   struct addrinfo **themlist,
+	   union sockaddr_union *us,
+	   socklen_t *uslen,
+	   bool *needbind,
+	   bool *lowport,
+	   int socktype) {
    uint16_t port;
    int result;
 
@@ -188,9 +194,7 @@
    if ((result =
 	xiogetaddrinfo(hostname, portname,
 		       *pf, socktype, protocol,
-		       themlist,
-		       res_opts0, res_opts1
-		       ))
+		       themlist, ai_flags, res_opts))
        != STAT_OK) {
       return STAT_NORETRY;	/*! STAT_RETRYLATER? */
    }
@@ -200,7 +204,7 @@
    /* 3 means: IP address AND port accepted */
    if (retropt_bind(opts, (*pf!=PF_UNSPEC)?*pf:(*themlist)->ai_family,
 		    socktype, protocol, (struct sockaddr *)us, uslen, 3,
-		    res_opts0, res_opts1)
+		    ai_flags, res_opts)
        != STAT_NOACTION) {
       *needbind = true;
    } else {
@@ -242,12 +246,18 @@
    applies and consumes the following options:
    OPT_PROTOCOL_FAMILY, OPT_BIND
  */
-int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0,
-				   const char *portname, int *pf, int ipproto,
-				  unsigned long res_opts0,
-				  unsigned long res_opts1,
-				   union sockaddr_union *us, socklen_t *uslen,
-				   int socktype) {
+int _xioopen_ipapp_listen_prepare(
+	struct opt *opts,
+	struct opt **opts0,
+	const char *portname,
+	int *pf,
+	int ipproto,
+	const int ai_flags[2],
+	const unsigned long res_opts[2],
+	union sockaddr_union *us,
+	socklen_t *uslen,
+	int socktype)
+{
    char *bindname = NULL;
    int result;
 
@@ -256,8 +266,7 @@
    retropt_string(opts, OPT_BIND, &bindname);
    result =
 	xioresolve(bindname, portname, *pf, socktype, ipproto,
-		   us, uslen,
-		   res_opts0, res_opts1);
+		   us, uslen, ai_flags, res_opts);
    if (result != STAT_OK) {
       /*! STAT_RETRY? */
       return result;
@@ -270,7 +279,7 @@
 /* we expect the form: port */
 /* currently only used for TCP4 */
 int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts,
-			  int xioflags, xiofile_t *fd,
+			  int xioflags, xiofile_t *xfd,
 			 groups_t groups, int socktype,
 			 int ipproto, int pf) {
    struct opt *opts0 = NULL;
@@ -282,6 +291,7 @@
       Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
    }
 
+   xioinit_ip(&xfd->stream, &pf);
    if (pf == PF_UNSPEC) {
 #if WITH_IP4 && WITH_IP6
       switch (xioparms.default_ip) {
@@ -296,22 +306,22 @@
 #endif
    }
 
-   fd->stream.howtoend = END_SHUTDOWN;
+   xfd->stream.howtoend = END_SHUTDOWN;
 
-   if (applyopts_single(&fd->stream, opts, PH_INIT) < 0)  return -1;
+   if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0)  return -1;
    applyopts(-1, opts, PH_INIT);
    applyopts(-1, opts, PH_EARLY);
 
    if (_xioopen_ipapp_listen_prepare(opts, &opts0, argv[1], &pf, ipproto,
-				     fd->stream.para.socket.ip.res_opts[1],
-				     fd->stream.para.socket.ip.res_opts[0],
+				     xfd->stream.para.socket.ip.ai_flags,
+				     xfd->stream.para.socket.ip.res_opts,
 				     us, &uslen, socktype)
        != STAT_OK) {
       return STAT_NORETRY;
    }
 
    if ((result =
-	xioopen_listen(&fd->stream, xioflags,
+	xioopen_listen(&xfd->stream, xioflags,
 		       (struct sockaddr *)us, uslen,
 		     opts, opts0, pf, socktype, ipproto))
        != 0)
diff --git a/xio-ipapp.h b/xio-ipapp.h
index b064c2f..1767fff 100644
--- a/xio-ipapp.h
+++ b/xio-ipapp.h
@@ -17,15 +17,8 @@
 extern int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd,
 			 groups_t groups, int socktype,
 			 int ipproto, int protname);
-extern int
-   _xioopen_ipapp_prepare(struct opt *opts, struct opt **opts0,
-			   const char *hostname,
-			   const char *portname, int *pf, int protocol,
-			   unsigned long res_opts0, unsigned long res_opts1,
-			  struct addrinfo **res,
-			   union sockaddr_union *us,  socklen_t *uslen,
-			   bool *needbind, bool *lowport,
-			   int socktype);
+extern int _xioopen_ipapp_prepare(struct opt *opts, struct opt **opts0, const char *hostname, const char *portname, int *pf, int protocol, const int ai_flags[2], const unsigned long res_opts[2], struct addrinfo **res, union sockaddr_union *us,  socklen_t *uslen, bool *needbind, bool *lowport,
+			  int socktype);
 extern int _xioopen_ip4app_connect(const char *hostname, const char *portname,
 				   struct single *xfd,
 				   int socktype, int ipproto, void *protname,
@@ -34,11 +27,6 @@
 			  int xioflags, xiofile_t *fd,
 			 groups_t groups, int socktype,
 				 int ipproto, int protname);
-extern int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0,
-				   const char *portname, int *pf, int ipproto,
-				  unsigned long res_opts0,
-				  unsigned long res_opts1,
-				   union sockaddr_union *us, socklen_t *uslen,
-					  int socktype);
+extern int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0, const char *portname, int *pf, int ipproto, const int ai_flags[2], const unsigned long res_opts[2], union sockaddr_union *us, socklen_t *uslen, int socktype);
 
 #endif /* !defined(__xio_ipapp_h_included) */
diff --git a/xio-listen.c b/xio-listen.c
index 882caa5..408b348 100644
--- a/xio-listen.c
+++ b/xio-listen.c
@@ -199,7 +199,10 @@
 
 #if WITH_IP4 /*|| WITH_IP6*/
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
-      if (xioparserange(rangename, pf, &xfd->para.socket.range) < 0) {
+      if (xioparserange(rangename, pf, &xfd->para.socket.range,
+			xfd->para.socket.ip.ai_flags,
+			xfd->para.socket.ip.res_opts)
+	  < 0) {
 	 free(rangename);
 	 return STAT_NORETRY;
       }
diff --git a/xio-openssl.c b/xio-openssl.c
index 479cd67..42197b7 100644
--- a/xio-openssl.c
+++ b/xio-openssl.c
@@ -280,6 +280,7 @@
       return STAT_NORETRY;
    }
 
+   xioinit_ip(xfd, &pf);
    xfd->howtoend = END_SHUTDOWN;
    if (applyopts_single(xfd, opts, PH_INIT) < 0)  return -1;
    applyopts(-1, opts, PH_INIT);
@@ -326,8 +327,8 @@
 
    result =
       _xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto,
-			     xfd->para.socket.ip.res_opts[1],
-			     xfd->para.socket.ip.res_opts[0],
+			     xfd->para.socket.ip.ai_flags,
+			     xfd->para.socket.ip.res_opts,
 			     &themlist, us, &uslen,
 			     &needbind, &lowport, socktype);
    if (result != STAT_OK)  return STAT_NORETRY;
@@ -571,6 +572,7 @@
       return STAT_NORETRY;
    }
 
+   xioinit_ip(xfd, &pf);
 #if WITH_IP4 && WITH_IP6
    switch (xioparms.default_ip) {
    case '4': pf = PF_INET; break;
@@ -610,8 +612,8 @@
    retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto);
 
    if (_xioopen_ipapp_listen_prepare(opts, &opts0, portname, &pf, ipproto,
-				     xfd->para.socket.ip.res_opts[1],
-				     xfd->para.socket.ip.res_opts[0],
+				     xfd->para.socket.ip.ai_flags,
+				     xfd->para.socket.ip.res_opts,
 				     us, &uslen, socktype)
        != STAT_OK) {
       return STAT_NORETRY;
@@ -1894,7 +1896,8 @@
 			case 16: /* IPv6 */
 			   inet_ntop(AF_INET6, data, aBuffer, sizeof(aBuffer));
 			   if (peername != NULL) {
-			      xioip6_pton(peername, &ip6bin);
+			      xioip6_pton(peername, &ip6bin, xfd->para.socket.ip.ai_flags,
+					  xfd->para.socket.ip.res_opts);
 			      if (memcmp(data, &ip6bin, sizeof(ip6bin)) == 0) {
 			         Debug2("subjectAltName \"%s\" matches peername \"%s\"",
 					aBuffer, peername);
diff --git a/xio-proxy.c b/xio-proxy.c
index bcda8ad..2753d70 100644
--- a/xio-proxy.c
+++ b/xio-proxy.c
@@ -110,6 +110,7 @@
    targetname = argv[2];
    targetport = argv[3];
 
+   xioinit_ip(xfd, &pf);
    xfd->howtoend = END_SHUTDOWN;
    if (applyopts_single(xfd, opts, PH_INIT) < 0)  return -1;
    applyopts(-1, opts, PH_INIT);
@@ -124,14 +125,16 @@
       }
    }
 
-   result = _xioopen_proxy_prepare(proxyvars, opts, targetname, targetport);
+   result = _xioopen_proxy_prepare(proxyvars, opts, targetname, targetport,
+				   xfd->para.socket.ip.ai_flags,
+				   xfd->para.socket.ip.res_opts);
    if (result != STAT_OK)  return result;
 
    result =
       _xioopen_ipapp_prepare(opts, &opts0, proxyname, proxyport,
 			     &pf, ipproto,
-			     xfd->para.socket.ip.res_opts[1],
-			     xfd->para.socket.ip.res_opts[0],
+			     xfd->para.socket.ip.ai_flags,
+			     xfd->para.socket.ip.res_opts,
 			     &themlist, us, &uslen,
 			     &needbind, &lowport, socktype);
    if (result != STAT_OK)  return result;
@@ -242,8 +245,13 @@
 }
 
 
-int _xioopen_proxy_prepare(struct proxyvars *proxyvars, struct opt *opts,
-			   const char *targetname, const char *targetport) {
+int _xioopen_proxy_prepare(
+	struct proxyvars *proxyvars,
+	struct opt *opts,
+	const char *targetname,
+	const char *targetport,
+	const int ai_flags[2],
+	const unsigned long res_opts[2]) {
    union sockaddr_union host;
    socklen_t socklen = sizeof(host);
    int rc;
@@ -300,10 +308,10 @@
    if (proxyvars->doresolve) {
       /* currently we only resolve to IPv4 addresses. This is in accordance to
 	 RFC 2396; however once it becomes clear how IPv6 addresses should be
-	 represented in CONNECT commands this code might be extended */
+	 represented in CONNECT commands this code might need to be extended */
       rc = xioresolve(targetname, targetport, PF_INET/*!?*/,
-			  SOCK_STREAM, IPPROTO_TCP,
-			  &host, &socklen, 0, 0);
+		      SOCK_STREAM, IPPROTO_TCP,
+		      &host, &socklen, ai_flags, res_opts);
       if (rc != STAT_OK) {
 	 proxyvars->targetaddr = strdup(targetname);
       } else {
diff --git a/xio-proxy.h b/xio-proxy.h
index ff8530b..c8a1d26 100644
--- a/xio-proxy.h
+++ b/xio-proxy.h
@@ -25,8 +25,7 @@
 
 extern const struct addrdesc xioaddr_proxy_connect;
 
-int _xioopen_proxy_prepare(struct proxyvars *proxyvars, struct opt *opts,
-			   const char *targetname, const char *targetport);
+extern int _xioopen_proxy_prepare(struct proxyvars *proxyvars, struct opt *opts, const char *targetname, const char *targetport, const int ai_flags[2], const unsigned long res_opts[2]);
 int _xioopen_proxy_connect(struct single *xfd,
 			   struct proxyvars *proxyvars,
 			   int level);
diff --git a/xio-rawip.c b/xio-rawip.c
index 76984f9..a314a75 100644
--- a/xio-rawip.c
+++ b/xio-rawip.c
@@ -73,6 +73,8 @@
 	     argv[0], argc-1);
       return STAT_NORETRY;
    }
+
+   xioinit_ip(&xxfd->stream, &pf);
    if ((result = _xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd,
 				       groups, &pf)) != STAT_OK) {
       return result;
@@ -123,8 +125,8 @@
    if ((result =
 	xioresolve(hostname, NULL, *pf, socktype, ipproto,
 		       &xfd->peersa, &xfd->salen,
-		       xfd->para.socket.ip.res_opts[0],
-		       xfd->para.socket.ip.res_opts[1]))
+		       xfd->para.socket.ip.ai_flags,
+		       xfd->para.socket.ip.res_opts))
        != STAT_OK) {
       return result;
    }
@@ -137,8 +139,9 @@
    xfd->dtype = XIODATA_RECVFROM_SKIPIP;
 
    if (retropt_bind(opts, *pf, socktype, ipproto, &us.soa, &uslen, feats,
-		    xfd->para.socket.ip.res_opts[0],
-		    xfd->para.socket.ip.res_opts[1]) != STAT_NOACTION) {
+		    xfd->para.socket.ip.ai_flags,
+		    xfd->para.socket.ip.res_opts)
+       != STAT_NOACTION) {
       needbind = true;
    }
    return
@@ -161,6 +164,8 @@
 	     argv[0], argc-1);
       return STAT_NORETRY;
    }
+
+   xioinit_ip(xfd, &pf);
    if ((result =
 	_xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd,
 				groups, &pf)) != STAT_OK) {
@@ -176,7 +181,10 @@
 
    /* which reply packets will be accepted - determine by range option */
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
-      if (xioparserange(rangename, pf, &xfd->para.socket.range) < 0) {
+      if (xioparserange(rangename, pf, &xfd->para.socket.range,
+			xfd->para.socket.ip.ai_flags,
+			xfd->para.socket.ip.res_opts)
+	  < 0) {
 	 free(rangename);
 	 return STAT_NORETRY;
       }
@@ -212,6 +220,7 @@
       return STAT_NORETRY;
    }
 
+   xioinit_ip(&xfd->stream, &pf);
    if ((ipproto = strtoul(protname, &garbage, 0)) >= 256) {
       Error2("xioopen_rawip_recvfrom(\"%s\",,): protocol number exceeds 255 (%u)",
 	     protname, ipproto);
@@ -239,8 +248,9 @@
    }
 
    if (retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, 1,
-		    xfd->stream.para.socket.ip.res_opts[0],
-		    xfd->stream.para.socket.ip.res_opts[1]) != STAT_NOACTION) {
+		    xfd->stream.para.socket.ip.ai_flags,
+		    xfd->stream.para.socket.ip.res_opts)
+       != STAT_NOACTION) {
       needbind = true;
    }
 
@@ -274,6 +284,7 @@
       return STAT_NORETRY;
    }
 
+   xioinit_ip(&xfd->stream, &pf);
    if ((ipproto = strtoul(protname, &garbage, 0)) >= 256) {
       Error2("xioopen_rawip_recv(\"%s\",,): protocol number exceeds 255 (%u)",
 	     protname, ipproto);
@@ -297,9 +308,9 @@
 
    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]) ==
-       STAT_OK) {
+		    xfd->stream.para.socket.ip.ai_flags,
+		    xfd->stream.para.socket.ip.res_opts)
+       == STAT_OK) {
       needbind = true;
    } else {
       /* pf is required during xioread checks */
diff --git a/xio-socket.c b/xio-socket.c
index 572cdb7..749ac0d 100644
--- a/xio-socket.c
+++ b/xio-socket.c
@@ -277,7 +277,7 @@
 
    socket_init(0, &us);
    if (retropt_bind(opts, 0 /*pf*/, socktype, proto, (struct sockaddr *)&us, &uslen, 3,
-		    0, 0)
+		    xfd->para.socket.ip.ai_flags, xfd->para.socket.ip.res_opts)
        != STAT_NOACTION) {
       needbind = true;
       us.soa.sa_family = pf;
@@ -540,7 +540,10 @@
    xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
 
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
-      if (xioparserange(rangename, 0, &xfd->para.socket.range) < 0) {
+      if (xioparserange(rangename, 0, &xfd->para.socket.range,
+			xfd->para.socket.ip.ai_flags,
+			xfd->para.socket.ip.res_opts)
+	  < 0) {
 	 free(rangename);
 	 return STAT_NORETRY;
       }
@@ -619,7 +622,10 @@
    xfd->para.socket.la.soa.sa_family = pf;
 
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
-      if (xioparserange(rangename, 0, &xfd->para.socket.range) < 0) {
+      if (xioparserange(rangename, 0, &xfd->para.socket.range,
+			xfd->para.socket.ip.ai_flags,
+			xfd->para.socket.ip.res_opts)
+	  < 0) {
 	 free(rangename);
 	 return STAT_NORETRY;
       }
@@ -699,7 +705,10 @@
 
    /* which reply sockets will accept - determine by range option */
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
-      if (xioparserange(rangename, 0, &xfd->para.socket.range) < 0) {
+      if (xioparserange(rangename, 0, &xfd->para.socket.range,
+			xfd->para.socket.ip.ai_flags,
+			xfd->para.socket.ip.res_opts)
+	  < 0) {
 	 free(rangename);
 	 return STAT_NORETRY;
       }
@@ -1169,7 +1178,10 @@
 
    /* for generic sockets, this has already been retrieved */
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
-      if (xioparserange(rangename, pf, &xfd->para.socket.range) < 0) {
+      if (xioparserange(rangename, pf, &xfd->para.socket.range,
+			xfd->para.socket.ip.ai_flags,
+			xfd->para.socket.ip.res_opts)
+	  < 0) {
 	 free(rangename);
 	 return STAT_NORETRY;
       }
@@ -1371,7 +1383,10 @@
 
 #if WITH_IP4 /*|| WITH_IP6*/
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
-      if (xioparserange(rangename, pf, &xfd->para.socket.range) < 0) {
+      if (xioparserange(rangename, pf, &xfd->para.socket.range,
+			xfd->para.socket.ip.ai_flags,
+			xfd->para.socket.ip.res_opts)
+	  < 0) {
 	 free(rangename);
 	 return STAT_NORETRY;
       }
@@ -1814,19 +1829,25 @@
 
 
 /* parses a network specification consisting of an address and a mask. */
-int xioparsenetwork(const char *rangename, int pf, struct xiorange *range) {
+int xioparsenetwork(
+	const char *rangename,
+	int pf,
+	struct xiorange *range,
+	const int ai_flags[2],
+	const unsigned long res_opts[2])
+{
    size_t addrlen = 0, masklen = 0;
    int result;
 
   switch (pf) {
 #if WITH_IP4
   case PF_INET:
-      return xioparsenetwork_ip4(rangename, range);
+     return xioparsenetwork_ip4(rangename, range, ai_flags, res_opts);
    break;
 #endif /* WITH_IP4 */
 #if WITH_IP6
    case PF_INET6:
-      return xioparsenetwork_ip6(rangename, range);
+      return xioparsenetwork_ip6(rangename, range, ai_flags, res_opts);
       break;
 #endif /* WITH_IP6 */
   case PF_UNSPEC:
@@ -1887,9 +1908,15 @@
 
 /* parses a string of form address/bits or address:mask, and fills the fields
    of the range union. The addr component is masked with mask. */
-int xioparserange(const char *rangename, int pf, struct xiorange *range) {
+int xioparserange(
+	const char *rangename,
+	int pf,
+	struct xiorange *range,
+	const int ai_flags[2],
+	const unsigned long res_opts[2])
+{
    int i;
-   if (xioparsenetwork(rangename, pf, range) < 0) {
+   if (xioparsenetwork(rangename, pf, range, ai_flags, res_opts) < 0) {
       Error2("failed to parse or resolve range \"%s\" (pf=%d)", rangename, pf);
       return -1;
    }
diff --git a/xio-socket.h b/xio-socket.h
index c7be43a..cea2749 100644
--- a/xio-socket.h
+++ b/xio-socket.h
@@ -125,11 +125,8 @@
 extern
 int xiosetsockaddrenv(const char *lr, union sockaddr_union *sau, socklen_t salen, int proto);
 
-extern
-int xioparsenetwork(const char *rangename, int pf,
-		    struct xiorange *range);
-extern
-int xioparserange(const char *rangename, int pf, struct xiorange *range);
+extern int xioparsenetwork(const char *rangename, int pf, struct xiorange *range, const int ai_flags[2], const unsigned long res_opts[2]);
+extern int xioparserange(const char *rangename, int pf, struct xiorange *range, const int ai_flags[2], const unsigned long res_opts[2]);
 
 extern int
 xiosocket(struct opt *opts, int pf, int socktype, int proto, int level);
diff --git a/xio-socks.c b/xio-socks.c
index b7472e5..77e5312 100644
--- a/xio-socks.c
+++ b/xio-socks.c
@@ -72,6 +72,7 @@
    targetname = argv[2];
    targetport = argv[3];
 
+   xioinit_ip(xfd, &pf);
    xfd->howtoend = END_SHUTDOWN;
    if (applyopts_single(xfd, opts, PH_INIT) < 0)  return -1;
    applyopts(-1, opts, PH_INIT);
@@ -85,8 +86,8 @@
    result =
       _xioopen_ipapp_prepare(opts, &opts0, sockdname, socksport,
 			     &pf, ipproto,
-			     xfd->para.socket.ip.res_opts[1],
-			     xfd->para.socket.ip.res_opts[0],
+			     xfd->para.socket.ip.ai_flags,
+			     xfd->para.socket.ip.res_opts,
 			     &themlist, us, &uslen,
 			     &needbind, &lowport, socktype);
 
@@ -272,10 +273,10 @@
       socklen_t saulen = sizeof(sau);
 
       if ((result = xioresolve(hostname, NULL,
-				   PF_INET, SOCK_STREAM, IPPROTO_TCP,
-				   &sau, &saulen,
-				   xfd->para.socket.ip.res_opts[1],
-				   xfd->para.socket.ip.res_opts[0]))
+			       PF_INET, SOCK_STREAM, IPPROTO_TCP,
+			       &sau, &saulen,
+			       xfd->para.socket.ip.ai_flags,
+			       xfd->para.socket.ip.res_opts))
 	  != STAT_OK) {
 	 return result;	/*! STAT_RETRY? */
       }
diff --git a/xio-tun.c b/xio-tun.c
index 707331e..e7eb003 100644
--- a/xio-tun.c
+++ b/xio-tun.c
@@ -133,7 +133,10 @@
           Error1("strdup(\"%s\"): out of memory", argv[1]);
           return STAT_RETRYLATER;
        }
-       if ((result = xioparsenetwork(ifaddr, pf, &network)) != STAT_OK) {
+       if ((result = xioparsenetwork(ifaddr, pf, &network,
+				     xfd->stream.para.socket.ip.ai_flags,
+				     xfd->stream.para.socket.ip.res_opts))
+	   != STAT_OK) {
           /*! recover */
           return result;
        }
diff --git a/xio-udp.c b/xio-udp.c
index 5a3215f..8e7477e 100644
--- a/xio-udp.c
+++ b/xio-udp.c
@@ -107,7 +107,10 @@
 
 #if WITH_IP4 /*|| WITH_IP6*/
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
-      if (xioparserange(rangename, pf, &sfd->para.socket.range) < 0) {
+      if (xioparserange(rangename, pf, &sfd->para.socket.range,
+			sfd->para.socket.ip.ai_flags,
+			sfd->para.socket.ip.res_opts)
+	  < 0) {
 	 free(rangename);
 	 return STAT_NORETRY;
       }
@@ -282,7 +285,7 @@
 
 /* we expect the form: port */
 int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
-			   int xioflags, xiofile_t *fd,
+			   int xioflags, xiofile_t *xfd,
 			  groups_t groups, int pf, int ipproto,
 			  int protname) {
    const char *portname = argv[1];
@@ -294,6 +297,7 @@
       Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
    }
 
+   xioinit_ip(&xfd->stream, &pf);
    if (pf == PF_UNSPEC) {
 #if WITH_IP4 && WITH_IP6
       switch (xioparms.default_ip) {
@@ -311,14 +315,14 @@
    retropt_socket_pf(opts, &pf);
    retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto);
 
-   if (applyopts_single(&fd->stream, opts, PH_INIT) < 0)  return -1;
+   if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0)  return -1;
    applyopts(-1, opts, PH_INIT);
 
    uslen = socket_init(pf, &us);
    retropt_bind(opts, pf, socktype, ipproto,
 		(struct sockaddr *)&us, &uslen, 1,
-		fd->stream.para.socket.ip.res_opts[1],
-		fd->stream.para.socket.ip.res_opts[0]);
+		xfd->stream.para.socket.ip.ai_flags,
+		xfd->stream.para.socket.ip.res_opts);
 
    if (false) {
       ;
@@ -334,13 +338,13 @@
       Error1("xioopen_ipdgram_listen(): unknown address family %d", pf);
    }
 
-   return _xioopen_ipdgram_listen(&fd->stream, xioflags, &us, uslen,
+   return _xioopen_ipdgram_listen(&xfd->stream, xioflags, &us, uslen,
 				  opts, pf, socktype, ipproto);
 }
 
 static
 int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts,
-		     int xioflags, xiofile_t *xxfd, groups_t groups,
+		     int xioflags, xiofile_t *xfd, groups_t groups,
 		     int pf, int socktype, int ipproto) {
    int result;
 
@@ -350,13 +354,14 @@
       return STAT_NORETRY;
    }
 
+   xioinit_ip(&xfd->stream, &pf);
    retropt_socket_pf(opts, &pf);
-   if ((result = _xioopen_udp_sendto(argv[1], argv[2], opts, xioflags, xxfd,
+   if ((result = _xioopen_udp_sendto(argv[1], argv[2], opts, xioflags, xfd,
 				     groups, pf, socktype, ipproto))
        != STAT_OK) {
       return result;
    }
-   _xio_openlate(&xxfd->stream, opts);
+   _xio_openlate(&xfd->stream, opts);
    return STAT_OK;
 }
 
@@ -387,9 +392,9 @@
    xfd->salen = sizeof(xfd->peersa);
    if ((result =
 	xioresolve(hostname, servname, pf, socktype, ipproto,
-		       &xfd->peersa, &xfd->salen,
-		       xfd->para.socket.ip.res_opts[0],
-		       xfd->para.socket.ip.res_opts[1]))
+		   &xfd->peersa, &xfd->salen,
+		   xfd->para.socket.ip.ai_flags,
+		   xfd->para.socket.ip.res_opts))
        != STAT_OK) {
       return result;
    }
@@ -398,8 +403,8 @@
    }
    uslen = socket_init(pf, &us);
    if (retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, feats,
-		    xfd->para.socket.ip.res_opts[0],
-		    xfd->para.socket.ip.res_opts[1])
+		    xfd->para.socket.ip.ai_flags,
+		    xfd->para.socket.ip.res_opts)
        != STAT_NOACTION) {
       needbind = true;
    }
@@ -446,6 +451,7 @@
       return STAT_NORETRY;
    }
 
+   xioinit_ip(xfd, &pf);
    if ((hostname = strdup(argv[1])) == NULL) {
       Error1("strdup(\"%s\"): out of memory", argv[1]);
       return STAT_RETRYLATER;
@@ -474,7 +480,10 @@
    /* which reply packets will be accepted - determine by range option */
    if (retropt_string(opts, OPT_RANGE, &rangename)
        >= 0) {
-      if (xioparserange(rangename, pf, &xfd->para.socket.range) < 0) {
+      if (xioparserange(rangename, pf, &xfd->para.socket.range,
+			xfd->para.socket.ip.ai_flags,
+			xfd->para.socket.ip.res_opts)
+	  < 0) {
 	 free(rangename);
 	 return STAT_NORETRY;
       }
@@ -506,6 +515,7 @@
       return STAT_NORETRY;
    }
 
+   xioinit_ip(&xfd->stream, &pf);
    xfd->stream.howtoend = END_NONE;
    retropt_socket_pf(opts, &pf);
    if (pf == PF_UNSPEC) {
@@ -523,9 +533,9 @@
    }
 
    if ((result =
-	xioresolve(NULL, argv[1], pf, socktype, ipproto,
-		       &us, &uslen, xfd->stream.para.socket.ip.res_opts[0],
-		       xfd->stream.para.socket.ip.res_opts[1]))
+	xioresolve(NULL, argv[1], pf, socktype, ipproto, &us, &uslen,
+		   xfd->stream.para.socket.ip.ai_flags,
+		   xfd->stream.para.socket.ip.res_opts))
        != STAT_OK) {
       return result;
    }
@@ -538,8 +548,8 @@
       socklen_t lalen = sizeof(la);
 
       if (retropt_bind(opts, pf, socktype, ipproto, &la.soa, &lalen, 1,
-		       xfd->stream.para.socket.ip.res_opts[0],
-		       xfd->stream.para.socket.ip.res_opts[1])
+		       xfd->stream.para.socket.ip.ai_flags,
+		       xfd->stream.para.socket.ip.res_opts)
 	  != STAT_NOACTION) {
 	 switch (pf) {
 #if WITH_IP4
@@ -584,6 +594,7 @@
       return STAT_NORETRY;
    }
 
+   xioinit_ip(&xfd->stream, &pf);
    retropt_socket_pf(opts, &pf);
    if (pf == PF_UNSPEC) {
 #if WITH_IP4 && WITH_IP6
@@ -600,9 +611,9 @@
    }
 
    if ((result =
-	xioresolve(NULL, argv[1], pf, socktype, ipproto,
-		       &us, &uslen, xfd->stream.para.socket.ip.res_opts[0],
-		       xfd->stream.para.socket.ip.res_opts[1]))
+	xioresolve(NULL, argv[1], pf, socktype, ipproto, &us, &uslen,
+		   xfd->stream.para.socket.ip.ai_flags,
+		   xfd->stream.para.socket.ip.res_opts))
        != STAT_OK) {
       return result;
    }
@@ -617,8 +628,8 @@
 
       if (retropt_bind(opts, pf, socktype, ipproto,
 		       &xfd->stream.para.socket.la.soa, &lalen, 1,
-		       xfd->stream.para.socket.ip.res_opts[0],
-		       xfd->stream.para.socket.ip.res_opts[1])
+		       xfd->stream.para.socket.ip.ai_flags,
+		       xfd->stream.para.socket.ip.res_opts)
 	  != STAT_NOACTION) {
 	 switch (pf) {
 #if WITH_IP4
@@ -638,7 +649,10 @@
 
 #if WITH_IP4 /*|| WITH_IP6*/
    if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
-      if (xioparserange(rangename, pf, &xfd->stream.para.socket.range) < 0) {
+      if (xioparserange(rangename, pf, &xfd->stream.para.socket.range,
+			xfd->stream.para.socket.ip.ai_flags,
+			xfd->stream.para.socket.ip.res_opts)
+	  < 0) {
 	 free(rangename);
 	 return STAT_NORETRY;
       }
diff --git a/xio-unix.c b/xio-unix.c
index 3cc4f36..5de2bd6 100644
--- a/xio-unix.c
+++ b/xio-unix.c
@@ -240,7 +240,8 @@
       retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
    }
    if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen,
-		    (abstract<<1)|xfd->para.socket.un.tight, 0, 0) == STAT_OK) {
+		    (abstract<<1)|xfd->para.socket.un.tight, NULL, NULL)
+       == STAT_OK) {
       needbind = true;
    }
 
@@ -383,7 +384,8 @@
    xfd->dtype = XIODATA_RECVFROM;
 
    if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen,
-		   (abstract<<1)| xfd->para.socket.un.tight, 0, 0) == STAT_OK) {
+		    (abstract<<1)| xfd->para.socket.un.tight, NULL, NULL)
+       == STAT_OK) {
       needbind = true;
    }
 
@@ -451,7 +453,8 @@
 
 #if 0
    if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen,
-		    (abstract<<1)|xfd->para.socket.un.tight, 0, 0) == STAT_OK) {
+		    (abstract<<1)|xfd->para.socket.un.tight, NULL, NULL)
+       == STAT_OK) {
    }
 #endif
 
@@ -531,7 +534,7 @@
 
 #if 0
    if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen,
-		    (abstract<<1)|xfd->para.socket.un.tight, 0, 0)
+		    (abstract<<1)|xfd->para.socket.un.tight, NULL, NULL)
        == STAT_OK) {
    }
 #endif
@@ -616,7 +619,7 @@
       retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
    }
    if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen,
-		    (abstract<<1)|xfd->para.socket.un.tight, 0, 0)
+		    (abstract<<1)|xfd->para.socket.un.tight, NULL, NULL)
        != STAT_NOACTION) {
       needbind = true;
    }
diff --git a/xio-vsock.c b/xio-vsock.c
index e6e6465..fca97f0 100644
--- a/xio-vsock.c
+++ b/xio-vsock.c
@@ -96,7 +96,8 @@
    xiolog_vsock_cid();
 
    ret = retropt_bind(opts, pf, socktype, protocol,
-                      (struct sockaddr *)&sa_local, &sa_len, 3, 0, 0);
+                      (struct sockaddr *)&sa_local, &sa_len, 3,
+		      NULL, NULL);
    if (ret == STAT_NORETRY)
       return ret;
    if (ret == STAT_OK)
@@ -153,7 +154,7 @@
    opts0 = copyopts(opts, GROUP_ALL);
 
    ret = retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&sa_bind,
-                      &sa_len, 1, 0, 0);
+                      &sa_len, 1, NULL, NULL);
    if (ret == STAT_NORETRY)
        return ret;
    if (ret == STAT_OK)
diff --git a/xio.h b/xio.h
index 910909c..1d72fa3 100644
--- a/xio.h
+++ b/xio.h
@@ -130,7 +130,8 @@
 
 #if _WITH_IP4 || _WITH_IP6
 struct para_ip {
-	unsigned int res_opts[2];	/* bits to be set in _res.options are
+	int	      ai_flags[2]; 	/* flags for getaddrinfo() ai_flags (set/unset) */
+	unsigned long res_opts[2];	/* bits to be set in _res.options are
 					   at [0], bits to be cleared are at [1] */
 	bool     dosourceport; 	/* check the source port of incoming connection or packets */
 	uint16_t sourceport;		/* host byte order */
diff --git a/xioopts.c b/xioopts.c
index 2154a12..7878096 100644
--- a/xioopts.c
+++ b/xioopts.c
@@ -173,6 +173,12 @@
 #if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP)
 	IF_IP     ("add-source-membership",	&opt_ip_add_source_membership)
 #endif
+#if defined(AI_ADDRCONFIG)
+	IF_IP	  ("addrconfig", 		&opt_ai_addrconfig)
+#endif
+#if defined(AI_ADDRCONFIG)
+	IF_IP	  ("ai-addrconfig", 		&opt_ai_addrconfig)
+#endif
 	IF_INTERFACE("allmulti",	&opt_iff_allmulti)
 #if WITH_LIBWRAP && defined(HAVE_HOSTS_ALLOW_TABLE)
 	IF_IPAPP  ("allow-table",	&opt_tcpwrap_hosts_allow_table)
@@ -2597,8 +2603,8 @@
 	    }
 	    *buffp = '\0';
 	    if (xioresolve(buff, NULL, AF_INET, SOCK_DGRAM, IPPROTO_IP,
-			   (union sockaddr_union *)&sa, &salen,
-			       0, 0/*!!!*/) != STAT_OK) {
+			   (union sockaddr_union *)&sa, &salen, NULL,
+			   NULL/*!! !*/) != STAT_OK) {
 	       opt->desc = ODESC_ERROR; continue;
 	    }
 	    opt->value.u_ip4addr = sa.sin_addr;
@@ -3109,7 +3115,8 @@
 				   UNIX (or'd): 1..tight
 						2..abstract
 				*/
-		 unsigned long res_opts0, unsigned long res_opts1) {
+		 const int ai_flags[2], const unsigned long res_opts[2])
+{
    const char portsep[] = ":";
    const char *ends[] = { portsep, NULL };
    const char *nests[] = { "[", "]", NULL };
@@ -3175,9 +3182,9 @@
       }
       if ((result =
 	   xioresolve(hostname[0]!='\0'?hostname:NULL, portp,
-			  af, socktype, ipproto,
-			  (union sockaddr_union *)sa, salen,
-			  res_opts0, res_opts1))
+		      af, socktype, ipproto,
+		      (union sockaddr_union *)sa, salen,
+		      ai_flags, res_opts))
 	  != STAT_OK) {
 	 Error("error resolving bind option");
 	 return STAT_NORETRY;
@@ -4070,6 +4077,10 @@
       break;
 
      case OFUNC_OFFSET_MASKS:
+	/* An external (e.g. library) variable with independent bits is to be
+	   manipulated. Here the data target is an array with size 2, the first
+	   element holds the bit mask to be set, the second one those to be
+	   cleared. Each related option sets or unsets a specific bit. */
 	{
 	   void *masks = (char *)xfd + opt->desc->major;
 	   size_t masksize = opt->desc->minor;
@@ -4089,8 +4100,14 @@
 		 ((uint32_t *)masks)[1] |= bit;
 	      }
 	      break;
+	   case sizeof(uint64_t):
+	      if (opt->value.u_bool) {
+		 ((uint64_t *)masks)[0] |= bit;
+	      } else {
+		 ((uint64_t *)masks)[1] |= bit;
+	      }
+	      break;
 	   default:
-	      Info1("sizeof(uint32_t)="F_Zu, sizeof(uint32_t));
 	      Error1("applyopts_single: masksize "F_Zu" not implemented",
 		     masksize);
 	   }
diff --git a/xioopts.h b/xioopts.h
index d1893b9..ab9fe88 100644
--- a/xioopts.h
+++ b/xioopts.h
@@ -24,6 +24,7 @@
    TYPE_CONST,		/* keyword means a fix value - implies int type */
    TYPE_BIN,		/* raw binary data, length determined by data */
    TYPE_BOOL,		/* value is 0 or 1 (no-value is interpreted as 1) */
+   TYPE_BOOL_NULL,	/* value is 0 or 1 (no-value is interpreted as 1), or just opt= */
    TYPE_BYTE,		/* unsigned char */
 
    TYPE_INT,		/* int */
@@ -103,7 +104,7 @@
    OFUNC_TERMIO,	/* termio() ? */
    OFUNC_SPEC,		/* special, i.e. no generalizable function call */
    OFUNC_OFFSET,	/* put a value into xiofile struct; major is offset */
-   OFUNC_OFFSET_MASKS,	/* !!! */
+   OFUNC_OFFSET_MASKS,	/* set pos or neg bit pattern in array[2] */
    /*OFUNC_APPL,*/	/* special, i.e. application must know which f. */
    OFUNC_EXT,		/* with extended file descriptors only */
    OFUNC_TERMIOS_FLAG,	/* a flag in struct termios: major..tcflag, minor..bit
@@ -201,6 +202,7 @@
 /* optcode's */
 enum e_optcode {
    OPT_ADDRESS_FAMILY = 1,
+   OPT_AI_ADDRCONFIG, 	/* getaddrinfo() */
    /* these are not alphabetically, I know... */
    OPT_B0,		/* termios.c_cflag */
    OPT_B50,		/* termios.c_cflag */
@@ -954,15 +956,7 @@
 extern int retropt_flag(struct opt *opts, int optcode, flags_t *result);
 extern int retropt_string(struct opt *opts, int optcode, char **result);
 extern int retropt_timespec(struct opt *opts, int optcode, struct timespec *result);
-extern int retropt_bind(struct opt *opts,
-		 int af,
-		 int socktype,
-		 int ipproto,
-		 struct sockaddr *sa,
-		 socklen_t *salen,
-		 int feats,	/* TCP etc: 1..address allowed,
-				   3..address and port allowed */
-		 unsigned long res_opts0, unsigned long res_opts1);
+extern int retropt_bind(struct opt *opts, int af, int socktype, int ipproto, struct sockaddr *sa, socklen_t *salen, int feats, const int ai_flags[2], const unsigned long res_opts[2]);
 extern int applyopts(int fd, struct opt *opts, enum e_phase phase);
 extern int applyopts2(int fd, struct opt *opts, unsigned int from,
 		      unsigned int to);