mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 23:42:34 +00:00
Fixed bind with abstract unix domain sockets (Linux)
This commit is contained in:
parent
f01ed154b6
commit
ad9e6b1fa4
5 changed files with 145 additions and 63 deletions
4
CHANGES
4
CHANGES
|
@ -162,6 +162,10 @@ corrections:
|
||||||
docu mentions option so-bindtodev but correct name is so-bindtodevice.
|
docu mentions option so-bindtodev but correct name is so-bindtodevice.
|
||||||
Thanks to Jim Zimmerman for reporting.
|
Thanks to Jim Zimmerman for reporting.
|
||||||
|
|
||||||
|
Bind with ABSTRACT commands used non-abstract namespace (Linux).
|
||||||
|
Test: ABSTRACT_BIND
|
||||||
|
Thanks to Denis Shatov for reporting this bug.
|
||||||
|
|
||||||
porting:
|
porting:
|
||||||
Red Hat issue 1020203: configure checks fail with some compilers.
|
Red Hat issue 1020203: configure checks fail with some compilers.
|
||||||
Use case: clang
|
Use case: clang
|
||||||
|
|
70
test.sh
70
test.sh
|
@ -9005,28 +9005,78 @@ rc2="$?"
|
||||||
i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done
|
i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done
|
||||||
kill "$pid1" 2>/dev/null; wait
|
kill "$pid1" 2>/dev/null; wait
|
||||||
if [ "$rc2" -ne 0 ]; then
|
if [ "$rc2" -ne 0 ]; then
|
||||||
$PRINTF "$FAILED: $TRACE $SOCAT:\n"
|
$PRINTF "$FAILED: $TRACE $SOCAT:\n"
|
||||||
echo "$CMD1 &"
|
echo "$CMD1 &"
|
||||||
echo "$CMD2"
|
echo "$CMD2"
|
||||||
cat "${te}1"
|
cat "${te}1"
|
||||||
cat "${te}2"
|
cat "${te}2"
|
||||||
numFAIL=$((numFAIL+1))
|
numFAIL=$((numFAIL+1))
|
||||||
listFAIL="$listFAIL $N"
|
listFAIL="$listFAIL $N"
|
||||||
elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
|
elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
|
||||||
$PRINTF "$FAILED\n"
|
$PRINTF "$FAILED\n"
|
||||||
cat "$tdiff"
|
echo "$CMD1 &"
|
||||||
|
cat "${te}1"
|
||||||
|
cat "$tdiff"
|
||||||
numFAIL=$((numFAIL+1))
|
numFAIL=$((numFAIL+1))
|
||||||
listFAIL="$listFAIL $N"
|
listFAIL="$listFAIL $N"
|
||||||
else
|
else
|
||||||
$PRINTF "$OK\n"
|
$PRINTF "$OK\n"
|
||||||
if [ -n "$debug" ]; then cat $te; fi
|
if [ -n "$debug" ]; then cat $te; fi
|
||||||
numOK=$((numOK+1))
|
numOK=$((numOK+1))
|
||||||
fi
|
fi
|
||||||
fi ;; # NUMCOND, feats
|
fi ;; # NUMCOND, feats
|
||||||
esac
|
esac
|
||||||
N=$((N+1))
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
|
# bind with Linux abstract UNIX domain addresses bound to filesystem socket
|
||||||
|
# instead of abstract namespace
|
||||||
|
NAME=ABSTRACT_BIND
|
||||||
|
case "$TESTS" in
|
||||||
|
*%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%abstract%*|*%$NAME%*)
|
||||||
|
TEST="$NAME: abstract bind"
|
||||||
|
# open an abstract client address with bind option, bind to the target socket.
|
||||||
|
# send a datagram.
|
||||||
|
# when socat outputs the datagram it got the test succeeded
|
||||||
|
if ! eval $NUMCOND; then :;
|
||||||
|
elif [ "$UNAME" != Linux ]; then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
else
|
||||||
|
tf="$td/test$N.stdout"
|
||||||
|
te="$td/test$N.stderr"
|
||||||
|
tdiff="$td/test$N.diff"
|
||||||
|
ts1="$td/test$N.sock1"
|
||||||
|
da="test$N $(date) $RANDOM"
|
||||||
|
CMD1="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts1"
|
||||||
|
printf "test $F_n $TEST... " $N
|
||||||
|
echo "$da" |$CMD1 >$tf 2>"${te}1"
|
||||||
|
rc1=$?
|
||||||
|
if [ $rc1 -ne 0 ]; then
|
||||||
|
$PRINTF "$FAILED\n"
|
||||||
|
echo "$CMD1" >&2
|
||||||
|
echo "rc=$rc1" >&2
|
||||||
|
cat "${te}1" >&2
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
elif echo "$da" |diff -q - $tf; then
|
||||||
|
$PRINTF "$OK\n"
|
||||||
|
numOK=$((numOK+1))
|
||||||
|
else
|
||||||
|
$PRINTF "$FAILED\n"
|
||||||
|
echo "$CMD1" >&2
|
||||||
|
cat "${te}1" >&2
|
||||||
|
echo "$da" |diff - "$tf" >&2
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
fi
|
||||||
|
fi # NUMCOND
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
PORT=$((PORT+1))
|
||||||
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
NAME=OPENSSLREAD
|
NAME=OPENSSLREAD
|
||||||
# socat determined availability of data using select(). With openssl, the
|
# socat determined availability of data using select(). With openssl, the
|
||||||
# following situation might occur:
|
# following situation might occur:
|
||||||
|
|
119
xio-unix.c
119
xio-unix.c
|
@ -73,13 +73,13 @@ static const struct xioaddr_endpoint_desc xioendpoint_abstract_client1 = { XIOA
|
||||||
const union xioaddr_desc *xioaddrs_abstract_client[] = { (union xioaddr_desc *)&xioendpoint_abstract_client1, NULL };
|
const union xioaddr_desc *xioaddrs_abstract_client[] = { (union xioaddr_desc *)&xioendpoint_abstract_client1, NULL };
|
||||||
#endif /* WITH_ABSTRACT_UNIXSOCKET */
|
#endif /* WITH_ABSTRACT_UNIXSOCKET */
|
||||||
|
|
||||||
const struct optdesc xioopt_unix_tightsocklen = { "unix-tightsocklen", "tightsocklen", OPT_UNIX_TIGHTSOCKLEN, GROUP_SOCK_UNIX, PH_INIT, TYPE_BOOL, OFUNC_SPEC, 0, 0 };
|
const struct optdesc xioopt_unix_tightsocklen = { "unix-tightsocklen", "tightsocklen", OPT_UNIX_TIGHTSOCKLEN, GROUP_SOCK_UNIX, PH_PREBIND, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.socket.un.tight), XIO_SIZEOF(para.socket.un.tight) };
|
||||||
|
|
||||||
|
|
||||||
/* fills the socket address struct and returns its effective length.
|
/* fills the socket address struct and returns its effective length.
|
||||||
abstract is usually 0; != 0 generates an abstract socket address on Linux.
|
abstract is usually 0; != 0 generates an abstract socket address on Linux.
|
||||||
tight!=0 calculates the resulting length from the path length, not from the
|
tight!=0 calculates the resulting length from the path length, not from the
|
||||||
structures length; this is more common.
|
structures length; this is more common (see option unix-tightsocklen)
|
||||||
the struct need not be initialized when calling this function.
|
the struct need not be initialized when calling this function.
|
||||||
*/
|
*/
|
||||||
socklen_t
|
socklen_t
|
||||||
|
@ -140,7 +140,6 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
||||||
int protocol = 0;
|
int protocol = 0;
|
||||||
struct sockaddr_un us;
|
struct sockaddr_un us;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
bool tight = true;
|
|
||||||
struct opt *opts0 = NULL;
|
struct opt *opts0 = NULL;
|
||||||
pid_t pid = Getpid();
|
pid_t pid = Getpid();
|
||||||
bool opt_unlink_early = false;
|
bool opt_unlink_early = false;
|
||||||
|
@ -152,11 +151,10 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
||||||
argv[0], argc-1);
|
argv[0], argc-1);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
|
|
||||||
|
xfd->para.socket.un.tight = true;
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
uslen = xiosetunix(pf, &us, name, abstract, tight);
|
|
||||||
|
|
||||||
if (!(ABSTRACT && abstract)) {
|
if (!(ABSTRACT && abstract)) {
|
||||||
/* only for non abstract because abstract do not work in file system */
|
/* only for non abstract because abstract do not work in file system */
|
||||||
|
@ -167,7 +165,10 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(-1, opts, PH_INIT);
|
||||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||||
|
applyopts_offset(xfd, opts);
|
||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(-1, opts, PH_EARLY);
|
||||||
|
|
||||||
|
uslen = xiosetunix(pf, &us, name, abstract, xfd->para.socket.un.tight);
|
||||||
|
|
||||||
if (!(ABSTRACT && abstract)) {
|
if (!(ABSTRACT && abstract)) {
|
||||||
if (opt_unlink_early) {
|
if (opt_unlink_early) {
|
||||||
|
@ -229,8 +230,7 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
int socktype = SOCK_STREAM;
|
int socktype = SOCK_STREAM;
|
||||||
int protocol = 0;
|
int protocol = 0;
|
||||||
struct sockaddr_un them, us;
|
struct sockaddr_un them, us;
|
||||||
socklen_t themlen, uslen;
|
socklen_t themlen, uslen = sizeof(us);
|
||||||
bool tight = true;
|
|
||||||
bool needbind = false;
|
bool needbind = false;
|
||||||
bool opt_unlink_close = false;
|
bool opt_unlink_close = false;
|
||||||
int result;
|
int result;
|
||||||
|
@ -241,18 +241,23 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->howtoshut = XIOSHUT_DOWN;
|
|
||||||
|
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
|
|
||||||
|
xfd->para.socket.un.tight = true;
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
xfd->howtoshut = XIOSHUT_DOWN;
|
||||||
themlen = xiosetunix(pf, &them, name, abstract, tight);
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
|
applyopts(-1, opts, PH_INIT);
|
||||||
|
applyopts_offset(xfd, opts);
|
||||||
|
applyopts(-1, opts, PH_EARLY);
|
||||||
|
|
||||||
|
themlen = xiosetunix(pf, &them, name, abstract, xfd->para.socket.un.tight);
|
||||||
if (!(ABSTRACT && abstract)) {
|
if (!(ABSTRACT && abstract)) {
|
||||||
/* only for non abstract because abstract do not work in file system */
|
/* only for non abstract because abstract do not work in file system */
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
}
|
}
|
||||||
if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen, 0, 0, 0)
|
if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen,
|
||||||
!= STAT_NOACTION) {
|
(abstract<<1)|xfd->para.socket.un.tight, 0, 0) == STAT_OK) {
|
||||||
needbind = true;
|
needbind = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,10 +268,6 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
xfd->opt_unlink_close = true;
|
xfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
|
||||||
applyopts(-1, opts, PH_EARLY);
|
|
||||||
|
|
||||||
if ((result =
|
if ((result =
|
||||||
xioopen_connect(xfd,
|
xioopen_connect(xfd,
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
needbind?(struct sockaddr *)&us:NULL, uslen,
|
||||||
|
@ -295,8 +296,7 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i
|
||||||
int socktype = SOCK_DGRAM;
|
int socktype = SOCK_DGRAM;
|
||||||
int protocol = 0;
|
int protocol = 0;
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
socklen_t uslen;
|
socklen_t uslen = sizeof(us);
|
||||||
bool tight = true;
|
|
||||||
bool needbind = false;
|
bool needbind = false;
|
||||||
bool opt_unlink_close = false;
|
bool opt_unlink_close = false;
|
||||||
int result;
|
int result;
|
||||||
|
@ -312,10 +312,13 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
|
|
||||||
|
xfd->para.socket.un.tight = true;
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
xfd->salen = xiosetunix(pf, &xfd->peersa.un, name, abstract, tight);
|
applyopts_offset(xfd, opts);
|
||||||
|
|
||||||
|
xfd->salen = xiosetunix(pf, &xfd->peersa.un, name, abstract, xfd->para.socket.un.tight);
|
||||||
|
|
||||||
if (!(ABSTRACT && abstract)) {
|
if (!(ABSTRACT && abstract)) {
|
||||||
/* only for non abstract because abstract do not work in file system */
|
/* only for non abstract because abstract do not work in file system */
|
||||||
|
@ -324,8 +327,8 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i
|
||||||
|
|
||||||
xfd->dtype = XIODATA_RECVFROM;
|
xfd->dtype = XIODATA_RECVFROM;
|
||||||
|
|
||||||
if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, 0, 0, 0)
|
if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen,
|
||||||
!= STAT_NOACTION) {
|
(abstract<<1)| xfd->para.socket.un.tight, 0, 0) == STAT_OK) {
|
||||||
needbind = true;
|
needbind = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,7 +366,6 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
||||||
int protocol = 0;
|
int protocol = 0;
|
||||||
struct sockaddr_un us;
|
struct sockaddr_un us;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
bool tight = true;
|
|
||||||
bool needbind = true;
|
bool needbind = true;
|
||||||
bool opt_unlink_early = false;
|
bool opt_unlink_early = false;
|
||||||
bool opt_unlink_close = true;
|
bool opt_unlink_close = true;
|
||||||
|
@ -373,16 +375,16 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
||||||
argv[0], argc-1);
|
argv[0], argc-1);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
retropt_socket_pf(opts, &pf);
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
uslen = xiosetunix(pf, &us, name, abstract, tight);
|
|
||||||
|
|
||||||
|
xfd->para.socket.un.tight = true;
|
||||||
|
retropt_socket_pf(opts, &pf);
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
|
|
||||||
retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen,
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
1, 0, 0);
|
applyopts(-1, opts, PH_INIT);
|
||||||
|
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||||
|
applyopts_offset(xfd, opts);
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
|
|
||||||
|
@ -391,6 +393,15 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
}
|
}
|
||||||
|
applyopts(-1, opts, PH_EARLY);
|
||||||
|
|
||||||
|
uslen = xiosetunix(pf, &us, name, abstract, xfd->para.socket.un.tight);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen,
|
||||||
|
(abstract<<1)|xfd->para.socket.un.tight, 0, 0) == STAT_OK) {
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!(ABSTRACT && abstract)) {
|
if (!(ABSTRACT && abstract)) {
|
||||||
if (opt_unlink_early) {
|
if (opt_unlink_early) {
|
||||||
|
@ -444,7 +455,6 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
int protocol = 0;
|
int protocol = 0;
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
bool tight = true;
|
|
||||||
bool opt_unlink_early = false;
|
bool opt_unlink_early = false;
|
||||||
bool opt_unlink_close = true;
|
bool opt_unlink_close = true;
|
||||||
int result;
|
int result;
|
||||||
|
@ -454,21 +464,33 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
argv[0], argc-1);
|
argv[0], argc-1);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
retropt_socket_pf(opts, &pf);
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
uslen = xiosetunix(pf, &us.un, name, abstract, tight);
|
|
||||||
|
|
||||||
#if 1 /*!!! why bind option? */
|
xfd->para.socket.un.tight = true;
|
||||||
retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, 1, 0, 0);
|
retropt_socket_pf(opts, &pf);
|
||||||
#endif
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
|
applyopts(-1, opts, PH_INIT);
|
||||||
|
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||||
|
applyopts_offset(xfd, opts);
|
||||||
|
|
||||||
if (!(ABSTRACT && abstract)) {
|
if (!(ABSTRACT && abstract)) {
|
||||||
/* only for non abstract because abstract do not work in file system */
|
/* only for non abstract because abstract do not work in file system */
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
|
|
||||||
|
}
|
||||||
|
applyopts(-1, opts, PH_EARLY);
|
||||||
|
|
||||||
|
uslen = xiosetunix(pf, &us.un, name, abstract, xfd->para.socket.un.tight);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen,
|
||||||
|
(abstract<<1)|xfd->para.socket.un.tight, 0, 0)
|
||||||
|
== STAT_OK) {
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!(ABSTRACT && abstract)) {
|
||||||
if (opt_unlink_early) {
|
if (opt_unlink_early) {
|
||||||
if (Unlink(name) < 0) {
|
if (Unlink(name) < 0) {
|
||||||
if (errno == ENOENT) {
|
if (errno == ENOENT) {
|
||||||
|
@ -531,27 +553,26 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups,
|
||||||
int socktype = 0; /* to be determined by server socket type */
|
int socktype = 0; /* to be determined by server socket type */
|
||||||
int protocol = 0;
|
int protocol = 0;
|
||||||
union sockaddr_union them, us;
|
union sockaddr_union them, us;
|
||||||
socklen_t themlen, uslen;
|
socklen_t themlen, uslen = sizeof(us);
|
||||||
bool tight = true;
|
|
||||||
bool needbind = false;
|
bool needbind = false;
|
||||||
bool opt_unlink_close = false;
|
bool opt_unlink_close = false;
|
||||||
struct opt *opts0;
|
struct opt *opts0;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
xfd->para.socket.un.tight = true;
|
||||||
applyopts(-1, opts, PH_INIT);
|
|
||||||
|
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
|
applyopts(-1, opts, PH_INIT);
|
||||||
|
applyopts_offset(xfd, opts);
|
||||||
|
applyopts(-1, opts, PH_EARLY);
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
themlen = xiosetunix(pf, &them.un, name, abstract, xfd->para.socket.un.tight);
|
||||||
themlen = xiosetunix(pf, &them.un, name, abstract, tight);
|
|
||||||
|
|
||||||
if (!(ABSTRACT && abstract)) {
|
if (!(ABSTRACT && abstract)) {
|
||||||
/* only for non abstract because abstract do not work in file system */
|
/* only for non abstract because abstract do not work in file system */
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
}
|
}
|
||||||
|
if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen,
|
||||||
if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, 0, 0, 0)
|
(abstract<<1)|xfd->para.socket.un.tight, 0, 0)
|
||||||
!= STAT_NOACTION) {
|
!= STAT_NOACTION) {
|
||||||
needbind = true;
|
needbind = true;
|
||||||
}
|
}
|
||||||
|
|
3
xio.h
3
xio.h
|
@ -394,6 +394,9 @@ typedef struct single {
|
||||||
char *hosts_deny_table;
|
char *hosts_deny_table;
|
||||||
#endif
|
#endif
|
||||||
} ip;
|
} ip;
|
||||||
|
struct {
|
||||||
|
bool tight;
|
||||||
|
} un;
|
||||||
#endif /* _WITH_IP4 || _WITH_IP6 */
|
#endif /* _WITH_IP4 || _WITH_IP6 */
|
||||||
} socket;
|
} socket;
|
||||||
#endif /* _WITH_SOCKET */
|
#endif /* _WITH_SOCKET */
|
||||||
|
|
12
xioopts.c
12
xioopts.c
|
@ -2808,7 +2808,7 @@ int retropt_string(struct opt *opts, int optcode, char **result) {
|
||||||
|
|
||||||
|
|
||||||
#if _WITH_SOCKET
|
#if _WITH_SOCKET
|
||||||
/* looks for an bind option and, if found, overwrites the complete contents of
|
/* looks for a bind option and, if found, overwrites the complete contents of
|
||||||
sa with the appropriate value(s).
|
sa with the appropriate value(s).
|
||||||
returns STAT_OK if option exists and could be resolved,
|
returns STAT_OK if option exists and could be resolved,
|
||||||
STAT_NORETRY if option exists but had error,
|
STAT_NORETRY if option exists but had error,
|
||||||
|
@ -2821,7 +2821,10 @@ int retropt_bind(struct opt *opts,
|
||||||
struct sockaddr *sa,
|
struct sockaddr *sa,
|
||||||
socklen_t *salen,
|
socklen_t *salen,
|
||||||
int feats, /* TCP etc: 1..address allowed,
|
int feats, /* TCP etc: 1..address allowed,
|
||||||
3..address and port allowed */
|
3..address and port allowed
|
||||||
|
UNIX (or'd): 1..tight
|
||||||
|
2..abstract
|
||||||
|
*/
|
||||||
unsigned long res_opts0, unsigned long res_opts1) {
|
unsigned long res_opts0, unsigned long res_opts1) {
|
||||||
const char portsep[] = ":";
|
const char portsep[] = ":";
|
||||||
const char *ends[] = { portsep, NULL };
|
const char *ends[] = { portsep, NULL };
|
||||||
|
@ -2889,9 +2892,10 @@ int retropt_bind(struct opt *opts,
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
case AF_UNIX:
|
case AF_UNIX:
|
||||||
{
|
{
|
||||||
bool tight = false;
|
bool abstract = (feats&2);
|
||||||
|
bool tight = (feats&1);
|
||||||
struct sockaddr_un *s_un = (struct sockaddr_un *)sa;
|
struct sockaddr_un *s_un = (struct sockaddr_un *)sa;
|
||||||
*salen = xiosetunix(af, s_un, bindname, false, tight);
|
*salen = xiosetunix(af, s_un, bindname, abstract, tight);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* WITH_UNIX */
|
#endif /* WITH_UNIX */
|
||||||
|
|
Loading…
Reference in a new issue