mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
Added option res-nsaddr
This commit is contained in:
parent
282db9feda
commit
254958a34d
12 changed files with 234 additions and 12 deletions
3
CHANGES
3
CHANGES
|
@ -140,6 +140,9 @@ Features:
|
||||||
number of times to retransmit.
|
number of times to retransmit.
|
||||||
Disable them and the old res-* opts with: ./configure --disable-resolve
|
Disable them and the old res-* opts with: ./configure --disable-resolve
|
||||||
|
|
||||||
|
Added option res-nsaddr that overrides /etc/resolv.conf nameserver
|
||||||
|
address based on an undocumented resolver feature.
|
||||||
|
|
||||||
Corrections:
|
Corrections:
|
||||||
When a sub process (EXEC, SYSTEM) terminated with exit code other than
|
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/
|
0, its last sent data might have been lost depending on timing of read/
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
"1.7.4.5+"
|
"1.7.4.5+20230721"
|
||||||
|
|
|
@ -680,6 +680,7 @@
|
||||||
|
|
||||||
#undef HAVE_RES_RETRANS
|
#undef HAVE_RES_RETRANS
|
||||||
#undef HAVE_RES_RETRY
|
#undef HAVE_RES_RETRY
|
||||||
|
#undef HAVE_RES_NSADDR_LIST
|
||||||
|
|
||||||
#undef HAVE_SETGRENT
|
#undef HAVE_SETGRENT
|
||||||
#undef HAVE_GETGRENT
|
#undef HAVE_GETGRENT
|
||||||
|
|
|
@ -2156,6 +2156,12 @@ AC_TRY_COMPILE([#include <resolv.h>],
|
||||||
[AC_MSG_RESULT(yes);
|
[AC_MSG_RESULT(yes);
|
||||||
AC_DEFINE(HAVE_RES_RETRY, 1)],
|
AC_DEFINE(HAVE_RES_RETRY, 1)],
|
||||||
[AC_MSG_RESULT(no)])
|
[AC_MSG_RESULT(no)])
|
||||||
|
AC_MSG_CHECKING(for _res.nsaddr_list)
|
||||||
|
AC_TRY_COMPILE([#include <resolv.h>],
|
||||||
|
[_res.nsaddr_list[0].sin_family == 0],
|
||||||
|
[AC_MSG_RESULT(yes);
|
||||||
|
AC_DEFINE(HAVE_RES_NSADDR_LIST, 1)],
|
||||||
|
[AC_MSG_RESULT(no)])
|
||||||
|
|
||||||
|
|
||||||
dnl "tcpd" "tcpwrappers"
|
dnl "tcpd" "tcpwrappers"
|
||||||
|
|
33
doc/socat.yo
33
doc/socat.yo
|
@ -2397,23 +2397,39 @@ label(OPTOIN_IP_TRANSPARENT)
|
||||||
dit(bf(tt(ip-transparent)))
|
dit(bf(tt(ip-transparent)))
|
||||||
Sets the IP_TRANSPARENT socket option.
|
Sets the IP_TRANSPARENT socket option.
|
||||||
This option might require root privilege.
|
This option might require root privilege.
|
||||||
|
enddit()
|
||||||
|
|
||||||
|
startdit()enddit()nl()
|
||||||
|
|
||||||
|
label(OPTIONS_RESOLVER)em(bf(Resolver options))
|
||||||
|
|
||||||
|
These options temporarily change the behaviour of hostname resolution. The
|
||||||
|
options of form code(ai-*) affect behaviour of the code(getaddrinfo()) function that
|
||||||
|
includes code(/etc/hosts) and NIS based lookups.
|
||||||
|
|
||||||
|
The addresses of form code(res-*) only affect DNS lookups, and only when the
|
||||||
|
result is not cached in code(nscd). These options might not work on all
|
||||||
|
operating systems or libc implementations.
|
||||||
|
|
||||||
|
startdit()
|
||||||
label(OPTION_AI_ADDRCONFIG)
|
label(OPTION_AI_ADDRCONFIG)
|
||||||
dit(bf(tt(ai-addrconfig[=0|1]))), dit(bf(tt(addrconfig[=0|1])))
|
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
|
Sets or unsets the AI_ADDRCONFIG flag to prevent name resolution to address
|
||||||
families that are not available on the computer (e.g. IPv6). Default value
|
families that are not available on the computer (e.g. IPv6). Default value
|
||||||
is 1 in case the resolver does not get an address family hint from Socat
|
is 1 in case the resolver does not get an address family hint from Socat
|
||||||
address or defaults.
|
address or defaults.
|
||||||
label(OPTION_AI_PASSIVE)
|
label(OPTION_AI_PASSIVE)
|
||||||
dit(bf(tt(ai-passive[=0|1]))), dit(bf(tt(passive[=0|1])))
|
dit(bf(tt(ai-passive[=0|1]))) dit(bf(tt(passive[=0|1])))
|
||||||
Sets of unsets the AI_ADDRCONFIG flag for code(getaddrinfo()) calls.
|
Sets of unsets the AI_PASSIVE flag for code(getaddrinfo()) calls.
|
||||||
Default is 1 for LISTEN, RECV, and RECVFROM type addresses, and with
|
Default is 1 for LISTEN, RECV, and RECVFROM type addresses, and with
|
||||||
link(bind)(OPTION_BIND) option.
|
link(bind)(OPTION_BIND) option.
|
||||||
label(OPTION_AI_V4MAPPED)
|
label(OPTION_AI_V4MAPPED)
|
||||||
dit(bf(tt(ai-v4mapped[=0|1]))), dit(bf(tt(v4mapped[=0|1])))
|
dit(bf(tt(ai-v4mapped[=0|1]))) dit(bf(tt(v4mapped[=0|1])))
|
||||||
Sets or unsets the AI_V4MAPPED flag for code(getaddrinfo()). With socat()
|
Sets or unsets the AI_V4MAPPED flag for code(getaddrinfo()). With socat()
|
||||||
addresses requiring IPv6 addresses, this resolves IPv4 addresses to the
|
addresses requiring IPv6 addresses, this resolves IPv4 addresses to the
|
||||||
approriate IPv6 address [::ffff:*:*]. For IPv6 Socat addresses, the default
|
approriate IPv6 address [::ffff:*:*]. For IPv6 Socat addresses, the default
|
||||||
is 1.
|
is 1.
|
||||||
|
|
||||||
label(OPTION_RES_DEBUG)dit(bf(tt(res-debug)))
|
label(OPTION_RES_DEBUG)dit(bf(tt(res-debug)))
|
||||||
label(OPTION_RES_AAONLY)dit(bf(tt(res-aaonly)))
|
label(OPTION_RES_AAONLY)dit(bf(tt(res-aaonly)))
|
||||||
label(OPTION_RES_USEVC)dit(bf(tt(res-usevc)))
|
label(OPTION_RES_USEVC)dit(bf(tt(res-usevc)))
|
||||||
|
@ -2437,6 +2453,12 @@ label(OPTION_RES_RETRANS)dit(bf(tt(res-retrans=<int>)))
|
||||||
label(OPTION_RES_RETRY)dit(bf(tt(res-retry=<int>)))
|
label(OPTION_RES_RETRY)dit(bf(tt(res-retry=<int>)))
|
||||||
Sets the number of retransmits of the DNS resolver (based on an undocumented
|
Sets the number of retransmits of the DNS resolver (based on an undocumented
|
||||||
feature).
|
feature).
|
||||||
|
label(OPTION_RES_NSADDR)dit(bf(tt(res-nsaddr=<ipaddr>[:<port>])))
|
||||||
|
Tries to overwrite nameserver settings loaded from /etc/resolv.conf by
|
||||||
|
writing the given IPv4 address into the undocumented
|
||||||
|
code(_res:nsaddr_list[0]) field.
|
||||||
|
code(/etc/hosts) is still checked by resolver. Please note that glibc's
|
||||||
|
code(nscd) is always queried first when it is running!
|
||||||
enddit()
|
enddit()
|
||||||
|
|
||||||
startdit()enddit()nl()
|
startdit()enddit()nl()
|
||||||
|
@ -2707,6 +2729,7 @@ label(OPTION_ACCEPT_TIMEOUT)dit(bf(tt(accept-timeout=<seconds>)))
|
||||||
End waiting for a connection after <seconds> [link(timeval)(TYPE_TIMEVAL)]
|
End waiting for a connection after <seconds> [link(timeval)(TYPE_TIMEVAL)]
|
||||||
with error status.
|
with error status.
|
||||||
enddit()
|
enddit()
|
||||||
|
|
||||||
startdit()enddit()nl()
|
startdit()enddit()nl()
|
||||||
|
|
||||||
|
|
||||||
|
@ -2826,6 +2849,7 @@ label(GROUP_SHELL)
|
||||||
|
|
||||||
Options for link(address SHELL)(ADDRESS_SHELL)
|
Options for link(address SHELL)(ADDRESS_SHELL)
|
||||||
|
|
||||||
|
startdit()
|
||||||
label(OPTION_SHELL)dit(bf(tt(shell=<filename>)))
|
label(OPTION_SHELL)dit(bf(tt(shell=<filename>)))
|
||||||
Overwrites use the default shell with the named executable, e.g.
|
Overwrites use the default shell with the named executable, e.g.
|
||||||
tt(/bin/dash). Also sets the tt(SHELL) environment variable.
|
tt(/bin/dash). Also sets the tt(SHELL) environment variable.
|
||||||
|
@ -3217,6 +3241,7 @@ measures are required to get the VLAN information, see NOEXPAND(packet(7)) PACKE
|
||||||
and to optionally insert the tag into the packet again, use option
|
and to optionally insert the tag into the packet again, use option
|
||||||
link(retrieve-vlan)(OPTION_RETRIEVE_VLAN) when you need this.
|
link(retrieve-vlan)(OPTION_RETRIEVE_VLAN) when you need this.
|
||||||
|
|
||||||
|
startdit()
|
||||||
label(OPTION_RETRIEVE_VLAN)dit(bf(tt(retrieve-vlan)))
|
label(OPTION_RETRIEVE_VLAN)dit(bf(tt(retrieve-vlan)))
|
||||||
On packets incoming on raw sockets, retrieve the VLAN information and insert
|
On packets incoming on raw sockets, retrieve the VLAN information and insert
|
||||||
it into the packets for further processing (Linux)
|
it into the packets for further processing (Linux)
|
||||||
|
|
75
test.sh
75
test.sh
|
@ -17287,6 +17287,80 @@ esac
|
||||||
N=$((N+1))
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
|
# Test the res-nsaddr (resolver, dns) option
|
||||||
|
NAME=RES_NSADDR
|
||||||
|
case "$TESTS" in
|
||||||
|
*%$N%*|*%functions%*|*%resolv%*|*%ip4%*|*%tcp4%*|*%socket%*|*%$NAME%*)
|
||||||
|
TEST="$NAME: test the res-nsaddr option"
|
||||||
|
# Start a supplementary Socat instance that will receive the DNS query.
|
||||||
|
# Run main Socat process, opening an IPv4 socket with option res-nsaddr
|
||||||
|
# directed to the aux process.
|
||||||
|
# When the supplementary Socat instance received the query the test succeeded.
|
||||||
|
if ! eval $NUMCOND; then :;
|
||||||
|
elif ! F=$(testfeats STDIO IP4 UDP TCP); then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
elif ! A=$(testaddrs STDIO TCP4 UDP-RECVFROM); 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 res-nsaddr) >/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 ! runsip4 >/dev/null; then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available on host${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
else
|
||||||
|
tf="$td/test$N.stdout"
|
||||||
|
te="$td/test$N.stderr"
|
||||||
|
tdiff="$td/test$N.diff"
|
||||||
|
da="$(echo test$N $(date) $RANDOM |tr ' :' '-')"
|
||||||
|
echo "$da" >"$td/test$N.da"
|
||||||
|
newport udp4 # or whatever proto, or drop this line
|
||||||
|
CMD0="$TRACE $SOCAT $opts -u UDP-RECVFROM:$PORT -"
|
||||||
|
CMD1="$TRACE $SOCAT $opts - TCP4:$da:0,res-nsaddr=$LOCALHOST:$PORT"
|
||||||
|
printf "test $F_n $TEST... " $N
|
||||||
|
$CMD0 >/dev/null 2>"${te}0" >"${tf}0" &
|
||||||
|
pid0=$!
|
||||||
|
waitudp4port $PORT 1
|
||||||
|
$CMD1 >"${tf}1" 2>"${te}1"
|
||||||
|
rc1=$?
|
||||||
|
kill $pid0 2>/dev/null; wait
|
||||||
|
if grep "$da" "${tf}0" >/dev/null; then
|
||||||
|
$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))
|
||||||
|
elif pgrep -u root nscd >/dev/null 2>&1; then
|
||||||
|
$PRINTF "${YELLOW}FAILED (due to nscd?)${NORMAL}\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
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
namesCAnT="$namesCANT $NAME"
|
||||||
|
else
|
||||||
|
$PRINTF "$FAILED (query not received)\n"
|
||||||
|
echo "$CMD0 &"
|
||||||
|
cat "${te}0" >&2
|
||||||
|
echo "$CMD1"
|
||||||
|
cat "${te}1" >&2
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
namesFAIL="$namesFAIL $NAME"
|
||||||
|
fi
|
||||||
|
fi # NUMCOND
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
# end of common tests
|
# end of common tests
|
||||||
|
|
||||||
##################################################################################
|
##################################################################################
|
||||||
|
@ -17502,6 +17576,7 @@ elif [ ??? ]; then
|
||||||
if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
|
if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
|
||||||
numCANT=$((numCANT+1))
|
numCANT=$((numCANT+1))
|
||||||
listCANT="$listCANT $N"
|
listCANT="$listCANT $N"
|
||||||
|
namesCANT="$namesCANT $NAME"
|
||||||
else
|
else
|
||||||
$PRINTF "$OK\n"
|
$PRINTF "$OK\n"
|
||||||
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
||||||
|
|
60
xio-ip.c
60
xio-ip.c
|
@ -116,6 +116,9 @@ const struct optdesc opt_res_retrans = { "res-retrans", "retrans", OPT_RES_RE
|
||||||
#if HAVE_RES_RETRY
|
#if HAVE_RES_RETRY
|
||||||
const struct optdesc opt_res_retry = { "res-retry", NULL, OPT_RES_RETRY, GROUP_SOCK_IP, PH_OFFSET, TYPE_INT, OFUNC_OFFSET, XIO_OFFSETOF(para.socket.ip.res.retry), XIO_SIZEOF(para.socket.ip.res.retry), RES_MAXRETRY };
|
const struct optdesc opt_res_retry = { "res-retry", NULL, OPT_RES_RETRY, GROUP_SOCK_IP, PH_OFFSET, TYPE_INT, OFUNC_OFFSET, XIO_OFFSETOF(para.socket.ip.res.retry), XIO_SIZEOF(para.socket.ip.res.retry), RES_MAXRETRY };
|
||||||
#endif
|
#endif
|
||||||
|
#if HAVE_RES_NSADDR_LIST
|
||||||
|
const struct optdesc opt_res_nsaddr = { "res-nsaddr", "dns", OPT_RES_NSADDR, GROUP_SOCK_IP, PH_OFFSET, TYPE_IP4SOCK, OFUNC_OFFSET, XIO_OFFSETOF(para.socket.ip.res.nsaddr), XIO_SIZEOF(para.socket.ip.res.retry), RES_MAXRETRY };
|
||||||
|
#endif
|
||||||
#endif /* HAVE_RESOLV_H */
|
#endif /* HAVE_RESOLV_H */
|
||||||
#endif /* WITH_RESOLVE */
|
#endif /* WITH_RESOLVE */
|
||||||
#endif /* WITH_IP4 || WITH_IP6 */
|
#endif /* WITH_IP4 || WITH_IP6 */
|
||||||
|
@ -139,7 +142,9 @@ int xioinit_ip(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if HAVE_RESOLV_H
|
#if HAVE_RESOLV_H
|
||||||
|
|
||||||
int Res_init(void) {
|
int Res_init(void) {
|
||||||
int result;
|
int result;
|
||||||
Debug("res_init()");
|
Debug("res_init()");
|
||||||
|
@ -147,13 +152,9 @@ int Res_init(void) {
|
||||||
Debug1("res_init() -> %d", result);
|
Debug1("res_init() -> %d", result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_RESOLV_H */
|
#endif /* HAVE_RESOLV_H */
|
||||||
|
|
||||||
#if HAVE_RESOLV_H
|
|
||||||
unsigned long res_opts() {
|
|
||||||
return _res.options;
|
|
||||||
}
|
|
||||||
#endif /* HAVE_RESOLV_H */
|
|
||||||
|
|
||||||
/* the ultimate(?) socat resolver function
|
/* the ultimate(?) socat resolver function
|
||||||
node: the address to be resolved; supported forms:
|
node: the address to be resolved; supported forms:
|
||||||
|
@ -1015,7 +1016,18 @@ int xio_res_init(
|
||||||
struct __res_state *save_res)
|
struct __res_state *save_res)
|
||||||
{
|
{
|
||||||
if (sfd->para.socket.ip.res.opts[0] ||
|
if (sfd->para.socket.ip.res.opts[0] ||
|
||||||
sfd->para.socket.ip.res.opts[1]) {
|
sfd->para.socket.ip.res.opts[1] ||
|
||||||
|
#if HAVE_RES_RETRANS
|
||||||
|
sfd->para.socket.ip.res.retrans >= 0 ||
|
||||||
|
#endif
|
||||||
|
#if HAVE_RES_RETRY
|
||||||
|
sfd->para.socket.ip.res.retry >= 0 ||
|
||||||
|
#endif
|
||||||
|
#if HAVE_RES_NSADDR_LIST
|
||||||
|
sfd->para.socket.ip.res.nsaddr.sin_family != PF_UNSPEC ||
|
||||||
|
#endif
|
||||||
|
0 /* for canonical reasons */
|
||||||
|
) {
|
||||||
if (!(_res.options & RES_INIT)) {
|
if (!(_res.options & RES_INIT)) {
|
||||||
if (Res_init() < 0) {
|
if (Res_init() < 0) {
|
||||||
Error("res_init() failed");
|
Error("res_init() failed");
|
||||||
|
@ -1027,8 +1039,44 @@ int xio_res_init(
|
||||||
_res.options &= ~sfd->para.socket.ip.res.opts[1];
|
_res.options &= ~sfd->para.socket.ip.res.opts[1];
|
||||||
Debug2("changed _res.options from 0x%lx to 0x%lx",
|
Debug2("changed _res.options from 0x%lx to 0x%lx",
|
||||||
save_res->options, _res.options);
|
save_res->options, _res.options);
|
||||||
|
|
||||||
|
#if HAVE_RES_RETRANS
|
||||||
|
if (sfd->para.socket.ip.res.retrans >= 0) {
|
||||||
|
_res.retrans = sfd->para.socket.ip.res.retrans;
|
||||||
|
Debug2("changed _res.retrans from 0x%x to 0x%x",
|
||||||
|
save_res->retrans, _res.retrans);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if HAVE_RES_RETRY
|
||||||
|
if (sfd->para.socket.ip.res.retry >= 0) {
|
||||||
|
_res.retry = sfd->para.socket.ip.res.retry;
|
||||||
|
Debug2("changed _res.retry from 0x%x to 0x%x",
|
||||||
|
save_res->retry, _res.retry);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if HAVE_RES_NSADDR_LIST
|
||||||
|
if (sfd->para.socket.ip.res.nsaddr.sin_family == PF_INET) {
|
||||||
|
_res.nscount = 1;
|
||||||
|
_res.nsaddr_list[0] = sfd->para.socket.ip.res.nsaddr;
|
||||||
|
if (_res.nsaddr_list[0].sin_port == htons(0))
|
||||||
|
_res.nsaddr_list[0].sin_port = htons(53);
|
||||||
|
Debug10("changed _res.nsaddr_list[0] from %u.%u.%u.%u:%u to %u.%u.%u.%u:%u",
|
||||||
|
((unsigned char *)&save_res->nsaddr_list[0].sin_addr.s_addr)[0],
|
||||||
|
((unsigned char *)&save_res->nsaddr_list[0].sin_addr.s_addr)[1],
|
||||||
|
((unsigned char *)&save_res->nsaddr_list[0].sin_addr.s_addr)[2],
|
||||||
|
((unsigned char *)&save_res->nsaddr_list[0].sin_addr.s_addr)[3],
|
||||||
|
ntohs(save_res->nsaddr_list[0].sin_port),
|
||||||
|
((unsigned char *)&_res.nsaddr_list[0].sin_addr.s_addr)[0],
|
||||||
|
((unsigned char *)&_res.nsaddr_list[0].sin_addr.s_addr)[1],
|
||||||
|
((unsigned char *)&_res.nsaddr_list[0].sin_addr.s_addr)[2],
|
||||||
|
((unsigned char *)&_res.nsaddr_list[0].sin_addr.s_addr)[3],
|
||||||
|
ntohs(_res.nsaddr_list[0].sin_port));
|
||||||
|
}
|
||||||
|
#endif /* HAVE_RES_NSADDR_LIST */
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
xio-ip.h
1
xio-ip.h
|
@ -44,6 +44,7 @@ extern const struct optdesc opt_res_stayopen;
|
||||||
extern const struct optdesc opt_res_dnsrch;
|
extern const struct optdesc opt_res_dnsrch;
|
||||||
extern const struct optdesc opt_res_retrans;
|
extern const struct optdesc opt_res_retrans;
|
||||||
extern const struct optdesc opt_res_retry;
|
extern const struct optdesc opt_res_retry;
|
||||||
|
extern const struct optdesc opt_res_nsaddr;
|
||||||
|
|
||||||
extern int xioinit_ip(int *pf, char ipv);
|
extern int xioinit_ip(int *pf, char ipv);
|
||||||
|
|
||||||
|
|
5
xio.h
5
xio.h
|
@ -143,6 +143,10 @@ struct para_ip_res {
|
||||||
#if HAVE_RES_RETRY
|
#if HAVE_RES_RETRY
|
||||||
int retry;
|
int retry;
|
||||||
#endif
|
#endif
|
||||||
|
#if HAVE_RES_NSADDR_LIST
|
||||||
|
# undef nsaddr /* resolv.h might define this, breaks debugger */
|
||||||
|
struct sockaddr_in nsaddr;
|
||||||
|
#endif
|
||||||
} ;
|
} ;
|
||||||
#endif /* WITH_RESOLVE && HAVE_RESOLV_H */
|
#endif /* WITH_RESOLVE && HAVE_RESOLV_H */
|
||||||
|
|
||||||
|
@ -423,6 +427,7 @@ union integral {
|
||||||
#endif /* HAVE_STRUCT_TIMESPEC */
|
#endif /* HAVE_STRUCT_TIMESPEC */
|
||||||
#if WITH_IP4
|
#if WITH_IP4
|
||||||
struct in_addr u_ip4addr;
|
struct in_addr u_ip4addr;
|
||||||
|
struct sockaddr_in u_ip4sock;
|
||||||
#endif
|
#endif
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ static const char *optiontypenames[] = {
|
||||||
"OFF64_T", "INT:INT", "INT:INTP", "INT:BIN",
|
"OFF64_T", "INT:INT", "INT:INTP", "INT:BIN",
|
||||||
"INT:STRING", "INT:INT:INT", "INT:INT:BIN", "INT:INT:STRING",
|
"INT:STRING", "INT:INT:INT", "INT:INT:BIN", "INT:INT:STRING",
|
||||||
"INT:INT:GENERIC",
|
"INT:INT:GENERIC",
|
||||||
"IP4NAME",
|
"IP4NAME", "IP4SOCK",
|
||||||
#if HAVE_STRUCT_LINGER
|
#if HAVE_STRUCT_LINGER
|
||||||
"STRUCT-LINGER",
|
"STRUCT-LINGER",
|
||||||
#endif
|
#endif
|
||||||
|
|
56
xioopts.c
56
xioopts.c
|
@ -430,6 +430,9 @@ const struct optname optionnames[] = {
|
||||||
#ifdef VDISCARD
|
#ifdef VDISCARD
|
||||||
IF_TERMIOS("discard", &opt_vdiscard)
|
IF_TERMIOS("discard", &opt_vdiscard)
|
||||||
#endif
|
#endif
|
||||||
|
#if HAVE_RES_NSADDR_LIST
|
||||||
|
IF_IP ("dns", &opt_res_nsaddr)
|
||||||
|
#endif
|
||||||
#if HAVE_RESOLV_H
|
#if HAVE_RESOLV_H
|
||||||
IF_RESOLVE("dnsrch", &opt_res_dnsrch)
|
IF_RESOLVE("dnsrch", &opt_res_dnsrch)
|
||||||
#endif /* HAVE_RESOLV_H */
|
#endif /* HAVE_RESOLV_H */
|
||||||
|
@ -1020,6 +1023,9 @@ const struct optname optionnames[] = {
|
||||||
IF_IP ("multicast-ttl", &opt_ip_multicast_ttl)
|
IF_IP ("multicast-ttl", &opt_ip_multicast_ttl)
|
||||||
IF_IP ("multicastloop", &opt_ip_multicast_loop)
|
IF_IP ("multicastloop", &opt_ip_multicast_loop)
|
||||||
IF_IP ("multicastttl", &opt_ip_multicast_ttl)
|
IF_IP ("multicastttl", &opt_ip_multicast_ttl)
|
||||||
|
#if HAVE_RES_NSADDR_LIST
|
||||||
|
IF_IP ("nameserver", &opt_res_nsaddr)
|
||||||
|
#endif
|
||||||
#if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK)
|
#if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK)
|
||||||
IF_ANY ("ndelay", &opt_o_ndelay)
|
IF_ANY ("ndelay", &opt_o_ndelay)
|
||||||
#else
|
#else
|
||||||
|
@ -1085,6 +1091,9 @@ const struct optname optionnames[] = {
|
||||||
IF_OPENSSL("nosni", &opt_openssl_no_sni)
|
IF_OPENSSL("nosni", &opt_openssl_no_sni)
|
||||||
#endif
|
#endif
|
||||||
IF_INTERFACE("notrailers", &opt_iff_notrailers)
|
IF_INTERFACE("notrailers", &opt_iff_notrailers)
|
||||||
|
#if HAVE_RES_NSADDR_LIST
|
||||||
|
IF_IP ("nsaddr", &opt_res_nsaddr)
|
||||||
|
#endif
|
||||||
#ifdef O_NSHARE
|
#ifdef O_NSHARE
|
||||||
IF_OPEN ("nshare", &opt_o_nshare)
|
IF_OPEN ("nshare", &opt_o_nshare)
|
||||||
#endif
|
#endif
|
||||||
|
@ -1426,6 +1435,9 @@ const struct optname optionnames[] = {
|
||||||
# if HAVE_RES_RETRY
|
# if HAVE_RES_RETRY
|
||||||
IF_RESOLVE("res-maxretry", &opt_res_retry)
|
IF_RESOLVE("res-maxretry", &opt_res_retry)
|
||||||
# endif
|
# endif
|
||||||
|
# if HAVE_RES_NSADDR_LIST
|
||||||
|
IF_IP ("res-nsaddr", &opt_res_nsaddr)
|
||||||
|
# endif
|
||||||
# if WITH_RES_PRIMARY
|
# if WITH_RES_PRIMARY
|
||||||
IF_RESOLVE("res-primary", &opt_res_primary)
|
IF_RESOLVE("res-primary", &opt_res_primary)
|
||||||
# endif
|
# endif
|
||||||
|
@ -2630,6 +2642,7 @@ int parseopts_table(const char **a, groups_t groups, struct opt **opts,
|
||||||
#if WITH_IP4
|
#if WITH_IP4
|
||||||
case TYPE_IP4NAME:
|
case TYPE_IP4NAME:
|
||||||
{
|
{
|
||||||
|
/*! On a good day merge this with code in retropt_bind() */
|
||||||
struct sockaddr_in sa; socklen_t salen = sizeof(sa);
|
struct sockaddr_in sa; socklen_t salen = sizeof(sa);
|
||||||
const char *ends[] = { NULL };
|
const char *ends[] = { NULL };
|
||||||
const char *nests[] = { "[","]", NULL };
|
const char *nests[] = { "[","]", NULL };
|
||||||
|
@ -2659,6 +2672,40 @@ int parseopts_table(const char **a, groups_t groups, struct opt **opts,
|
||||||
opt->value.u_ip4addr = sa.sin_addr;
|
opt->value.u_ip4addr = sa.sin_addr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TYPE_IP4SOCK:
|
||||||
|
{
|
||||||
|
/*! On a good day merge this with code for TYPE_IP4NAME */
|
||||||
|
struct sockaddr_in sa; socklen_t salen = sizeof(sa);
|
||||||
|
const char portsep[] = ":";
|
||||||
|
const char *ends[] = { portsep, NULL };
|
||||||
|
const char *nests[] = { "[","]", NULL };
|
||||||
|
char hostname[512], *hostp = hostname, *portp = NULL;
|
||||||
|
size_t hostlen = sizeof(hostname)-1;
|
||||||
|
|
||||||
|
tokp = token;
|
||||||
|
parsres =
|
||||||
|
nestlex((const char **)&tokp, &hostp, &hostlen,
|
||||||
|
ends, NULL, NULL, nests,
|
||||||
|
true, false, false);
|
||||||
|
if (parsres < 0) {
|
||||||
|
Error1("option too long: \"%s\"", *a);
|
||||||
|
return -1;
|
||||||
|
} else if (parsres > 0) {
|
||||||
|
Error1("syntax error in \"%s\"", *a);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*hostp++ = '\0';
|
||||||
|
if (!strncmp(tokp, portsep, strlen(portsep))) {
|
||||||
|
portp = tokp + strlen(portsep);
|
||||||
|
}
|
||||||
|
if (xioresolve(hostname, portp, AF_INET, SOCK_DGRAM, IPPROTO_IP,
|
||||||
|
(union sockaddr_union *)&sa, &salen, 0)
|
||||||
|
!= STAT_OK) {
|
||||||
|
opt->desc = ODESC_ERROR; continue;
|
||||||
|
}
|
||||||
|
opt->value.u_ip4sock = sa;
|
||||||
|
}
|
||||||
|
break;
|
||||||
#endif /* defined(WITH_IP4) */
|
#endif /* defined(WITH_IP4) */
|
||||||
|
|
||||||
#if LATER
|
#if LATER
|
||||||
|
@ -4132,6 +4179,15 @@ static int applyopt_offset(struct single *sfd, struct opt *opt) {
|
||||||
case TYPE_CONST:
|
case TYPE_CONST:
|
||||||
*(int *)ptr = opt->desc->minor;
|
*(int *)ptr = opt->desc->minor;
|
||||||
break;
|
break;
|
||||||
|
case TYPE_IP4NAME:
|
||||||
|
memset(ptr, 0, sizeof(struct sockaddr_in));
|
||||||
|
((struct sockaddr_in *)ptr)->sin_addr = opt->value.u_ip4addr;
|
||||||
|
((struct sockaddr_in *)ptr)->sin_family = PF_INET;
|
||||||
|
break;
|
||||||
|
case TYPE_IP4SOCK:
|
||||||
|
memset(ptr, 0, sizeof(struct sockaddr_in));
|
||||||
|
*(struct sockaddr_in *)ptr = opt->value.u_ip4sock;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Error2("applyopt_offset(opt:%s): type %s not implemented",
|
Error2("applyopt_offset(opt:%s): type %s not implemented",
|
||||||
opt->desc->defname, xiohelp_opttypename(opt->desc->type));
|
opt->desc->defname, xiohelp_opttypename(opt->desc->type));
|
||||||
|
|
|
@ -68,6 +68,7 @@ enum e_types {
|
||||||
TYPE_INT_INT_GENERIC, /* 3 params: first and second are int, 3rd is specified by value (dalan syntax) */
|
TYPE_INT_INT_GENERIC, /* 3 params: first and second are int, 3rd is specified by value (dalan syntax) */
|
||||||
|
|
||||||
TYPE_IP4NAME, /* IPv4 hostname or address */
|
TYPE_IP4NAME, /* IPv4 hostname or address */
|
||||||
|
TYPE_IP4SOCK, /* IPv4 hostname or address optionally with port */
|
||||||
#if HAVE_STRUCT_LINGER
|
#if HAVE_STRUCT_LINGER
|
||||||
TYPE_LINGER, /* struct linger */
|
TYPE_LINGER, /* struct linger */
|
||||||
#endif /* HAVE_STRUCT_LINGER */
|
#endif /* HAVE_STRUCT_LINGER */
|
||||||
|
@ -628,6 +629,7 @@ enum e_optcode {
|
||||||
OPT_RES_DEFNAMES, /* resolver(3) */
|
OPT_RES_DEFNAMES, /* resolver(3) */
|
||||||
OPT_RES_DNSRCH, /* resolver(3) */
|
OPT_RES_DNSRCH, /* resolver(3) */
|
||||||
OPT_RES_IGNTC, /* resolver(3) */
|
OPT_RES_IGNTC, /* resolver(3) */
|
||||||
|
OPT_RES_NSADDR, /* undocumented */
|
||||||
OPT_RES_PRIMARY, /* resolver(3) */
|
OPT_RES_PRIMARY, /* resolver(3) */
|
||||||
OPT_RES_RECURSE, /* resolver(3) */
|
OPT_RES_RECURSE, /* resolver(3) */
|
||||||
OPT_RES_RETRANS, /* undocumented */
|
OPT_RES_RETRANS, /* undocumented */
|
||||||
|
|
Loading…
Reference in a new issue