On bad parameter number print syntax; struct single pointers are now mostly called sfd

This commit is contained in:
Gerhard Rieger 2023-07-13 09:06:35 +02:00
parent 5eebca3a5b
commit 50b199dcd9
42 changed files with 1354 additions and 1163 deletions

View file

@ -188,6 +188,8 @@ Coding:
Moved multicast related code from xioopts.c to xio-ip.c and xio-ip6.c
Pointers of type struct single are now always called sfd.
Porting:
Removed Config/ because its contents have not been maintained for many
years.
@ -207,6 +209,8 @@ Documentation:
Renamed xiogetpacketsrc() to xiogetancillary()
On bad parameter number now print syntax.
####################### V 1.7.4.5 (not released):
Corrections:

View file

@ -17097,7 +17097,6 @@ CMD0="$TRACE $SOCAT $opts -T 2 PIPE EXEC:\"$CAT\",pty,setsid,sigint"
printf "test $F_n $TEST... " $N
$CMD0 >/dev/null 2>"${te}0" &
pid0=$!
#echo "pid0=$pid0" >&2 #!!!
sleep 1
kill -INT $pid0
wait

View file

@ -13,7 +13,7 @@
#include "xio-creat.h"
static int xioopen_creat(int arg, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3);
static int xioopen_creat(int arg, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, const struct addrdesc *addrdesc);
/*! within stream model, this is a write-only address - use 2 instead of 3 */
@ -37,7 +37,14 @@ static int _xioopen_creat(const char *path, int rw, struct opt *opts) {
}
static int xioopen_creat(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int dummy1, int dummy2, int dummy3) {
static int xioopen_creat(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xxfd->stream;
const char *filename = argv[1];
int rw = (xioflags&XIO_ACCMODE);
@ -46,7 +53,10 @@ static int xioopen_creat(int argc, const char *argv[], struct opt *opts, int xio
int result;
/* remove old file, or set user/permissions on old file; parse options */
if ((result = _xioopen_named_early(argc, argv, xxfd, groups, &exists, opts)) < 0) {
if ((result =
_xioopen_named_early(argc, argv, xxfd, addrdesc->groups, &exists, opts,
addrdesc->syntax))
< 0) {
return result;
}

View file

@ -13,23 +13,20 @@
#if WITH_EXEC
static int xioopen_exec(int argc, const char *argv[], struct opt *opts,
int xioflags, /* XIO_RDONLY etc. */
xiofile_t *fd,
groups_t groups,
int dummy1, int dummy2, int dummy3
);
static int xioopen_exec(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
const struct addrdesc xioaddr_exec = { "EXEC", 3, xioopen_exec, GROUP_FD|GROUP_FORK|GROUP_EXEC|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_TERMIOS|GROUP_FIFO|GROUP_PTY|GROUP_PARENT, 0, 0, 0 HELP(":<command-line>") };
const struct optdesc opt_dash = { "dash", "login", OPT_DASH, GROUP_EXEC, PH_PREEXEC, TYPE_BOOL, OFUNC_SPEC };
static int xioopen_exec(int argc, const char *argv[], struct opt *opts,
int xioflags, /* XIO_RDONLY, XIO_MAYCHILD etc. */
xiofile_t *xfd,
groups_t groups,
int dummy1, int dummy2, int dummy3
) {
static int xioopen_exec(
int argc,
const char *argv[],
struct opt *opts,
int xioflags, /* XIO_RDONLY, XIO_MAYCHILD etc. */
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xfd->stream;
int status;
bool dash = false;
@ -37,12 +34,14 @@ static int xioopen_exec(int argc, const char *argv[], struct opt *opts,
int numleft;
if (argc != 2) {
Error2("\"%s\": wrong number of parameters (%d instead of 1)", argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
retropt_bool(opts, OPT_DASH, &dash);
status = _xioopen_foxec(xioflags, sfd, groups, &opts, &duptostderr);
status =
_xioopen_foxec(xioflags, sfd, addrdesc->groups, &opts, &duptostderr);
if (status < 0)
return status;
if (status == 0) { /* child */

View file

@ -14,8 +14,8 @@
#if WITH_FDNUM
static int xioopen_fdnum(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3);
static int xioopen_accept_fd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3);
static int xioopen_fdnum(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
static int xioopen_accept_fd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
const struct addrdesc xioaddr_fd = { "FD", 1+XIO_RDWR, xioopen_fdnum, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_FILE|GROUP_SOCKET|GROUP_TERMIOS|GROUP_SOCK_UNIX|GROUP_SOCK_IP|GROUP_IPAPP, 0, 0, 0 HELP(":<fdnum>") };
@ -25,9 +25,14 @@ const struct addrdesc xioaddr_accept_fd = { "ACCEPT-FD", 1+XIO_RDWR, xioopen_acc
/* use some file descriptor and apply the options. Set the FD_CLOEXEC flag. */
static int xioopen_fdnum(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int dummy1, int dummy2, int dummy3) {
static int xioopen_fdnum(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
char *a1;
int rw = (xioflags&XIO_ACCMODE);
int numfd;
@ -46,7 +51,7 @@ static int xioopen_fdnum(int argc, const char *argv[], struct opt *opts,
Warn2("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", numfd, strerror(errno));
}
Notice2("using file descriptor %d for %s", numfd, ddirection[rw]);
if ((result = xioopen_fd(opts, rw, &xfd->stream, numfd, dummy2, dummy3)) < 0) {
if ((result = xioopen_fd(opts, rw, &xfd->stream, numfd)) < 0) {
return result;
}
return 0;
@ -61,10 +66,7 @@ static int xioopen_accept_fd(
struct opt *opts,
int xioflags,
xiofile_t *xfd,
groups_t groups,
int dummy1,
int dummy2,
int dummy3)
const struct addrdesc *addrdesc)
{
char *a1;
int rw = (xioflags&XIO_ACCMODE);
@ -74,7 +76,8 @@ static int xioopen_accept_fd(
int result;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
numfd = strtoul(argv[1], &a1, 0);
@ -103,29 +106,29 @@ static int xioopen_accept_fd(
#if WITH_FD
/* retrieve and apply options to a standard file descriptor.
Do not set FD_CLOEXEC flag. */
int xioopen_fd(struct opt *opts, int rw, xiosingle_t *xfd, int numfd, int dummy2, int dummy3) {
/* Retrieves and apply options to a standard file descriptor.
Does not set FD_CLOEXEC flag. */
int xioopen_fd(struct opt *opts, int rw, struct single *sfd, int numfd) {
xfd->fd = numfd;
xfd->howtoend = END_NONE;
sfd->fd = numfd;
sfd->howtoend = END_NONE;
#if WITH_TERMIOS
if (Isatty(xfd->fd)) {
if (Tcgetattr(xfd->fd, &xfd->savetty) < 0) {
if (Isatty(sfd->fd)) {
if (Tcgetattr(sfd->fd, &sfd->savetty) < 0) {
Warn2("cannot query current terminal settings on fd %d: %s",
xfd->fd, strerror(errno));
sfd->fd, strerror(errno));
} else {
xfd->ttyvalid = true;
sfd->ttyvalid = true;
}
}
#endif /* WITH_TERMIOS */
if (applyopts_single(xfd, opts, PH_INIT) < 0)
if (applyopts_single(sfd, opts, PH_INIT) < 0)
return -1;
applyopts2(xfd, -1, opts, PH_INIT, PH_FD);
applyopts2(sfd, -1, opts, PH_INIT, PH_FD);
return _xio_openlate(xfd, opts);
return _xio_openlate(sfd, opts);
}
#endif /* WITH_FD */

View file

@ -8,6 +8,6 @@
extern const struct addrdesc xioaddr_fd;
extern const struct addrdesc xioaddr_accept_fd;
extern int xioopen_fd(struct opt *opts, int rw, xiosingle_t *xfd, int numfd, int dummy2, int dummy3);
extern int xioopen_fd(struct opt *opts, int rw, xiosingle_t *xfd, int numfd);
#endif /* !defined(__xio_fdnum_h_included) */

View file

@ -11,7 +11,7 @@
#include "xio-file.h"
static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3);
static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
#if WITH_OPEN
@ -72,7 +72,14 @@ const struct addrdesc xioaddr_open = { "OPEN", 3, xioopen_open, GROUP_FD|GRO
if the filesystem entry already exists, the data is appended
if it does not exist, a file is created and the data is appended
*/
static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3) {
static int xioopen_open(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
const char *filename = argv[1];
int rw = (xioflags & XIO_ACCMODE);
struct single *sfd = &xfd->stream;
@ -81,7 +88,10 @@ static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xiof
int result;
/* remove old file, or set user/permissions on old file; parse options */
if ((result = _xioopen_named_early(argc, argv, xfd, groups, &exists, opts)) < 0) {
if ((result =
_xioopen_named_early(argc, argv, xfd, addrdesc->groups, &exists, opts,
addrdesc->syntax))
< 0) {
return result;
}

View file

@ -14,12 +14,19 @@
#if WITH_GOPEN
static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3);
static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
const struct addrdesc xioaddr_gopen = { "GOPEN", 3, xioopen_gopen, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_REG|GROUP_NAMED|GROUP_OPEN|GROUP_FILE|GROUP_TERMIOS|GROUP_SOCKET|GROUP_SOCK_UNIX, 0, 0, 0 HELP(":<filename>") };
static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int dummy1, int dummy2, int dummy3) {
static int xioopen_gopen(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xxfd->stream;
const char *filename = argv[1];
flags_t openflags = (xioflags & XIO_ACCMODE);
@ -29,7 +36,9 @@ static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xio
int result;
if ((result =
_xioopen_named_early(argc, argv, xxfd, GROUP_NAMED|groups, &exists, opts)) < 0) {
_xioopen_named_early(argc, argv, xxfd, GROUP_NAMED|addrdesc->groups, &exists,
opts, addrdesc->syntax))
< 0) {
return result;
}
st_mode = result;
@ -53,7 +62,7 @@ static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xio
Info1("\"%s\" is a socket, connecting to it", filename);
result =
_xioopen_unix_client(sfd, xioflags, groups, 0, opts, filename);
_xioopen_unix_client(sfd, xioflags, addrdesc->groups, 0, opts, filename);
if (result < 0) {
return result;
}

View file

@ -15,10 +15,7 @@
#include "xio-interface.h"
static
int xioopen_interface(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups, int pf,
int dummy2, int dummy3);
static int xioopen_interface(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
/*0 const struct optdesc opt_interface_addr = { "interface-addr", "address", OPT_INTERFACE_ADDR, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };*/
/*0 const struct optdesc opt_interface_netmask = { "interface-netmask", "netmask", OPT_INTERFACE_NETMASK, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };*/
@ -62,7 +59,7 @@ static
int _xioopen_interface(const char *ifname,
struct opt *opts, int xioflags, xiofile_t *xxfd,
groups_t groups, int pf) {
xiosingle_t *xfd = &xxfd->stream;
xiosingle_t *sfd = &xxfd->stream;
union sockaddr_union us = {{0}};
socklen_t uslen;
int socktype = SOCK_RAW;
@ -77,21 +74,21 @@ int _xioopen_interface(const char *ifname,
ifidx = 0; /* desparate attempt to continue */
}
xfd->howtoend = END_INTERFACE;
sfd->howtoend = END_INTERFACE;
retropt_int(opts, OPT_SO_TYPE, &socktype);
retropt_socket_pf(opts, &pf);
/* ...res_opts[] */
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
applyopts(xfd, -1, opts, PH_INIT);
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
applyopts(sfd, -1, opts, PH_INIT);
xfd->salen = sizeof(xfd->peersa);
sfd->salen = sizeof(sfd->peersa);
if (pf == PF_UNSPEC) {
pf = xfd->peersa.soa.sa_family;
pf = sfd->peersa.soa.sa_family;
}
xfd->dtype = XIODATA_RECVFROM_SKIPIP;
sfd->dtype = XIODATA_RECVFROM_SKIPIP;
if (retropt_string(opts, OPT_BIND, &bindstring)) {
needbind = true;
@ -102,24 +99,24 @@ int _xioopen_interface(const char *ifname,
us.ll.sll_ifindex = ifidx;
uslen = sizeof(sall);
needbind = true;
xfd->peersa = (union sockaddr_union)us;
sfd->peersa = (union sockaddr_union)us;
rc =
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
opts, xioflags, xfd, groups, pf, socktype, 0, 0);
opts, xioflags, sfd, groups, pf, socktype, 0, 0);
if (rc < 0)
return rc;
strncpy(xfd->para.interface.name, ifname, IFNAMSIZ);
_xiointerface_get_iff(xfd->fd, ifname, &xfd->para.interface.save_iff);
_xiointerface_apply_iff(xfd->fd, ifname, xfd->para.interface.iff_opts);
strncpy(sfd->para.interface.name, ifname, IFNAMSIZ);
_xiointerface_get_iff(sfd->fd, ifname, &sfd->para.interface.save_iff);
_xiointerface_apply_iff(sfd->fd, ifname, sfd->para.interface.iff_opts);
#ifdef PACKET_IGNORE_OUTGOING
/* Raw socket might also provide packets that are outbound - we are not
interested in these and disable this "feature" in kernel if possible */
if (Setsockopt(xfd->fd, SOL_PACKET, PACKET_IGNORE_OUTGOING, &one, sizeof(one)) < 0) {
if (Setsockopt(sfd->fd, SOL_PACKET, PACKET_IGNORE_OUTGOING, &one, sizeof(one)) < 0) {
Warn2("setsockopt(%d, SOL_PACKET, PACKET_IGNORE_OUTGOING, {1}): %s",
xfd->fd, strerror(errno));
sfd->fd, strerror(errno));
}
#endif /*defined(PACKET_IGNORE_OUTGOING) */
@ -144,32 +141,37 @@ int _interface_setsockopt_auxdata(int fd, int auxdata) {
}
static
int xioopen_interface(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int pf, int dummy2, int dummy3) {
xiosingle_t *xfd = &xxfd->stream;
int xioopen_interface(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
xiosingle_t *sfd = &xxfd->stream;
int result;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)",
argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
if ((result =
_xioopen_interface(argv[1], opts, xioflags, xxfd, groups, pf))
_xioopen_interface(argv[1], opts, xioflags, xxfd, addrdesc->groups,
addrdesc->arg1))
!= STAT_OK) {
return result;
}
xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
if (pf == PF_INET) {
xfd->dtype |= XIOREAD_RECV_SKIPIP;
sfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
if (addrdesc->arg1 == PF_INET) {
sfd->dtype |= XIOREAD_RECV_SKIPIP;
}
xfd->para.socket.la.soa.sa_family = xfd->peersa.soa.sa_family;
sfd->para.socket.la.soa.sa_family = sfd->peersa.soa.sa_family;
_xio_openlate(xfd, opts);
_xio_openlate(sfd, opts);
return STAT_OK;
}

View file

@ -731,7 +731,7 @@ int xiotype_ip_add_membership(
#if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)
int xioapply_ip_add_membership(
xiosingle_t *xfd,
struct single *sfd,
struct opt *opt)
{
union {
@ -754,9 +754,9 @@ mc:addr
/* First parameter is always multicast address */
/*! result */
xioresolve(opt->value.u_string/*multiaddr*/, NULL,
xfd->para.socket.la.soa.sa_family,
sfd->para.socket.la.soa.sa_family,
SOCK_DGRAM, IPPROTO_IP, &sockaddr1, &socklen1,
xfd->para.socket.ip.ai_flags);
sfd->para.socket.ip.ai_flags);
ip4_mreqn.mreq.imr_multiaddr = sockaddr1.ip4.sin_addr;
if (0) {
; /* for canonical reasons */
@ -765,9 +765,9 @@ mc:addr
/* three parameters */
/* second parameter is interface address */
xioresolve(opt->value2.u_string/*param2*/, NULL,
xfd->para.socket.la.soa.sa_family,
sfd->para.socket.la.soa.sa_family,
SOCK_DGRAM, IPPROTO_IP, &sockaddr2, &socklen2,
xfd->para.socket.ip.ai_flags);
sfd->para.socket.ip.ai_flags);
ip4_mreqn.mreq.imr_interface = sockaddr2.ip4.sin_addr;
/* third parameter is interface */
if (ifindex(opt->value3.u_string/*ifindex*/,
@ -793,10 +793,10 @@ mc:addr
} else {
/*! result */
xioresolve(opt->value2.u_string/*param2*/, NULL,
xfd->para.socket.la.soa.sa_family,
sfd->para.socket.la.soa.sa_family,
SOCK_DGRAM, IPPROTO_IP,
&sockaddr2, &socklen2,
xfd->para.socket.ip.ai_flags);
sfd->para.socket.ip.ai_flags);
ip4_mreqn.mreq.imr_interface = sockaddr2.ip4.sin_addr;
}
}
@ -804,18 +804,18 @@ mc:addr
#if LATER
if (0) {
; /* for canonical reasons */
} else if (xfd->para.socket.la.soa.sa_family == PF_INET) {
} else if (xfd->para.socket.la.soa.sa_family == PF_INET6) {
} else if (sfd->para.socket.la.soa.sa_family == PF_INET) {
} else if (sfd->para.socket.la.soa.sa_family == PF_INET6) {
ip6_mreqn.mreq.imr_multiaddr = sockaddr1.ip6.sin6_addr;
ip6_mreqn.mreq.imr_interface = sockaddr2.ip6.sin6_addr;
}
#endif
#if HAVE_STRUCT_IP_MREQN
if (Setsockopt(xfd->fd, opt->desc->major, opt->desc->minor,
if (Setsockopt(sfd->fd, opt->desc->major, opt->desc->minor,
&ip4_mreqn.mreqn, sizeof(ip4_mreqn.mreqn)) < 0) {
Error8("setsockopt(%d, %d, %d, {0x%08x,0x%08x,%d}, "F_Zu"): %s",
xfd->fd, opt->desc->major, opt->desc->minor,
sfd->fd, opt->desc->major, opt->desc->minor,
ip4_mreqn.mreqn.imr_multiaddr.s_addr,
ip4_mreqn.mreqn.imr_address.s_addr,
ip4_mreqn.mreqn.imr_ifindex,
@ -825,10 +825,10 @@ mc:addr
return -1;
}
#else
if (Setsockopt(xfd->fd, opt->desc->major, opt->desc->minor,
if (Setsockopt(sfd->fd, opt->desc->major, opt->desc->minor,
&ip4_mreqn.mreq, sizeof(ip4_mreqn.mreq)) < 0) {
Error7("setsockopt(%d, %d, %d, {0x%08x,0x%08x}, "F_Zu"): %s",
xfd->fd, opt->desc->major, opt->desc->minor,
sfd->fd, opt->desc->major, opt->desc->minor,
ip4_mreqn.mreq.imr_multiaddr,
ip4_mreqn.mreq.imr_interface,
sizeof(ip4_mreqn.mreq),
@ -932,7 +932,7 @@ int xiotype_ip_add_source_membership(char *token, const struct optname *ent, str
return 0;
}
int xioapply_ip_add_source_membership(struct single *xfd, struct opt *opt) {
int xioapply_ip_add_source_membership(struct single *sfd, struct opt *opt) {
struct ip_mreq_source ip4_mreq_src = {{0}};
/* IPv6 not supported - seems to have different handling */
union sockaddr_union sockaddr1;
@ -945,35 +945,35 @@ int xioapply_ip_add_source_membership(struct single *xfd, struct opt *opt) {
/* first parameter is always multicast address */
rc = xioresolve(opt->value.u_string/*mcaddr*/, NULL,
xfd->para.socket.la.soa.sa_family,
sfd->para.socket.la.soa.sa_family,
SOCK_DGRAM, IPPROTO_IP,
&sockaddr1, &socklen1, xfd->para.socket.ip.ai_flags);
&sockaddr1, &socklen1, sfd->para.socket.ip.ai_flags);
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,
sfd->para.socket.la.soa.sa_family,
SOCK_DGRAM, IPPROTO_IP,
&sockaddr2, &socklen2, xfd->para.socket.ip.ai_flags);
&sockaddr2, &socklen2, sfd->para.socket.ip.ai_flags);
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,
sfd->para.socket.la.soa.sa_family,
SOCK_DGRAM, IPPROTO_IP,
&sockaddr3, &socklen3, xfd->para.socket.ip.ai_flags);
&sockaddr3, &socklen3, sfd->para.socket.ip.ai_flags);
if (rc < 0) {
return -1;
}
ip4_mreq_src.imr_sourceaddr = sockaddr3.ip4.sin_addr;
if (Setsockopt(xfd->fd, opt->desc->major, opt->desc->minor,
if (Setsockopt(sfd->fd, opt->desc->major, opt->desc->minor,
&ip4_mreq_src, sizeof(ip4_mreq_src)) < 0) {
Error8("setsockopt(%d, %d, %d, {0x%08x,0x%08x,0x%08x}, "F_Zu"): %s",
xfd->fd, opt->desc->major, opt->desc->minor,
sfd->fd, opt->desc->major, opt->desc->minor,
htonl((uint32_t)ip4_mreq_src.imr_multiaddr.s_addr),
ip4_mreq_src.imr_interface.s_addr,
ip4_mreq_src.imr_sourceaddr.s_addr,

View file

@ -259,7 +259,7 @@ int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange *range) {
returns STAT_OK on success
*/
int xiolog_ancillary_ip6(
struct single *xfd,
struct single *sfd,
struct cmsghdr *cmsg,
int *num,
char *typbuff, int typlen,
@ -476,7 +476,7 @@ xiosetsockaddrenv_ip6(int idx, char *namebuff, size_t namelen,
#if defined(HAVE_STRUCT_IPV6_MREQ)
int xioapply_ipv6_join_group(
xiosingle_t *xfd,
struct single *sfd,
struct opt *opt)
{
struct ipv6_mreq ip6_mreq = {{{{0}}}};
@ -488,10 +488,10 @@ int xioapply_ipv6_join_group(
/* First parameter is multicast address */
if ((res =
xioresolve(opt->value.u_string/*multiaddr*/, NULL,
xfd->para.socket.la.soa.sa_family,
sfd->para.socket.la.soa.sa_family,
SOCK_DGRAM, IPPROTO_IP,
&sockaddr1, &socklen1,
xfd->para.socket.ip.ai_flags))
sfd->para.socket.ip.ai_flags))
!= STAT_OK) {
return res;
}
@ -504,10 +504,10 @@ int xioapply_ipv6_join_group(
ip6_mreq.ipv6mr_interface = htonl(0);
}
if (Setsockopt(xfd->fd, opt->desc->major, opt->desc->minor,
if (Setsockopt(sfd->fd, opt->desc->major, opt->desc->minor,
&ip6_mreq, sizeof(ip6_mreq)) < 0) {
Error6("setsockopt(%d, %d, %d, {...,0x%08x}, "F_Zu"): %s",
xfd->fd, opt->desc->major, opt->desc->minor,
sfd->fd, opt->desc->major, opt->desc->minor,
ip6_mreq.ipv6mr_interface,
sizeof(ip6_mreq),
strerror(errno));
@ -618,7 +618,7 @@ int xiotype_ip6_join_source_group(
return 0;
}
int xioapply_ip6_join_source_group(struct single *xfd, struct opt *opt) {
int xioapply_ip6_join_source_group(struct single *sfd, struct opt *opt) {
struct group_source_req ip6_gsr = {0};
union sockaddr_union sockaddr1;
socklen_t socklen1 = sizeof(sockaddr1.ip6);
@ -629,9 +629,9 @@ int xioapply_ip6_join_source_group(struct single *xfd, struct opt *opt) {
/* First parameter is always multicast address */
if ((res =
xioresolve(opt->value.u_string/*mcaddr*/, NULL,
xfd->para.socket.la.soa.sa_family,
sfd->para.socket.la.soa.sa_family,
SOCK_DGRAM, IPPROTO_IP, &sockaddr1, &socklen1,
xfd->para.socket.ip.ai_flags))
sfd->para.socket.ip.ai_flags))
!= STAT_OK) {
return res;
}
@ -647,17 +647,17 @@ int xioapply_ip6_join_source_group(struct single *xfd, struct opt *opt) {
/* Third parameter is source address */
if ((res =
xioresolve(opt->value3.u_string/*srcaddr*/, NULL,
xfd->para.socket.la.soa.sa_family,
sfd->para.socket.la.soa.sa_family,
SOCK_DGRAM, IPPROTO_IP, &sockaddr2, &socklen2,
xfd->para.socket.ip.ai_flags))
sfd->para.socket.ip.ai_flags))
!= STAT_OK) {
return res;
}
memcpy(&ip6_gsr.gsr_source, &sockaddr2.ip6, socklen2);
if (Setsockopt(xfd->fd, opt->desc->major, opt->desc->minor,
if (Setsockopt(sfd->fd, opt->desc->major, opt->desc->minor,
&ip6_gsr, sizeof(ip6_gsr)) < 0) {
Error6("setsockopt(%d, %d, %d, {%d,...}, "F_Zu"): %s",
xfd->fd, opt->desc->major, opt->desc->minor,
sfd->fd, opt->desc->major, opt->desc->minor,
ip6_gsr.gsr_interface,
sizeof(ip6_gsr),
strerror(errno));

View file

@ -21,12 +21,19 @@ const struct optdesc opt_lowport = { "lowport", NULL, OPT_LOWPORT, GROUP_IPAPP,
#if WITH_IP4
/* we expect the form "host:port" */
int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd,
groups_t groups, int socktype, int ipproto,
int pf) {
struct single *xfd = &xxfd->stream;
int xioopen_ipapp_connect(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xxfd->stream;
struct opt *opts0 = NULL;
int socktype = addrdesc->arg1;
int ipproto = addrdesc->arg2;
int pf = addrdesc->arg3;
const char *hostname = argv[1], *portname = argv[2];
bool dofork = false;
union sockaddr_union us_sa, *us = &us_sa;
@ -41,19 +48,21 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
int result;
if (argc != 3) {
Error2("%s: wrong number of parameters (%d instead of 2)", argv[0], argc-1);
xio_syntax(argv[0], 2, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
xfd->howtoend = END_SHUTDOWN;
xioinit_ip(&pf, xioparms.default_ip);
sfd->howtoend = END_SHUTDOWN;
if (applyopts_single(xfd, opts, PH_INIT) < 0)
if (applyopts_single(sfd, opts, PH_INIT) < 0)
return -1;
applyopts(xfd, -1, opts, PH_INIT);
applyopts(sfd, -1, opts, PH_INIT);
retropt_bool(opts, OPT_FORK, &dofork);
if (_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto,
xfd->para.socket.ip.ai_flags,
sfd->para.socket.ip.ai_flags,
&themlist, us, &uslen, &needbind, &lowport,
socktype) != STAT_OK) {
return STAT_NORETRY;
@ -95,14 +104,14 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
infobuff, sizeof(infobuff)));
#if WITH_RETRY
if (xfd->forever || xfd->retry || ai_sorted[i] != NULL) {
if (sfd->forever || sfd->retry || ai_sorted[i] != NULL) {
level = E_INFO;
} else
#endif /* WITH_RETRY */
level = E_ERROR;
result =
_xioopen_connect(xfd,
_xioopen_connect(sfd,
needbind?us:NULL, uslen,
themp->ai_addr, themp->ai_addrlen,
opts, pf?pf:themp->ai_family, socktype, ipproto,
@ -119,10 +128,10 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
#if WITH_RETRY
case STAT_RETRYLATER:
case STAT_RETRYNOW:
if (xfd->forever || xfd->retry) {
--xfd->retry;
if (sfd->forever || sfd->retry) {
--sfd->retry;
if (result == STAT_RETRYLATER) {
Nanosleep(&xfd->intervall, NULL);
Nanosleep(&sfd->intervall, NULL);
}
dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL);
continue;
@ -138,13 +147,13 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
if (dofork) {
pid_t pid;
int level = E_ERROR;
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
level = E_WARN; /* most users won't expect a problem here,
so Notice is too weak */
}
while ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
if (xfd->forever || --xfd->retry) {
Nanosleep(&xfd->intervall, NULL); continue;
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
if (sfd->forever || --sfd->retry) {
Nanosleep(&sfd->intervall, NULL); continue;
}
free(ai_sorted);
free(opts0);
@ -152,14 +161,14 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
}
if (pid == 0) { /* child process */
xfd->forever = false; xfd->retry = 0;
sfd->forever = false; sfd->retry = 0;
break;
}
/* parent process */
Close(xfd->fd);
Close(sfd->fd);
/* with and without retry */
Nanosleep(&xfd->intervall, NULL);
Nanosleep(&sfd->intervall, NULL);
dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL);
continue; /* with next socket() bind() connect() */
} else
@ -172,7 +181,7 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
free(ai_sorted);
xiofreeaddrinfo(themlist);
if ((result = _xio_openlate(xfd, opts)) < 0) {
if ((result = _xio_openlate(sfd, opts)) < 0) {
free(opts0);free(opts);
return result;
}
@ -302,18 +311,26 @@ int _xioopen_ipapp_listen_prepare(
/* 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 *xfd,
groups_t groups, int socktype,
int ipproto, int pf) {
int xioopen_ipapp_listen(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xfd->stream;
struct opt *opts0 = NULL;
int socktype = addrdesc->arg1;
int ipproto = addrdesc->arg2;
int pf = addrdesc->arg3;
union sockaddr_union us_sa, *us = &us_sa;
socklen_t uslen = sizeof(us_sa);
int result;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
xio_syntax(argv[0], 2, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
xioinit_ip(&pf, xioparms.default_ip);
@ -331,23 +348,23 @@ int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts,
#endif
}
xfd->stream.howtoend = END_SHUTDOWN;
sfd->howtoend = END_SHUTDOWN;
if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0) return -1;
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
applyopts(sfd, -1, opts, PH_INIT);
applyopts(sfd, -1, opts, PH_EARLY);
if (_xioopen_ipapp_listen_prepare(opts, &opts0, argv[1], &pf, ipproto,
xfd->stream.para.socket.ip.ai_flags,
sfd->para.socket.ip.ai_flags,
us, &uslen, socktype)
!= STAT_OK) {
return STAT_NORETRY;
}
if ((result =
xioopen_listen(&xfd->stream, xioflags,
xioopen_listen(sfd, xioflags,
(struct sockaddr *)us, uslen,
opts, opts0, pf, socktype, ipproto))
opts, opts0, pf, socktype, ipproto))
!= 0)
return result;
return 0;

View file

@ -14,19 +14,13 @@ extern const struct optdesc opt_sourceport;
/*extern const struct optdesc opt_port;*/
extern const struct optdesc opt_lowport;
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, const int ai_flags[2], struct addrinfo **res, union sockaddr_union *us, socklen_t *uslen, bool *needbind, bool *lowport,
int socktype);
extern int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
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], 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,
struct opt *opts);
extern int xioopen_ipapp_listen(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_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
extern int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0, const char *portname, int *pf, int ipproto, const int ai_flags[2], union sockaddr_union *us, socklen_t *uslen, int socktype);
extern int _xio_sort_ip_addresses(struct addrinfo *themlist, struct addrinfo **ai_sorted);

View file

@ -35,7 +35,7 @@ const struct optdesc opt_accept_timeout = { "accept-timeout", "listen-timeout",
OPT_SOURCEPORT, OPT_LOWPORT, cloexec
*/
int
xioopen_listen(struct single *xfd, int xioflags,
xioopen_listen(struct single *sfd, int xioflags,
struct sockaddr *us, socklen_t uslen,
struct opt *opts, struct opt *opts0,
int pf, int socktype, int proto) {
@ -43,7 +43,7 @@ int
int result;
#if WITH_RETRY
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
level = E_INFO;
} else
#endif /* WITH_RETRY */
@ -53,7 +53,7 @@ int
/* tcp listen; this can fork() for us; it only returns on error or on
successful establishment of tcp connection */
result = _xioopen_listen(xfd, xioflags,
result = _xioopen_listen(sfd, xioflags,
(struct sockaddr *)us, uslen,
opts, pf, socktype, proto, level);
/*! not sure if we should try again on retry/forever */
@ -62,13 +62,13 @@ int
#if WITH_RETRY
case STAT_RETRYLATER:
case STAT_RETRYNOW:
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
if (result == STAT_RETRYLATER) {
Nanosleep(&xfd->intervall, NULL);
Nanosleep(&sfd->intervall, NULL);
}
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
--xfd->retry;
--sfd->retry;
continue;
}
return STAT_NORETRY;
@ -103,31 +103,31 @@ int
OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_BACKLOG, OPT_RANGE, tcpwrap,
OPT_SOURCEPORT, OPT_LOWPORT, cloexec
*/
int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen,
int _xioopen_listen(struct single *sfd, int xioflags, struct sockaddr *us, socklen_t uslen,
struct opt *opts, int pf, int socktype, int proto, int level) {
int backlog = 5; /* why? 1 seems to cause problems under some load */
char infobuff[256];
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
if ((xfd->fd = xiosocket(opts, pf?pf:us->sa_family, socktype, proto, level)) < 0) {
if ((sfd->fd = xiosocket(opts, pf?pf:us->sa_family, socktype, proto, level)) < 0) {
return STAT_RETRYLATER;
}
applyopts(xfd, -1, opts, PH_PASTSOCKET);
applyopts(sfd, -1, opts, PH_PASTSOCKET);
applyopts_offset(xfd, opts);
applyopts_cloexec(xfd->fd, opts);
applyopts_offset(sfd, opts);
applyopts_cloexec(sfd->fd, opts);
/* Phase prebind */
xiosock_reuseaddr(xfd->fd, proto, opts);
applyopts(xfd, -1, opts, PH_PREBIND);
xiosock_reuseaddr(sfd->fd, proto, opts);
applyopts(sfd, -1, opts, PH_PREBIND);
applyopts(xfd, -1, opts, PH_BIND);
if (Bind(xfd->fd, (struct sockaddr *)us, uslen) < 0) {
Msg4(level, "bind(%d, {%s}, "F_socklen"): %s", xfd->fd,
applyopts(sfd, -1, opts, PH_BIND);
if (Bind(sfd->fd, (struct sockaddr *)us, uslen) < 0) {
Msg4(level, "bind(%d, {%s}, "F_socklen"): %s", sfd->fd,
sockaddr_info(us, uslen, infobuff, sizeof(infobuff)), uslen,
strerror(errno));
Close(xfd->fd);
Close(sfd->fd);
return STAT_RETRYLATER;
}
@ -136,36 +136,36 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl
if (((union sockaddr_union *)us)->un.sun_path[0] != '\0') {
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_FD);
} else {
applyopts(xfd, -1, opts, PH_FD);
applyopts(sfd, -1, opts, PH_FD);
}
}
#endif
applyopts(xfd, -1, opts, PH_PASTBIND);
applyopts(sfd, -1, opts, PH_PASTBIND);
#if WITH_UNIX
if (us->sa_family == AF_UNIX) {
if (((union sockaddr_union *)us)->un.sun_path[0] != '\0') {
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_EARLY);
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_PREOPEN);
} else {
applyopts(xfd, -1, opts, PH_EARLY);
applyopts(xfd, -1, opts, PH_PREOPEN);
applyopts(sfd, -1, opts, PH_EARLY);
applyopts(sfd, -1, opts, PH_PREOPEN);
}
}
#endif /* WITH_UNIX */
applyopts(xfd, -1, opts, PH_PRELISTEN);
applyopts(sfd, -1, opts, PH_PRELISTEN);
retropt_int(opts, OPT_BACKLOG, &backlog);
applyopts(xfd, -1, opts, PH_LISTEN);
if (Listen(xfd->fd, backlog) < 0) {
Error3("listen(%d, %d): %s", xfd->fd, backlog, strerror(errno));
applyopts(sfd, -1, opts, PH_LISTEN);
if (Listen(sfd->fd, backlog) < 0) {
Error3("listen(%d, %d): %s", sfd->fd, backlog, strerror(errno));
return STAT_RETRYLATER;
}
return _xioopen_accept_fd(xfd, xioflags, us, uslen, opts, pf, proto,level);
return _xioopen_accept_fd(sfd, xioflags, us, uslen, opts, pf, proto,level);
}
int _xioopen_accept_fd(
struct single *xfd,
struct single *sfd,
int xioflags,
struct sockaddr *us,
socklen_t uslen,
@ -196,7 +196,7 @@ int _xioopen_accept_fd(
Error("option fork not allowed here");
return STAT_NORETRY;
}
xfd->flags |= XIO_DOESFORK;
sfd->flags |= XIO_DOESFORK;
}
retropt_int(opts, OPT_MAX_CHILDREN, &maxchildren);
@ -213,33 +213,33 @@ int _xioopen_accept_fd(
/* Under some circumstances (e.g., TCP listen on port 0) bind() fills empty
fields that we want to know. */
salen = sizeof(sa);
if (Getsockname(xfd->fd, us, &uslen) < 0) {
if (Getsockname(sfd->fd, us, &uslen) < 0) {
Warn4("getsockname(%d, %p, {%d}): %s",
xfd->fd, &us, uslen, strerror(errno));
sfd->fd, &us, uslen, strerror(errno));
}
#if WITH_IP4 /*|| WITH_IP6*/
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
if (xioparserange(rangename, pf, &xfd->para.socket.range,
xfd->para.socket.ip.ai_flags)
if (xioparserange(rangename, pf, &sfd->para.socket.range,
sfd->para.socket.ip.ai_flags)
< 0) {
free(rangename);
return STAT_NORETRY;
}
free(rangename);
xfd->para.socket.dorange = true;
sfd->para.socket.dorange = true;
}
#endif
#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
xio_retropt_tcpwrap(xfd, opts);
xio_retropt_tcpwrap(sfd, opts);
#endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */
#if WITH_TCP || WITH_UDP
if (retropt_ushort(opts, OPT_SOURCEPORT, &xfd->para.socket.ip.sourceport) >= 0) {
xfd->para.socket.ip.dosourceport = true;
if (retropt_ushort(opts, OPT_SOURCEPORT, &sfd->para.socket.ip.sourceport) >= 0) {
sfd->para.socket.ip.dosourceport = true;
}
retropt_bool(opts, OPT_LOWPORT, &xfd->para.socket.ip.lowport);
retropt_bool(opts, OPT_LOWPORT, &sfd->para.socket.ip.lowport);
#endif /* WITH_TCP || WITH_UDP */
if (xioparms.logopt == 'm') {
@ -259,30 +259,30 @@ int _xioopen_accept_fd(
do {
/*? int level = E_ERROR;*/
Notice1("listening on %s", sockaddr_info(us, uslen, lisname, sizeof(lisname)));
if (xfd->para.socket.accept_timeout.tv_sec > 0 ||
xfd->para.socket.accept_timeout.tv_usec > 0) {
if (sfd->para.socket.accept_timeout.tv_sec > 0 ||
sfd->para.socket.accept_timeout.tv_usec > 0) {
fd_set rfd;
struct timeval tmo;
FD_ZERO(&rfd);
FD_SET(xfd->fd, &rfd);
tmo.tv_sec = xfd->para.socket.accept_timeout.tv_sec;
tmo.tv_usec = xfd->para.socket.accept_timeout.tv_usec;
FD_SET(sfd->fd, &rfd);
tmo.tv_sec = sfd->para.socket.accept_timeout.tv_sec;
tmo.tv_usec = sfd->para.socket.accept_timeout.tv_usec;
while (1) {
if (Select(xfd->fd+1, &rfd, NULL, NULL, &tmo) < 0) {
if (Select(sfd->fd+1, &rfd, NULL, NULL, &tmo) < 0) {
if (errno != EINTR) {
Error5("Select(%d, &0x%lx, NULL, NULL, {%ld.%06ld}): %s", xfd->fd+1, 1L<<(xfd->fd+1),
xfd->para.socket.accept_timeout.tv_sec, xfd->para.socket.accept_timeout.tv_usec,
Error5("Select(%d, &0x%lx, NULL, NULL, {%ld.%06ld}): %s", sfd->fd+1, 1L<<(sfd->fd+1),
sfd->para.socket.accept_timeout.tv_sec, sfd->para.socket.accept_timeout.tv_usec,
strerror(errno));
}
} else {
break;
}
}
if (!FD_ISSET(xfd->fd, &rfd)) {
if (!FD_ISSET(sfd->fd, &rfd)) {
struct sigaction act;
Warn1("accept: %s", strerror(ETIMEDOUT));
Close(xfd->fd);
Close(sfd->fd);
Notice("Waiting for child processes to terminate");
memset(&act, 0, sizeof(struct sigaction));
act.sa_flags = SA_NOCLDSTOP/*|SA_RESTART*/
@ -304,9 +304,9 @@ int _xioopen_accept_fd(
Exit(0);
}
}
ps = Accept(xfd->fd, (struct sockaddr *)&sa, &salen);
ps = Accept(sfd->fd, (struct sockaddr *)&sa, &salen);
if (ps >= 0) {
/*0 Info4("accept(%d, %p, {"F_Zu"}) -> %d", xfd->fd, &sa, salen, ps);*/
/*0 Info4("accept(%d, %p, {"F_Zu"}) -> %d", sfd->fd, &sa, salen, ps);*/
break; /* success, break out of loop */
}
if (errno == EINTR) {
@ -314,12 +314,12 @@ int _xioopen_accept_fd(
}
if (errno == ECONNABORTED) {
Notice4("accept(%d, %p, {"F_socklen"}): %s",
xfd->fd, &sa, salen, strerror(errno));
sfd->fd, &sa, salen, strerror(errno));
continue;
}
Msg4(level, "accept(%d, %p, {"F_socklen"}): %s",
xfd->fd, &sa, salen, strerror(errno));
Close(xfd->fd);
sfd->fd, &sa, salen, strerror(errno));
Close(sfd->fd);
return STAT_RETRYLATER;
} while (true);
applyopts_cloexec(ps, opts);
@ -339,7 +339,7 @@ int _xioopen_accept_fd(
la?
sockaddr_info(&la->soa, las, sockname, sizeof(sockname)):"NULL");
if (pa != NULL && la != NULL && xiocheckpeer(xfd, pa, la) < 0) {
if (pa != NULL && la != NULL && xiocheckpeer(sfd, pa, la) < 0) {
if (Shutdown(ps, 2) < 0) {
Info2("shutdown(%d, 2): %s", ps, strerror(errno));
}
@ -363,9 +363,9 @@ int _xioopen_accept_fd(
if ((pid =
xio_fork(false, level==E_ERROR?level:E_WARN,
xfd->shutup))
sfd->shutup))
< 0) {
Close(xfd->fd);
Close(sfd->fd);
Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL);
return STAT_RETRYLATER;
}
@ -376,14 +376,14 @@ int _xioopen_accept_fd(
Info1("just born: child process "F_pid, cpid);
xiosetenvulong("PID", cpid, 1);
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
xfd->fd = ps;
sfd->fd = ps;
#if WITH_RETRY
/* !? */
xfd->forever = false; xfd->retry = 0;
sfd->forever = false; sfd->retry = 0;
level = E_ERROR;
#endif /* WITH_RETRY */
@ -410,18 +410,18 @@ int _xioopen_accept_fd(
}
Info("still listening");
} else {
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
xfd->fd = ps;
sfd->fd = ps;
break;
}
}
applyopts(xfd, -1, opts, PH_FD);
applyopts(xfd, -1, opts, PH_PASTSOCKET);
applyopts(xfd, -1, opts, PH_CONNECTED);
if ((result = _xio_openlate(xfd, opts)) < 0)
applyopts(sfd, -1, opts, PH_FD);
applyopts(sfd, -1, opts, PH_PASTSOCKET);
applyopts(sfd, -1, opts, PH_CONNECTED);
if ((result = _xio_openlate(sfd, opts)) < 0)
return result;
/* set the env vars describing the local and remote sockets */

View file

@ -95,8 +95,14 @@ int applyopts_named(const char *filename, struct opt *opts, unsigned int phase)
If the path exists, its st_mode field is returned.
After this sub you may proceed with open() or whatever...
*/
int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd,
groups_t groups, bool *exists, struct opt *opts)
int _xioopen_named_early(
int argc,
const char *argv[],
xiofile_t *xfd,
groups_t groups,
bool *exists,
struct opt *opts,
const char *syntax)
{
const char *path = argv[1];
struct single *sfd = &xfd->stream;
@ -108,7 +114,8 @@ int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd,
bool opt_unlink_early = false;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0]?argv[0]:"<named>", argc);
xio_syntax(argv[0], 1, argc-1, syntax);
return STAT_NORETRY;
}
statbuf.st_mode = 0;
/* find the appropriate groupbits */

View file

@ -18,9 +18,7 @@ extern const struct optdesc opt_umask;
extern int
applyopts_named(const char *filename, struct opt *opts, unsigned int phase);
extern int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd,
groups_t groups,
bool *exists, struct opt *opts);
extern int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd, groups_t groups, bool *exists, struct opt *opts, const char *syntax);
extern int _xioopen_open(const char *path, int rw, struct opt *opts);
extern int xio_unlink(const char *pathname, int level);

View file

@ -43,21 +43,18 @@
*/
/* static declaration of ssl's open function */
static int xioopen_openssl_connect(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *fd, groups_t groups,
int dummy1, int dummy2, int dummy3);
static int xioopen_openssl_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
/* static declaration of ssl's open function */
static int xioopen_openssl_listen(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *fd, groups_t groups,
int dummy1, int dummy2, int dummy3);
static int xioopen_openssl_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
static int openssl_SSL_ERROR_SSL(int level, const char *funcname);
static int openssl_handle_peer_certificate(struct single *xfd,
static int openssl_handle_peer_certificate(struct single *sfd,
const char *peername,
bool opt_ver,
int level);
static int xioSSL_set_fd(struct single *xfd, int level);
static int xioSSL_connect(struct single *xfd, const char *opt_commonname, bool opt_ver, int level);
static int xioSSL_set_fd(struct single *sfd, int level);
static int xioSSL_connect(struct single *sfd, const char *opt_commonname, bool opt_ver, int level);
static int openssl_delete_cert_info(void);
@ -223,26 +220,20 @@ static void openssl_conn_loginfo(SSL *ssl) {
}
/* the open function for OpenSSL client */
static int
xioopen_openssl_connect(int argc,
const char *argv[], /* the arguments in the address string */
struct opt *opts,
int xioflags, /* is the open meant for reading (0),
static int xioopen_openssl_connect(
int argc,
const char *argv[], /* the arguments in the address string */
struct opt *opts,
int xioflags, /* is the open meant for reading (0),
writing (1), or both (2) ? */
xiofile_t *xxfd, /* a xio file descriptor structure,
xiofile_t *xxfd, /* a xio file descriptor structure,
already allocated */
groups_t groups, /* the matching address groups... */
int protogrp, /* first transparent integer value from
addr_openssl */
int dummy2, /* second transparent integer value from
addr_openssl */
int dummy3) /* transparent pointer value from
addr_openssl */
const struct addrdesc *addrdesc) /* the above descriptor */
{
struct single *xfd = &xxfd->stream;
struct single *sfd = xfd;
struct single *sfd = &xxfd->stream;
struct opt *opts0 = NULL;
const char *hostname, *portname;
int protogrp = addrdesc->arg1;
int pf = PF_UNSPEC;
bool use_dtls = (protogrp != 0);
int socktype = SOCK_STREAM;
@ -268,10 +259,10 @@ static int
Error("address with data processing not allowed here");
return STAT_NORETRY;
}
xfd->flags |= XIO_DOESCONVERT;
sfd->flags |= XIO_DOESCONVERT;
if (argc != 3) {
Error1("%s: 2 parameters required", argv[0]);
xio_syntax(argv[0], 2, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
hostname = argv[1];
@ -283,8 +274,10 @@ static int
return STAT_NORETRY;
}
xfd->howtoend = END_SHUTDOWN;
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
xioinit_ip(&pf, xioparms.default_ip);
sfd->howtoend = END_SHUTDOWN;
if (applyopts_single(sfd, opts, PH_INIT) < 0)
return -1;
applyopts(sfd, -1, opts, PH_INIT);
retropt_bool(opts, OPT_FORK, &dofork);
@ -317,7 +310,7 @@ static int
#endif
result =
_xioopen_openssl_prepare(opts, xfd, false, &opt_ver, opt_cert, &ctx, (bool *)&use_dtls);
_xioopen_openssl_prepare(opts, sfd, false, &opt_ver, opt_cert, &ctx, (bool *)&use_dtls);
if (result != STAT_OK) return STAT_NORETRY;
if (use_dtls) {
@ -329,7 +322,7 @@ static int
result =
_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto,
xfd->para.socket.ip.ai_flags,
sfd->para.socket.ip.ai_flags,
&themlist, us, &uslen,
&needbind, &lowport, socktype);
if (result != STAT_OK) return STAT_NORETRY;
@ -362,7 +355,7 @@ static int
while (themp != NULL) {
#if WITH_RETRY
if (xfd->forever || xfd->retry || ai_sorted[i] != NULL) {
if (sfd->forever || sfd->retry || ai_sorted[i] != NULL) {
level = E_INFO;
} else
#endif /* WITH_RETRY */
@ -370,7 +363,7 @@ static int
/* This cannot fork because we retrieved fork option above */
result =
_xioopen_connect(xfd,
_xioopen_connect(sfd,
needbind?us:NULL, uslen,
themp->ai_addr, themp->ai_addrlen,
opts, pf?pf:themp->ai_addr->sa_family, socktype, ipproto, lowport, level);
@ -386,12 +379,12 @@ static int
#if WITH_RETRY
case STAT_RETRYLATER:
case STAT_RETRYNOW:
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
if (result == STAT_RETRYLATER) {
Nanosleep(&xfd->intervall, NULL);
Nanosleep(&sfd->intervall, NULL);
}
--xfd->retry;
--sfd->retry;
continue;
}
free(ai_sorted);
@ -402,25 +395,25 @@ static int
return result;
}
/*! isn't this too early? */
if ((result = _xio_openlate(xfd, opts)) < 0) {
if ((result = _xio_openlate(sfd, opts)) < 0) {
free(ai_sorted);
return result;
}
result = _xioopen_openssl_connect(xfd, opt_ver, opt_commonname,
result = _xioopen_openssl_connect(sfd, opt_ver, opt_commonname,
opt_no_sni, opt_snihost, ctx, level);
switch (result) {
case STAT_OK: break;
#if WITH_RETRY
case STAT_RETRYLATER:
case STAT_RETRYNOW:
if (xfd->forever || xfd->retry) {
Close(xfd->fd);
if (sfd->forever || sfd->retry) {
Close(sfd->fd);
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
if (result == STAT_RETRYLATER) {
Nanosleep(&xfd->intervall, NULL);
Nanosleep(&sfd->intervall, NULL);
}
--xfd->retry;
--sfd->retry;
continue;
}
#endif /* WITH_RETRY */
@ -437,28 +430,28 @@ static int
if (dofork) {
pid_t pid;
int level = E_ERROR;
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
level = E_WARN;
}
while ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
if (xfd->forever || --xfd->retry) {
Nanosleep(&xfd->intervall, NULL); continue;
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
if (sfd->forever || --sfd->retry) {
Nanosleep(&sfd->intervall, NULL); continue;
}
xiofreeaddrinfo(themlist);
return STAT_RETRYLATER;
}
if (pid == 0) { /* child process */
xfd->forever = false; xfd->retry = 0;
sfd->forever = false; sfd->retry = 0;
break;
}
/* parent process */
Close(xfd->fd);
sycSSL_free(xfd->para.openssl.ssl);
xfd->para.openssl.ssl = NULL;
Close(sfd->fd);
sycSSL_free(sfd->para.openssl.ssl);
sfd->para.openssl.ssl = NULL;
/* with and without retry */
Nanosleep(&xfd->intervall, NULL);
Nanosleep(&sfd->intervall, NULL);
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
continue; /* with next socket() bind() connect() */
}
@ -468,7 +461,7 @@ static int
free(ai_sorted);
xiofreeaddrinfo(themlist);
openssl_conn_loginfo(xfd->para.openssl.ssl);
openssl_conn_loginfo(sfd->para.openssl.ssl);
free((void *)opt_commonname);
free((void *)opt_snihost);
@ -479,10 +472,10 @@ static int
/* this function is typically called within the OpenSSL client fork/retry loop.
xfd must be of type DATA_OPENSSL, and its fd must be set with a valid file
sfd must be of type DATA_OPENSSL, and its fd must be set with a valid file
descriptor. this function then performs all SSL related step to make a valid
SSL connection from an FD and a CTX. */
int _xioopen_openssl_connect(struct single *xfd,
int _xioopen_openssl_connect(struct single *sfd,
bool opt_ver,
const char *opt_commonname,
bool no_sni,
@ -502,12 +495,12 @@ int _xioopen_openssl_connect(struct single *xfd,
/*Error("SSL_new()");*/
return STAT_RETRYLATER;
}
xfd->para.openssl.ssl = ssl;
sfd->para.openssl.ssl = ssl;
result = xioSSL_set_fd(xfd, level);
result = xioSSL_set_fd(sfd, level);
if (result != STAT_OK) {
sycSSL_free(xfd->para.openssl.ssl);
xfd->para.openssl.ssl = NULL;
sycSSL_free(sfd->para.openssl.ssl);
sfd->para.openssl.ssl = NULL;
return result;
}
@ -517,25 +510,25 @@ int _xioopen_openssl_connect(struct single *xfd,
Warn("refusing to set empty SNI host name");
} else if (!SSL_set_tlsext_host_name(ssl, snihost)) {
Error1("Failed to set SNI host \"%s\"", snihost);
sycSSL_free(xfd->para.openssl.ssl);
xfd->para.openssl.ssl = NULL;
sycSSL_free(sfd->para.openssl.ssl);
sfd->para.openssl.ssl = NULL;
return STAT_NORETRY;
}
}
#endif
result = xioSSL_connect(xfd, opt_commonname, opt_ver, level);
result = xioSSL_connect(sfd, opt_commonname, opt_ver, level);
if (result != STAT_OK) {
sycSSL_free(xfd->para.openssl.ssl);
xfd->para.openssl.ssl = NULL;
sycSSL_free(sfd->para.openssl.ssl);
sfd->para.openssl.ssl = NULL;
return result;
}
result = openssl_handle_peer_certificate(xfd, opt_commonname,
result = openssl_handle_peer_certificate(sfd, opt_commonname,
opt_ver, level);
if (result != STAT_OK) {
sycSSL_free(xfd->para.openssl.ssl);
xfd->para.openssl.ssl = NULL;
sycSSL_free(sfd->para.openssl.ssl);
sfd->para.openssl.ssl = NULL;
return result;
}
@ -545,25 +538,19 @@ int _xioopen_openssl_connect(struct single *xfd,
#if WITH_LISTEN
static int
xioopen_openssl_listen(int argc,
const char *argv[], /* the arguments in the address string */
struct opt *opts,
int xioflags, /* is the open meant for reading (0),
static int xioopen_openssl_listen(
int argc,
const char *argv[], /* the arguments in the address string */
struct opt *opts,
int xioflags, /* is the open meant for reading (0),
writing (1), or both (2) ? */
xiofile_t *xxfd, /* a xio file descriptor structure,
xiofile_t *xxfd, /* a xio file descriptor structure,
already allocated */
groups_t groups, /* the matching address groups... */
int protogrp, /* first transparent integer value from
addr_openssl */
int dummy2, /* second transparent integer value from
addr_openssl */
int dummy3) /* transparent pointer value from
addr_openssl */
const struct addrdesc *addrdesc) /* the above descriptor */
{
struct single *xfd = &xxfd->stream;
struct single *sfd = xfd;
struct single *sfd = &xxfd->stream;
const char *portname;
int protogrp = addrdesc->arg1;
struct opt *opts0 = NULL;
union sockaddr_union us_sa, *us = &us_sa;
socklen_t uslen = sizeof(us_sa);
@ -583,13 +570,14 @@ static int
Error("address with data processing not allowed here");
return STAT_NORETRY;
}
xfd->flags |= XIO_DOESCONVERT;
sfd->flags |= XIO_DOESCONVERT;
if (argc != 2) {
Error1("%s: 1 parameter required", argv[0]);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
xioinit_ip(&pf, xioparms.default_ip);
#if WITH_IP4 && WITH_IP6
switch (xioparms.default_ip) {
case '4': pf = PF_INET; break;
@ -604,8 +592,8 @@ static int
portname = argv[1];
xfd->howtoend = END_SHUTDOWN;
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
sfd->howtoend = END_SHUTDOWN;
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
applyopts(sfd, -1, opts, PH_INIT);
retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert);
@ -618,7 +606,7 @@ static int
applyopts(sfd, -1, opts, PH_EARLY);
result =
_xioopen_openssl_prepare(opts, xfd, true, &opt_ver, opt_cert, &ctx, &use_dtls);
_xioopen_openssl_prepare(opts, sfd, true, &opt_ver, opt_cert, &ctx, &use_dtls);
if (result != STAT_OK) return STAT_NORETRY;
if (use_dtls) {
@ -629,7 +617,7 @@ static int
retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto);
if (_xioopen_ipapp_listen_prepare(opts, &opts0, portname, &pf, ipproto,
xfd->para.socket.ip.ai_flags,
sfd->para.socket.ip.ai_flags,
us, &uslen, socktype)
!= STAT_OK) {
return STAT_NORETRY;
@ -637,12 +625,12 @@ static int
if (pf == 0)
pf = us->soa.sa_family;
xfd->dtype = XIODATA_OPENSSL;
sfd->dtype = XIODATA_OPENSSL;
while (true) { /* loop over failed attempts */
#if WITH_RETRY
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
level = E_INFO;
} else
#endif /* WITH_RETRY */
@ -651,18 +639,18 @@ static int
/* this can fork() for us; it only returns on error or on
successful establishment of connection */
if (ipproto == IPPROTO_TCP) {
result = _xioopen_listen(xfd, xioflags,
result = _xioopen_listen(sfd, xioflags,
(struct sockaddr *)us, uslen,
opts, pf, socktype, ipproto,
#if WITH_RETRY
(xfd->retry||xfd->forever)?E_INFO:E_ERROR
(sfd->retry||sfd->forever)?E_INFO:E_ERROR
#else
E_ERROR
#endif /* WITH_RETRY */
);
#if WITH_UDP
} else {
result = _xioopen_ipdgram_listen(xfd, xioflags,
result = _xioopen_ipdgram_listen(sfd, xioflags,
us, uslen, opts, pf, socktype, ipproto);
#endif /* WITH_UDP */
}
@ -672,13 +660,13 @@ static int
#if WITH_RETRY
case STAT_RETRYLATER:
case STAT_RETRYNOW:
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
if (result == STAT_RETRYLATER) {
Nanosleep(&xfd->intervall, NULL);
Nanosleep(&sfd->intervall, NULL);
}
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
--xfd->retry;
--sfd->retry;
continue;
}
return STAT_NORETRY;
@ -687,19 +675,19 @@ static int
return result;
}
result = _xioopen_openssl_listen(xfd, opt_ver, opt_commonname, ctx, level);
result = _xioopen_openssl_listen(sfd, opt_ver, opt_commonname, ctx, level);
switch (result) {
case STAT_OK: break;
#if WITH_RETRY
case STAT_RETRYLATER:
case STAT_RETRYNOW:
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
if (result == STAT_RETRYLATER) {
Nanosleep(&xfd->intervall, NULL);
Nanosleep(&sfd->intervall, NULL);
}
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
--xfd->retry;
--sfd->retry;
continue;
}
return STAT_NORETRY;
@ -708,7 +696,7 @@ static int
return result;
}
openssl_conn_loginfo(xfd->para.openssl.ssl);
openssl_conn_loginfo(sfd->para.openssl.ssl);
break;
} /* drop out on success */
@ -719,7 +707,7 @@ static int
}
int _xioopen_openssl_listen(struct single *xfd,
int _xioopen_openssl_listen(struct single *sfd,
bool opt_ver,
const char *opt_commonname,
SSL_CTX *ctx,
@ -729,7 +717,7 @@ int _xioopen_openssl_listen(struct single *xfd,
int errint, ret;
/* create an SSL object */
if ((xfd->para.openssl.ssl = sycSSL_new(ctx)) == NULL) {
if ((sfd->para.openssl.ssl = sycSSL_new(ctx)) == NULL) {
if (ERR_peek_error() == 0) Msg(level, "SSL_new() failed");
while (err = ERR_get_error()) {
Msg1(level, "SSL_new(): %s", ERR_error_string(err, NULL));
@ -739,11 +727,11 @@ int _xioopen_openssl_listen(struct single *xfd,
}
/* assign the network connection to the SSL object */
if (sycSSL_set_fd(xfd->para.openssl.ssl, xfd->fd) <= 0) {
if (sycSSL_set_fd(sfd->para.openssl.ssl, sfd->fd) <= 0) {
if (ERR_peek_error() == 0) Msg(level, "SSL_set_fd() failed");
while (err = ERR_get_error()) {
Msg2(level, "SSL_set_fd(, %d): %s",
xfd->fd, ERR_error_string(err, NULL));
sfd->fd, ERR_error_string(err, NULL));
}
}
@ -753,7 +741,7 @@ int _xioopen_openssl_listen(struct single *xfd,
const char *ciphers = NULL;
Debug("available ciphers:");
do {
ciphers = SSL_get_cipher_list(xfd->para.openssl.ssl, i);
ciphers = SSL_get_cipher_list(sfd->para.openssl.ssl, i);
if (ciphers == NULL) break;
Debug2("CIPHERS pri=%d: %s", i, ciphers);
++i;
@ -762,9 +750,9 @@ int _xioopen_openssl_listen(struct single *xfd,
#endif /* WITH_DEBUG */
/* connect via SSL by performing handshake */
if ((ret = sycSSL_accept(xfd->para.openssl.ssl)) <= 0) {
if ((ret = sycSSL_accept(sfd->para.openssl.ssl)) <= 0) {
/*if (ERR_peek_error() == 0) Msg(level, "SSL_accept() failed");*/
errint = SSL_get_error(xfd->para.openssl.ssl, ret);
errint = SSL_get_error(sfd->para.openssl.ssl, ret);
switch (errint) {
case SSL_ERROR_NONE:
Msg(level, "ok"); break;
@ -803,7 +791,7 @@ int _xioopen_openssl_listen(struct single *xfd,
return STAT_RETRYLATER;
}
if (openssl_handle_peer_certificate(xfd, opt_commonname, opt_ver, E_ERROR/*!*/) < 0) {
if (openssl_handle_peer_certificate(sfd, opt_commonname, opt_ver, E_ERROR/*!*/) < 0) {
return STAT_NORETRY;
}
@ -978,7 +966,7 @@ static int _xio_openssl_parse_version(const char *verstring, int vergroups) {
int
_xioopen_openssl_prepare(struct opt *opts,
struct single *xfd,/* a xio file descriptor
struct single *sfd,/* a xio file descriptor
structure, already allocated
*/
bool server, /* SSL client: false */
@ -1004,7 +992,7 @@ int
unsigned long err;
int result;
xfd->dtype = XIODATA_OPENSSL;
sfd->dtype = XIODATA_OPENSSL;
retropt_bool(opts, OPT_OPENSSL_FIPS, &opt_fips);
retropt_string(opts, OPT_OPENSSL_METHOD, &me_str);
@ -1237,35 +1225,35 @@ int
/*ERR_clear_error;*/
return STAT_RETRYLATER;
}
xfd->para.openssl.ctx = ctx;
sfd->para.openssl.ctx = ctx;
*ctxp = ctx;
#if HAVE_SSL_CTX_set_min_proto_version || defined(SSL_CTX_set_min_proto_version)
if (xfd->para.openssl.min_proto_version != NULL) {
if (sfd->para.openssl.min_proto_version != NULL) {
int sslver, rc;
sslver = _xio_openssl_parse_version(xfd->para.openssl.min_proto_version,
sslver = _xio_openssl_parse_version(sfd->para.openssl.min_proto_version,
XIO_OPENSSL_VERSIONGROUP_TLS|XIO_OPENSSL_VERSIONGROUP_DTLS);
if (sslver < 0)
return STAT_NORETRY;
if ((rc = SSL_CTX_set_min_proto_version(ctx, sslver)) <= 0) {
Debug1("version: %ld", SSL_CTX_get_min_proto_version(ctx));
Error3("_xioopen_openssl_prepare(): SSL_CTX_set_min_proto_version(\"%s\"->%d): failed (%d)",
xfd->para.openssl.min_proto_version, sslver, rc);
sfd->para.openssl.min_proto_version, sslver, rc);
return STAT_NORETRY;
}
Debug1("version: %ld", SSL_CTX_get_min_proto_version(ctx));
}
#endif /* HAVE_SSL_set_min_proto_version || defined(SSL_set_min_proto_version) */
#if HAVE_SSL_CTX_set_max_proto_version || defined(SSL_CTX_set_max_proto_version)
if (xfd->para.openssl.max_proto_version != NULL) {
if (sfd->para.openssl.max_proto_version != NULL) {
int sslver;
sslver = _xio_openssl_parse_version(xfd->para.openssl.max_proto_version,
sslver = _xio_openssl_parse_version(sfd->para.openssl.max_proto_version,
XIO_OPENSSL_VERSIONGROUP_TLS|XIO_OPENSSL_VERSIONGROUP_DTLS);
if (sslver < 0)
return STAT_NORETRY;
if (SSL_CTX_set_max_proto_version(ctx, sslver) <= 0) {
Error2("_xioopen_openssl_prepare(): SSL_CTX_set_max_proto_version(\"%s\"->%d): failed",
xfd->para.openssl.max_proto_version, sslver);
sfd->para.openssl.max_proto_version, sslver);
return STAT_NORETRY;
}
}
@ -1793,7 +1781,7 @@ static bool openssl_check_peername(X509_NAME *name, const char *peername) {
/* peername is, with OpenSSL client, the server name, or the value of option
commonname if provided;
With OpenSSL server, it is the value of option commonname */
static int openssl_handle_peer_certificate(struct single *xfd,
static int openssl_handle_peer_certificate(struct single *sfd,
const char *peername,
bool opt_ver, int level) {
X509 *peer_cert;
@ -1802,7 +1790,7 @@ static int openssl_handle_peer_certificate(struct single *xfd,
int extcount, i, ok = 0;
int status;
if ((peer_cert = SSL_get_peer_certificate(xfd->para.openssl.ssl)) == NULL) {
if ((peer_cert = SSL_get_peer_certificate(sfd->para.openssl.ssl)) == NULL) {
if (opt_ver) {
Msg(level, "no peer certificate");
status = STAT_RETRYLATER;
@ -1816,7 +1804,7 @@ static int openssl_handle_peer_certificate(struct single *xfd,
/* verify peer certificate (trust, signature, validity dates) */
if (opt_ver) {
long verify_result;
if ((verify_result = sycSSL_get_verify_result(xfd->para.openssl.ssl)) != X509_V_OK) {
if ((verify_result = sycSSL_get_verify_result(sfd->para.openssl.ssl)) != X509_V_OK) {
const char *message = NULL;
if (verify_result >= 0 &&
(size_t)verify_result <
@ -1912,7 +1900,7 @@ static int openssl_handle_peer_certificate(struct single *xfd,
case 16: /* IPv6 */
inet_ntop(AF_INET6, data, aBuffer, sizeof(aBuffer));
if (peername != NULL) {
xioip6_pton(peername, &ip6bin, xfd->para.socket.ip.ai_flags);
xioip6_pton(peername, &ip6bin, sfd->para.socket.ip.ai_flags);
if (memcmp(data, &ip6bin, sizeof(ip6bin)) == 0) {
Debug2("subjectAltName \"%s\" matches peername \"%s\"",
aBuffer, peername);
@ -1964,15 +1952,15 @@ static int openssl_handle_peer_certificate(struct single *xfd,
return status;
}
static int xioSSL_set_fd(struct single *xfd, int level) {
static int xioSSL_set_fd(struct single *sfd, int level) {
unsigned long err;
/* assign a network connection to the SSL object */
if (sycSSL_set_fd(xfd->para.openssl.ssl, xfd->fd) <= 0) {
if (sycSSL_set_fd(sfd->para.openssl.ssl, sfd->fd) <= 0) {
Msg(level, "SSL_set_fd() failed");
while (err = ERR_get_error()) {
Msg2(level, "SSL_set_fd(, %d): %s",
xfd->fd, ERR_error_string(err, NULL));
sfd->fd, ERR_error_string(err, NULL));
}
return STAT_RETRYLATER;
}
@ -1984,16 +1972,16 @@ static int xioSSL_set_fd(struct single *xfd, int level) {
in case of an error condition, this function check forever and retry
options and ev. sleeps an interval. It returns NORETRY when the caller
should not retry for any reason. */
static int xioSSL_connect(struct single *xfd, const char *opt_commonname,
static int xioSSL_connect(struct single *sfd, const char *opt_commonname,
bool opt_ver, int level) {
char error_string[120];
int errint, status, ret;
unsigned long err;
/* connect via SSL by performing handshake */
if ((ret = sycSSL_connect(xfd->para.openssl.ssl)) <= 0) {
if ((ret = sycSSL_connect(sfd->para.openssl.ssl)) <= 0) {
/*if (ERR_peek_error() == 0) Msg(level, "SSL_connect() failed");*/
errint = SSL_get_error(xfd->para.openssl.ssl, ret);
errint = SSL_get_error(sfd->para.openssl.ssl, ret);
switch (errint) {
case SSL_ERROR_NONE:
/* this is not an error, but I dare not continue for security reasons*/
@ -2030,7 +2018,7 @@ static int xioSSL_connect(struct single *xfd, const char *opt_commonname,
break;
case SSL_ERROR_SSL:
status = openssl_SSL_ERROR_SSL(level, "SSL_connect");
if (openssl_handle_peer_certificate(xfd, opt_commonname, opt_ver, level/*!*/) < 0) {
if (openssl_handle_peer_certificate(sfd, opt_commonname, opt_ver, level/*!*/) < 0) {
return STAT_RETRYLATER;
}
break;

View file

@ -14,7 +14,7 @@
#if WITH_PIPE
static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3);
static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
static int xioopen_fifo_unnamed(xiofile_t *sock, struct opt *opts);
@ -77,7 +77,14 @@ static int xioopen_fifo_unnamed(xiofile_t *sock, struct opt *opts) {
/* open a named or unnamed pipe/fifo */
static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3) {
static int xioopen_fifo(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xfd->stream;
const char *pipename = argv[1];
int rw = (xioflags & XIO_ACCMODE);
@ -96,7 +103,8 @@ static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xiof
}
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1,addrdesc->syntax);
return STAT_NORETRY;
}
if (applyopts_single(sfd, opts, PH_INIT) < 0)

View file

@ -19,7 +19,7 @@ static int _posixmq_unlink(
const char *name,
int level); /* message level on error */
static int xioopen_posixmq(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dirs, int dummy, int dummy3);
static int xioopen_posixmq(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
const struct addrdesc xioaddr_posixmq_bidir = { "POSIXMQ-BIDIRECTIONAL", 1+XIO_RDWR, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY, XIO_RDWR, 0, 0 HELP(":<mqname>") };
const struct addrdesc xioaddr_posixmq_read = { "POSIXMQ-READ", 1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY, XIO_RDONLY, 0, 0 HELP(":<mqname>") };
@ -37,14 +37,13 @@ static int xioopen_posixmq(
struct opt *opts,
int xioflags,
xiofile_t *xfd,
groups_t groups,
int dirs,
int oneshot,
int dummy3)
const struct addrdesc *addrdesc)
{
/* We expect the form: /mqname */
xiosingle_t *sfd = &xfd->stream;
const char *name;
int dirs = addrdesc->arg1;
int oneshot = addrdesc->arg2;
bool opt_unlink_early = false;
int oflag;
bool opt_o_excl = false;
@ -61,8 +60,7 @@ static int xioopen_posixmq(
return STAT_NORETRY;
}
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)",
argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}

View file

@ -312,8 +312,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
if (rw != XIO_WRONLY) {
applyopts_cloexec(rdpip[0], popts);
applyopts(NULL, rdpip[0], popts, PH_FD);
applyopts(NULL, rdpip[1], copts, PH_FD);
applyopts(sfd, rdpip[0], popts, PH_FD);
applyopts(sfd, rdpip[1], copts, PH_FD);
}
if (rw != XIO_RDONLY) {
@ -326,8 +326,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
/* wrpip[1]: write by socat; wrpip[0]: read by child */
if (rw != XIO_RDONLY) {
applyopts_cloexec(wrpip[1], popts);
applyopts(NULL, wrpip[1], popts, PH_FD);
applyopts(NULL, wrpip[0], copts, PH_FD);
applyopts(sfd, wrpip[1], popts, PH_FD);
applyopts(sfd, wrpip[0], copts, PH_FD);
}
if (sfd->howtoend == END_UNSPEC) {
sfd->howtoend = END_CLOSE_KILL;
@ -362,19 +362,19 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
return -1;
}
popts = opts;
applyopts(NULL, sv[0], copts, PH_PASTSOCKET);
applyopts(NULL, sv[1], popts, PH_PASTSOCKET);
applyopts(sfd, sv[0], copts, PH_PASTSOCKET);
applyopts(sfd, sv[1], popts, PH_PASTSOCKET);
applyopts_cloexec(sv[0], copts);
applyopts(NULL, sv[0], copts, PH_FD);
applyopts(NULL, sv[1], popts, PH_FD);
applyopts(sfd, sv[0], copts, PH_FD);
applyopts(sfd, sv[1], popts, PH_FD);
applyopts(NULL, sv[0], copts, PH_PREBIND);
applyopts(NULL, sv[0], copts, PH_BIND);
applyopts(NULL, sv[0], copts, PH_PASTBIND);
applyopts(NULL, sv[1], popts, PH_PREBIND);
applyopts(NULL, sv[1], popts, PH_BIND);
applyopts(NULL, sv[1], popts, PH_PASTBIND);
applyopts(sfd, sv[0], copts, PH_PREBIND);
applyopts(sfd, sv[0], copts, PH_BIND);
applyopts(sfd, sv[0], copts, PH_PASTBIND);
applyopts(sfd, sv[1], popts, PH_PREBIND);
applyopts(sfd, sv[1], popts, PH_BIND);
applyopts(sfd, sv[1], popts, PH_PASTBIND);
if (sfd->howtoend == END_UNSPEC) {
sfd->howtoend = END_SHUTDOWN_KILL;
@ -437,7 +437,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
#endif
/* this for child, was after fork */
applyopts(NULL, ttyfd, copts, PH_FD);
applyopts(sfd, ttyfd, copts, PH_FD);
Info1("opened pseudo terminal %s", tn);
Close(ptyfd);
@ -464,8 +464,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
applyopts_cloexec(ttyfd, copts);
}
applyopts(NULL, ttyfd, copts, PH_LATE);
applyopts(NULL, ttyfd, copts, PH_LATE2);
applyopts(sfd, ttyfd, copts, PH_LATE);
applyopts(sfd, ttyfd, copts, PH_LATE2);
} else
#endif /* HAVE_PTY */
if (usepipes) {
@ -515,10 +515,10 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
/* applyopts_cloexec(fdi, *copts);*/ /* option is already consumed! */
}
applyopts(NULL, fdi, copts, PH_LATE);
applyopts(NULL, fdo, copts, PH_LATE);
applyopts(NULL, fdi, copts, PH_LATE2);
applyopts(NULL, fdo, copts, PH_LATE2);
applyopts(sfd, fdi, copts, PH_LATE);
applyopts(sfd, fdo, copts, PH_LATE);
applyopts(sfd, fdi, copts, PH_LATE2);
applyopts(sfd, fdo, copts, PH_LATE2);
} else { /* socketpair */
Close(sv[0]);
@ -545,8 +545,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
Close(sv[1]);
}
applyopts(NULL, fdi, copts, PH_LATE);
applyopts(NULL, fdi, copts, PH_LATE2);
applyopts(sfd, fdi, copts, PH_LATE);
applyopts(sfd, fdi, copts, PH_LATE2);
}
if (withfork) {
Info("notifying parent that child process is ready");
@ -554,8 +554,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
}
} /* withfork */
else {
applyopts(NULL, -1, copts, PH_LATE);
applyopts(NULL, -1, copts, PH_LATE2);
applyopts(sfd, -1, copts, PH_LATE);
applyopts(sfd, -1, copts, PH_LATE2);
}
_xioopen_setdelayeduser();
if (withstderr) {

View file

@ -20,10 +20,7 @@
#define PROXYPORT "8080"
static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *fd,
groups_t groups, int dummy1, int dummy2,
int dummy3);
static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
const struct optdesc opt_proxyport = { "proxyport", NULL, OPT_PROXYPORT, GROUP_HTTP, PH_LATE, TYPE_STRING, OFUNC_SPEC };
const struct optdesc opt_ignorecr = { "ignorecr", NULL, OPT_IGNORECR, GROUP_HTTP, PH_LATE, TYPE_BOOL, OFUNC_SPEC };
@ -57,15 +54,15 @@ enum {
returns <0 when error occurs
*/
static ssize_t
xioproxy_recvbytes(struct single *xfd, char *buff, size_t buflen, int level) {
xioproxy_recvbytes(struct single *sfd, char *buff, size_t buflen, int level) {
ssize_t result;
do {
/* we need at least buflen bytes... */
result = Read(xfd->fd, buff, buflen);
result = Read(sfd->fd, buff, buflen);
} while (result < 0 && errno == EINTR); /*! EAGAIN? */
if (result < 0) {
Msg4(level, "read(%d, %p, "F_Zu"): %s",
xfd->fd, buff, buflen, strerror(errno));
sfd->fd, buff, buflen, strerror(errno));
return result;
}
if (result == 0) {
@ -78,12 +75,16 @@ static ssize_t
#define BUFLEN 2048
static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd,
groups_t groups, int dummy1, int dummy2,
int dummy3) {
static int xioopen_proxy_connect(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
/* we expect the form: host:host:port */
struct single *xfd = &xxfd->stream;
struct single *sfd = &xxfd->stream;
struct opt *opts0 = NULL;
struct proxyvars struct_proxyvars = { 0 }, *proxyvars = &struct_proxyvars;
/* variables to be filled with address option values */
@ -105,16 +106,17 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
int result;
if (argc != 4) {
Error1("%s: 3 parameters required", argv[0]);
xio_syntax(argv[0], 3, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
proxyname = argv[1];
targetname = argv[2];
targetport = argv[3];
xfd->howtoend = END_SHUTDOWN;
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
applyopts(xfd, 1, opts, PH_INIT);
sfd->howtoend = END_SHUTDOWN;
if (applyopts_single(sfd, opts, PH_INIT) < 0)
return -1;
applyopts(sfd, 1, opts, PH_INIT);
retropt_int(opts, OPT_SO_TYPE, &socktype);
@ -127,7 +129,7 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
}
result = _xioopen_proxy_prepare(proxyvars, opts, targetname, targetport,
xfd->para.socket.ip.ai_flags);
sfd->para.socket.ip.ai_flags);
if (result != STAT_OK)
return result;
@ -142,7 +144,7 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
result =
_xioopen_ipapp_prepare(opts, &opts0, proxyname, proxyport,
&pf, ipproto,
xfd->para.socket.ip.ai_flags,
sfd->para.socket.ip.ai_flags,
&themlist, us, &uslen,
&needbind, &lowport, socktype);
if (result != STAT_OK)
@ -168,14 +170,14 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
Notice4("opening connection to %s:%u via proxy %s:%s",
proxyvars->targetaddr, proxyvars->targetport, proxyname, proxyport);
#if WITH_RETRY
if (xfd->forever || xfd->retry || ai_sorted[i] != NULL) {
if (sfd->forever || sfd->retry || ai_sorted[i] != NULL) {
level = E_INFO;
} else
#endif /* WITH_RETRY */
level = E_ERROR;
result =
_xioopen_connect(xfd,
_xioopen_connect(sfd,
needbind?us:NULL, sizeof(*us),
themp->ai_addr, themp->ai_addrlen,
opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP, lowport, level);
@ -190,10 +192,10 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
#if WITH_RETRY
case STAT_RETRYLATER:
case STAT_RETRYNOW:
if (xfd->forever || xfd->retry) {
--xfd->retry;
if (sfd->forever || sfd->retry) {
--sfd->retry;
if (result == STAT_RETRYLATER)
Nanosleep(&xfd->intervall, NULL);
Nanosleep(&sfd->intervall, NULL);
continue;
}
#endif /* WITH_RETRY */
@ -204,19 +206,19 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
}
}
xiofreeaddrinfo(themlist);
applyopts(xfd, -1, opts, PH_ALL);
applyopts(sfd, -1, opts, PH_ALL);
if ((result = _xio_openlate(xfd, opts)) < 0)
if ((result = _xio_openlate(sfd, opts)) < 0)
return result;
result = _xioopen_proxy_connect(xfd, proxyvars, level);
result = _xioopen_proxy_connect(sfd, proxyvars, level);
switch (result) {
case STAT_OK: break;
#if WITH_RETRY
case STAT_RETRYLATER:
case STAT_RETRYNOW:
if (xfd->forever || xfd->retry--) {
if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL);
if (sfd->forever || sfd->retry--) {
if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL);
continue;
}
#endif /* WITH_RETRY */
@ -232,24 +234,24 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
if (dofork) {
pid_t pid;
int level = E_ERROR;
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
level = E_WARN;
}
while ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
if (xfd->forever || --xfd->retry) {
Nanosleep(&xfd->intervall, NULL); continue;
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
if (sfd->forever || --sfd->retry) {
Nanosleep(&sfd->intervall, NULL); continue;
}
return STAT_RETRYLATER;
}
if (pid == 0) { /* child process */
xfd->forever = false; xfd->retry = 0;
sfd->forever = false; sfd->retry = 0;
break;
}
/* parent process */
Close(xfd->fd);
Nanosleep(&xfd->intervall, NULL);
Close(sfd->fd);
Nanosleep(&sfd->intervall, NULL);
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
continue;
} else
@ -357,7 +359,7 @@ int _xioopen_proxy_prepare(
return STAT_OK;
}
int _xioopen_proxy_connect(struct single *xfd,
int _xioopen_proxy_connect(struct single *sfd,
struct proxyvars *proxyvars,
int level) {
size_t offset;
@ -387,11 +389,11 @@ int _xioopen_proxy_connect(struct single *xfd,
* xiosanitize(request, strlen(request), textbuff) = '\0';
Info1("sending \"%s\"", textbuff);
/* write errors are assumed to always be hard errors, no retry */
if (writefull(xfd->fd, request, strlen(request)) < 0) {
if (writefull(sfd->fd, request, strlen(request)) < 0) {
Msg4(level, "write(%d, %p, "F_Zu"): %s",
xfd->fd, request, strlen(request), strerror(errno));
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
sfd->fd, request, strlen(request), strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
return STAT_RETRYLATER;
}
@ -417,11 +419,11 @@ int _xioopen_proxy_connect(struct single *xfd,
*next = '\0';
Info1("sending \"%s\\r\\n\"", header);
*next++ = '\r'; *next++ = '\n'; *next++ = '\0';
if (writefull(xfd->fd, header, strlen(header)) < 0) {
if (writefull(sfd->fd, header, strlen(header)) < 0) {
Msg4(level, "write(%d, %p, "F_Zu"): %s",
xfd->fd, header, strlen(header), strerror(errno));
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
sfd->fd, header, strlen(header), strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
return STAT_RETRYLATER;
}
@ -430,11 +432,11 @@ int _xioopen_proxy_connect(struct single *xfd,
}
Info("sending \"\\r\\n\"");
if (writefull(xfd->fd, "\r\n", 2) < 0) {
if (writefull(sfd->fd, "\r\n", 2) < 0) {
Msg2(level, "write(%d, \"\\r\\n\", 2): %s",
xfd->fd, strerror(errno));
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
sfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
return STAT_RETRYLATER;
}
@ -450,7 +452,7 @@ int _xioopen_proxy_connect(struct single *xfd,
offset = 0; /* up to where the buffer is filled (relative) */
/*eol;*/ /* points to the first lineterm of the current line */
do {
sresult = xioproxy_recvbytes(xfd, buff+offset, 1, level);
sresult = xioproxy_recvbytes(sfd, buff+offset, 1, level);
if (sresult <= 0) {
state = XIOSTATE_ERROR;
break; /* leave read cycles */

View file

@ -18,7 +18,7 @@
#define MAXPTYNAMELEN 64
static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3);
static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
const struct addrdesc xioaddr_pty = { "PTY", 3, xioopen_pty, GROUP_NAMED|GROUP_FD|GROUP_TERMIOS|GROUP_PTY, 0, 0, 0 HELP("") };
@ -28,7 +28,14 @@ const struct optdesc opt_pty_wait_slave = { "pty-wait-slave", "wait-slave", OPT_
const struct optdesc opt_pty_intervall = { "pty-interval", NULL, OPT_PTY_INTERVALL, GROUP_PTY, PH_EARLY, TYPE_TIMESPEC, OFUNC_SPEC, 0, 0 };
#endif /* HAVE_POLL */
static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3) {
static int xioopen_pty(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
/* we expect the form: filename */
struct single *sfd = &xfd->stream;
int ptyfd = -1, ttyfd = -1;
@ -49,7 +56,8 @@ static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xiofl
struct timespec pollintv = { PTY_INTERVALL };
if (argc != 1) {
Error2("%s: wrong number of parameters (%d instead of 0)", argv[0], argc-1);
xio_syntax(argv[0], 0, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
sfd->howtoend = END_CLOSE;

View file

@ -17,22 +17,10 @@
#include "xio-rawip.h"
static
int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *fd, groups_t groups, int pf,
int dummy2, int dummy3);
static
int xioopen_rawip_datagram(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *fd, groups_t groups, int pf,
int dummy2, int dummy3);
static
int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int pf, int socktype, int dummy3);
static
int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int pf, int socktype, int ipproto);
static int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
static int xioopen_rawip_datagram(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
static int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
static int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
static
int _xioopen_rawip_sendto(const char *hostname, const char *protname,
@ -62,21 +50,25 @@ const struct addrdesc xioaddr_rawip6_recv = { "IP6-RECV", 1+XIO_RDONLY,
/* we expect the form: host:protocol */
/* struct sockaddr_in sa;*/
/* socklen_t salen;*/
static
int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int pf, int dummy2, int dummy3) {
static int xioopen_rawip_sendto(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
int pf = addrdesc->arg1;
int result;
if (argc != 3) {
Error2("%s: wrong number of parameters (%d instead of 2)",
argv[0], argc-1);
xio_syntax(argv[0], 2, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
xioinit_ip(&pf, xioparms.preferred_ip);
if ((result = _xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd,
groups, &pf)) != STAT_OK) {
addrdesc->groups, &pf)) != STAT_OK) {
return result;
}
_xio_openlate(&xxfd->stream, opts);
@ -95,7 +87,7 @@ int _xioopen_rawip_sendto(const char *hostname, const char *protname,
struct opt *opts, int xioflags, xiofile_t *xxfd,
groups_t groups, int *pf) {
char *garbage;
xiosingle_t *xfd = &xxfd->stream;
xiosingle_t *sfd = &xxfd->stream;
union sockaddr_union us;
socklen_t uslen;
int feats = 1; /* option bind supports only address, not port */
@ -114,95 +106,106 @@ int _xioopen_rawip_sendto(const char *hostname, const char *protname,
/*return STAT_NORETRY;*/
}
xfd->howtoend = END_SHUTDOWN;
sfd->howtoend = END_SHUTDOWN;
retropt_int(opts, OPT_PROTOCOL_FAMILY, pf);
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
applyopts(xfd, -1, opts, PH_INIT);
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
applyopts(sfd, -1, opts, PH_INIT);
xfd->salen = sizeof(xfd->peersa);
sfd->salen = sizeof(sfd->peersa);
if ((result =
xioresolve(hostname, NULL, *pf, socktype, ipproto,
&xfd->peersa, &xfd->salen,
xfd->para.socket.ip.ai_flags))
&sfd->peersa, &sfd->salen,
sfd->para.socket.ip.ai_flags))
!= STAT_OK) {
return result;
}
if (*pf == PF_UNSPEC) {
*pf = xfd->peersa.soa.sa_family;
*pf = sfd->peersa.soa.sa_family;
}
uslen = socket_init(*pf, &us);
xfd->dtype = XIODATA_RECVFROM_SKIPIP;
sfd->dtype = XIODATA_RECVFROM_SKIPIP;
if (retropt_bind(opts, *pf, socktype, ipproto, &us.soa, &uslen, feats,
xfd->para.socket.ip.ai_flags)
sfd->para.socket.ip.ai_flags)
!= STAT_NOACTION) {
needbind = true;
}
return
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
opts, xioflags, xfd, groups, *pf, socktype, ipproto, 0);
opts, xioflags, sfd, groups, *pf, socktype, ipproto, 0);
}
/* we expect the form: address:protocol */
static
int xioopen_rawip_datagram(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int pf, int dummy2, int dummy3) {
xiosingle_t *xfd = &xxfd->stream;
static int xioopen_rawip_datagram(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
xiosingle_t *sfd = &xxfd->stream;
int pf = addrdesc->arg1;
char *rangename;
int result;
if (argc != 3) {
Error2("%s: wrong number of parameters (%d instead of 2)",
argv[0], argc-1);
xio_syntax(argv[0], 2, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
xioinit_ip(&pf, xioparms.preferred_ip);
if ((result =
_xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd,
groups, &pf)) != STAT_OK) {
addrdesc->groups, &pf)) != STAT_OK) {
return result;
}
xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
sfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
if (pf == PF_INET) {
xfd->dtype |= XIOREAD_RECV_SKIPIP;
sfd->dtype |= XIOREAD_RECV_SKIPIP;
}
xfd->para.socket.la.soa.sa_family = xfd->peersa.soa.sa_family;
sfd->para.socket.la.soa.sa_family = sfd->peersa.soa.sa_family;
/* 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,
xfd->para.socket.ip.ai_flags)
if (xioparserange(rangename, pf, &sfd->para.socket.range,
sfd->para.socket.ip.ai_flags)
< 0) {
free(rangename);
return STAT_NORETRY;
}
xfd->para.socket.dorange = true;
xfd->dtype |= XIOREAD_RECV_CHECKRANGE;
sfd->para.socket.dorange = true;
sfd->dtype |= XIOREAD_RECV_CHECKRANGE;
free(rangename);
}
#if WITH_LIBWRAP
xio_retropt_tcpwrap(xfd, opts);
xio_retropt_tcpwrap(sfd, opts);
#endif /* WITH_LIBWRAP */
_xio_openlate(xfd, opts);
_xio_openlate(sfd, opts);
return STAT_OK;
}
static
int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int pf, int socktype, int dummy3) {
static int xioopen_rawip_recvfrom(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xfd->stream;
const char *protname = argv[1];
int pf = addrdesc->arg1;
int socktype = addrdesc->arg2;
char *garbage;
union sockaddr_union us;
socklen_t uslen = sizeof(us);
@ -211,8 +214,7 @@ int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts,
int result;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)",
argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
@ -226,7 +228,7 @@ int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts,
protname);
/*return STAT_NORETRY;*/
}
xfd->stream.howtoend = END_NONE;
sfd->howtoend = END_NONE;
retropt_socket_pf(opts, &pf);
if (pf == PF_UNSPEC) {
@ -244,28 +246,34 @@ int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts,
}
if (retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, 1,
xfd->stream.para.socket.ip.ai_flags)
sfd->para.socket.ip.ai_flags)
!= STAT_NOACTION) {
needbind = true;
}
xfd->stream.dtype = XIODATA_RECVFROM_SKIPIP_ONE;
sfd->dtype = XIODATA_RECVFROM_SKIPIP_ONE;
if ((result =
_xioopen_dgram_recvfrom(&xfd->stream, xioflags, needbind?&us.soa:NULL,
_xioopen_dgram_recvfrom(sfd, xioflags, needbind?&us.soa:NULL,
uslen, opts, pf, socktype, ipproto, E_ERROR))
!= STAT_OK) {
return result;
}
_xio_openlate(&xfd->stream, opts);
_xio_openlate(sfd, opts);
return STAT_OK;
}
static
int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int pf, int socktype, int dummy3) {
static int xioopen_rawip_recv(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
const char *protname = argv[1];
int pf = addrdesc->arg1;
int socktype = addrdesc->arg2;
char *garbage;
bool needbind = false;
union sockaddr_union us;
@ -274,8 +282,7 @@ int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts,
int result;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)",
argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}

View file

@ -25,9 +25,7 @@ uses stdin!!
/* length of buffer for dynamic prompt */
#define READLINE_MAXPROMPT 512
static int xioopen_readline(int argc, const char *argv[], struct opt *opts,
int rw, xiofile_t *xfd, groups_t groups,
int dummy1, int dummy2, int dummy3);
static int xioopen_readline(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *xfd, const struct addrdesc *addrdesc);
const struct addrdesc xioaddr_readline = { "READLINE", 3, xioopen_readline, GROUP_FD|GROUP_TERMIOS|GROUP_READLINE, 0, 0, 0 HELP(NULL) };
@ -37,9 +35,14 @@ const struct optdesc opt_prompt = { "prompt", NULL, OPT_PROMPT,
const struct optdesc opt_noprompt = { "noprompt", NULL, OPT_NOPROMPT, GROUP_READLINE, PH_LATE, TYPE_BOOL, OFUNC_SPEC, 0 };
const struct optdesc opt_noecho = { "noecho", NULL, OPT_NOECHO, GROUP_READLINE, PH_LATE, TYPE_STRING, OFUNC_SPEC, 0 };
static int xioopen_readline(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int dummy1, int dummy2, int dummy3) {
static int xioopen_readline(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xfd->stream;
int rw = (xioflags & XIO_ACCMODE);
char msgbuf[256], *cp = msgbuf;
@ -47,7 +50,7 @@ static int xioopen_readline(int argc, const char *argv[], struct opt *opts,
char *noecho = NULL;
if (argc != 1) {
Error1("%s: 0 parameters required", argv[0]);
xio_syntax(argv[0], 0, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}

View file

@ -30,30 +30,12 @@
#include "xio-tcpwrap.h"
static
int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int dummy1, int dummy2, int dummy3);
static
int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int dummy1, int dummy2, int dummy3);
static
int xioopen_socket_sendto(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int dummy1, int dummy2, int dummy3);
static
int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int dummy1, int dummy2, int dummy3);
static
int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int dummy1, int socktype, int dummy3);
static
int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int dummy1, int dummy2, int dummy3);
static int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
static int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
static int xioopen_socket_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
static int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
static int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
static int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
static
int _xioopen_socket_sendto(const char *pfname, const char *type,
@ -68,7 +50,7 @@ xiolog_ancillary_socket(struct single *sfd, struct cmsghdr *cmsg, int *num,
char *envbuff, int envlen,
char *valbuff, int vallen);
static int xiobind(
struct single *xfd,
struct single *sfd,
union sockaddr_union *us,
size_t uslen,
struct opt *opts,
@ -215,10 +197,14 @@ const struct optdesc opt_null_eof = { "null-eof", NULL, OPT_NULL_EOF, GROUP_SOCK
#if WITH_GENERICSOCKET
static
int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int dummy1, int dummy2, int dummy3) {
static int xioopen_socket_connect(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xxfd->stream;
const char *pfname = argv[1];
const char *protname = argv[2];
@ -233,8 +219,7 @@ int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts,
int result;
if (argc != 4) {
Error2("%s: wrong number of parameters (%d instead of 3)",
argv[0], argc-1);
xio_syntax(argv[0], 3, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
@ -297,10 +282,14 @@ int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts,
}
#if WITH_LISTEN
static
int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int dummy1, int dummy2, int dummy3) {
static int xioopen_socket_listen(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xxfd->stream;
const char *pfname = argv[1];
const char *protname = argv[2];
@ -314,8 +303,7 @@ int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts,
int result;
if (argc != 4) {
Error2("%s: wrong number of parameters (%d instead of 3)",
argv[0], argc-1);
xio_syntax(argv[0], 3, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
@ -368,20 +356,23 @@ int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts,
#endif /* WITH_LISTEN */
/* we expect the form: ...:domain:type:protocol:remote-address */
static
int xioopen_socket_sendto(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int dummy1, int dummy2, int dummy3) {
static int xioopen_socket_sendto(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
int result;
if (argc != 5) {
Error2("%s: wrong number of parameters (%d instead of 4)",
argv[0], argc-1);
xio_syntax(argv[0], 4, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
if ((result =
_xioopen_socket_sendto(argv[1], argv[2], argv[3], argv[4],
opts, xioflags, xxfd, groups))
opts, xioflags, xxfd, addrdesc->groups))
!= STAT_OK) {
return result;
}
@ -482,24 +473,28 @@ int _xioopen_socket_sendto(const char *pfname, const char *type,
/* we expect the form: ...:domain:socktype:protocol:local-address */
static
int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int dummy, int summy2, int dummy3) {
struct single *xfd = &xxfd->stream;
int xioopen_socket_recvfrom(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xxfd->stream;
const char *pfname = argv[1];
const char *typename = argv[2];
const char *protname = argv[3];
const char *address = argv[4];
char *garbage;
union sockaddr_union *us = &xfd->para.socket.la;
union sockaddr_union *us = &sfd->para.socket.la;
socklen_t uslen; size_t ussize;
int pf, socktype, proto;
char *rangename;
int result;
if (argc != 5) {
Error2("%s: wrong number of parameters (%d instead of 4)",
argv[0], argc-1);
xio_syntax(argv[0], 4, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
@ -521,7 +516,7 @@ int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts,
retropt_socket_pf(opts, &pf);
retropt_int(opts, OPT_SO_TYPE, &socktype);
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
xfd->howtoend = END_NONE;
sfd->howtoend = END_NONE;
ussize = 0;
if ((result =
@ -537,35 +532,40 @@ int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts,
+ sizeof(us->soa.sa_len);
#endif
;
xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
sfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
if (xioparserange(rangename, 0, &xfd->para.socket.range,
xfd->para.socket.ip.ai_flags)
if (xioparserange(rangename, 0, &sfd->para.socket.range,
sfd->para.socket.ip.ai_flags)
< 0) {
free(rangename);
return STAT_NORETRY;
}
xfd->para.socket.dorange = true;
sfd->para.socket.dorange = true;
free(rangename);
}
if ((result =
_xioopen_dgram_recvfrom(xfd, xioflags, &us->soa, uslen,
_xioopen_dgram_recvfrom(sfd, xioflags, &us->soa, uslen,
opts, pf, socktype, proto, E_ERROR))
!= STAT_OK) {
return result;
}
_xio_openlate(xfd, opts);
_xio_openlate(sfd, opts);
return STAT_OK;
}
/* we expect the form: ...:domain:type:protocol:local-address */
static
int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int dummy1, int dummy2, int dummy3) {
struct single *xfd = &xxfd->stream;
int xioopen_socket_recv(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xxfd->stream;
const char *pfname = argv[1];
const char *typename = argv[2];
const char *protname = argv[3];
@ -578,8 +578,7 @@ int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts,
int result;
if (argc != 5) {
Error2("%s: wrong number of parameters (%d instead of 4)",
argv[0], argc-1);
xio_syntax(argv[0], 4, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
@ -601,7 +600,7 @@ int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts,
retropt_socket_pf(opts, &pf);
retropt_int(opts, OPT_SO_TYPE, &socktype);
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
xfd->howtoend = END_NONE;
sfd->howtoend = END_NONE;
ussize = 0;
if ((result =
@ -617,37 +616,41 @@ int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts,
+sizeof(us.soa.sa_len)
#endif
;
xfd->dtype = XIOREAD_RECV;
xfd->para.socket.la.soa.sa_family = pf;
sfd->dtype = XIOREAD_RECV;
sfd->para.socket.la.soa.sa_family = pf;
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
if (xioparserange(rangename, 0, &xfd->para.socket.range,
xfd->para.socket.ip.ai_flags)
if (xioparserange(rangename, 0, &sfd->para.socket.range,
sfd->para.socket.ip.ai_flags)
< 0) {
free(rangename);
return STAT_NORETRY;
}
xfd->para.socket.dorange = true;
sfd->para.socket.dorange = true;
free(rangename);
}
if ((result =
_xioopen_dgram_recv(xfd, xioflags, &us.soa,
_xioopen_dgram_recv(sfd, xioflags, &us.soa,
uslen, opts, pf, socktype, proto, E_ERROR))
!= STAT_OK) {
return result;
}
_xio_openlate(xfd, opts);
_xio_openlate(sfd, opts);
return STAT_OK;
}
/* we expect the form: ...:domain:type:protocol:remote-address */
static
int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int dummy1, int dummy2, int dummy3) {
xiosingle_t *xfd = &xxfd->stream;
static int xioopen_socket_datagram(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
xiosingle_t *sfd = &xxfd->stream;
const char *pfname = argv[1];
const char *typename = argv[2];
const char *protname = argv[3];
@ -659,8 +662,7 @@ int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts,
int result;
if (argc != 5) {
Error2("%s: wrong number of parameters (%d instead of 4)",
argv[0], argc-1);
xio_syntax(argv[0], 4, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
@ -671,50 +673,50 @@ int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts,
retropt_socket_pf(opts, &pf);
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
xfd->howtoend = END_SHUTDOWN;
sfd->howtoend = END_SHUTDOWN;
xfd->peersa.soa.sa_family = pf;
sfd->peersa.soa.sa_family = pf;
themsize = 0;
if ((result =
dalan(address, (uint8_t *)&xfd->peersa.soa.sa_data, &themsize,
sizeof(xfd->peersa), 'i'))
dalan(address, (uint8_t *)&sfd->peersa.soa.sa_data, &themsize,
sizeof(sfd->peersa), 'i'))
< 0) {
Error1("data too long: \"%s\"", address);
} else if (result > 0) {
Error1("syntax error in \"%s\"", address);
}
xfd->salen = themsize + sizeof(sa_family_t);
sfd->salen = themsize + sizeof(sa_family_t);
#if HAVE_STRUCT_SOCKADDR_SALEN
xfd->peersa.soa.sa_len =
sizeof(xfd->peersa.soa.sa_len) + sizeof(xfd->peersa.soa.sa_family) +
sfd->peersa.soa.sa_len =
sizeof(sfd->peersa.soa.sa_len) + sizeof(sfd->peersa.soa.sa_family) +
themsize;
#endif
if ((result =
_xioopen_socket_sendto(pfname, typename, protname, address,
opts, xioflags, xxfd, groups))
opts, xioflags, xxfd, addrdesc->groups))
!= STAT_OK) {
return result;
}
xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
sfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
xfd->para.socket.la.soa.sa_family = xfd->peersa.soa.sa_family;
sfd->para.socket.la.soa.sa_family = sfd->peersa.soa.sa_family;
/* 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,
xfd->para.socket.ip.ai_flags)
if (xioparserange(rangename, 0, &sfd->para.socket.range,
sfd->para.socket.ip.ai_flags)
< 0) {
free(rangename);
return STAT_NORETRY;
}
xfd->para.socket.dorange = true;
xfd->dtype |= XIOREAD_RECV_CHECKRANGE;
sfd->para.socket.dorange = true;
sfd->dtype |= XIOREAD_RECV_CHECKRANGE;
free(rangename);
}
_xio_openlate(xfd, opts);
_xio_openlate(sfd, opts);
return STAT_OK;
}
@ -943,7 +945,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC
returns 0 on success.
*/
int xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen,
int xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
struct sockaddr *them, size_t themlen,
struct opt *opts, int pf, int socktype, int protocol,
bool alt) {
@ -963,22 +965,22 @@ int xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen,
do { /* loop over retries and forks */
#if WITH_RETRY
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
level = E_INFO;
} else
#endif /* WITH_RETRY */
level = E_ERROR;
result =
_xioopen_connect(xfd, us, uslen, them, themlen, opts,
_xioopen_connect(sfd, us, uslen, them, themlen, opts,
pf, socktype, protocol, alt, level);
switch (result) {
case STAT_OK: break;
#if WITH_RETRY
case STAT_RETRYLATER:
if (xfd->forever || xfd->retry) {
--xfd->retry;
if (sfd->forever || sfd->retry) {
--sfd->retry;
if (result == STAT_RETRYLATER) {
Nanosleep(&xfd->intervall, NULL);
Nanosleep(&sfd->intervall, NULL);
}
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
continue;
@ -997,16 +999,16 @@ int xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen,
if (dofork) {
pid_t pid;
int level = E_ERROR;
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
level = E_WARN; /* most users won't expect a problem here,
so Notice is too weak */
}
while ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
--xfd->retry;
if (xfd->forever || xfd->retry) {
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
--sfd->retry;
if (sfd->forever || sfd->retry) {
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
Nanosleep(&xfd->intervall, NULL); continue;
Nanosleep(&sfd->intervall, NULL); continue;
}
return STAT_RETRYLATER;
}
@ -1016,9 +1018,9 @@ int xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen,
}
/* parent process */
Close(xfd->fd);
Close(sfd->fd);
/* with and without retry */
Nanosleep(&xfd->intervall, NULL);
Nanosleep(&sfd->intervall, NULL);
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
continue; /* with next socket() bind() connect() */
} else
@ -1124,7 +1126,7 @@ int _xioopen_dgram_sendto(/* them is already in xfd->peersa */
OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, cloexec, OPT_RANGE, tcpwrap
EINTR is not handled specially.
*/
int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
int _xioopen_dgram_recvfrom(struct single *sfd, int xioflags,
struct sockaddr *us, socklen_t uslen,
struct opt *opts,
int pf, int socktype, int proto, int level) {
@ -1143,25 +1145,25 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
Error("option fork not allowed here");
return STAT_NORETRY;
}
xfd->flags |= XIO_DOESFORK;
sfd->flags |= XIO_DOESFORK;
}
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY;
if ((xfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) {
if ((sfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) {
return STAT_RETRYLATER;
}
applyopts(xfd, -1, opts, PH_PASTSOCKET);
applyopts(sfd, -1, opts, PH_PASTSOCKET);
applyopts_cloexec(xfd->fd, opts);
applyopts_cloexec(sfd->fd, opts);
if (xiobind(xfd, (union sockaddr_union *)us, uslen,
if (xiobind(sfd, (union sockaddr_union *)us, uslen,
opts, pf, 0, level) < 0) {
return -1;
}
applyopts(xfd, -1, opts, PH_PASTBIND);
applyopts(sfd, -1, opts, PH_PASTBIND);
#if WITH_UNIX
if (pf == AF_UNIX && us != NULL) {
@ -1173,18 +1175,18 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
/* for generic sockets, this has already been retrieved */
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
if (xioparserange(rangename, pf, &xfd->para.socket.range,
xfd->para.socket.ip.ai_flags)
if (xioparserange(rangename, pf, &sfd->para.socket.range,
sfd->para.socket.ip.ai_flags)
< 0) {
free(rangename);
return STAT_NORETRY;
}
free(rangename);
xfd->para.socket.dorange = true;
sfd->para.socket.dorange = true;
}
#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
xio_retropt_tcpwrap(xfd, opts);
xio_retropt_tcpwrap(sfd, opts);
#endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */
if (xioparms.logopt == 'm') {
@ -1215,7 +1217,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
if (drop) {
char *dummy[2];
Recv(xfd->fd, dummy, sizeof(dummy), 0);
Recv(sfd->fd, dummy, sizeof(dummy), 0);
drop = true;
}
@ -1229,7 +1231,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
} else {
Notice1("receiving IP protocol %u", proto);
}
readfd.fd = xfd->fd;
readfd.fd = sfd->fd;
readfd.events = POLLIN;
if (xiopoll(&readfd, 1, NULL) > 0) {
break;
@ -1239,8 +1241,8 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
continue;
}
Msg2(level, "poll({%d,,},,-1): %s", xfd->fd, strerror(errno));
Close(xfd->fd);
Msg2(level, "poll({%d,,},,-1): %s", sfd->fd, strerror(errno));
Close(sfd->fd);
return STAT_RETRYLATER;
} while (true);
@ -1252,7 +1254,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN
msgh.msg_controllen = sizeof(ctrlbuff);
#endif
while ((rc = xiogetancillary(xfd->fd,
while ((rc = xiogetancillary(sfd->fd,
&msgh,
MSG_PEEK
#ifdef MSG_TRUNC
@ -1267,12 +1269,12 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
sockaddr_info(&pa->soa, palen, peername, sizeof(peername))/*,
sockaddr_info(&la->soa, sockname, sizeof(sockname))*/);
xiodopacketinfo(xfd, &msgh, true, true);
xiodopacketinfo(sfd, &msgh, true, true);
if (xiocheckpeer(xfd, pa, la) < 0) {
if (xiocheckpeer(sfd, pa, la) < 0) {
/* drop packet */
char buff[512];
Recv(xfd->fd, buff, sizeof(buff), 0);
Recv(sfd->fd, buff, sizeof(buff), 0);
continue;
}
Info1("permitting packet from %s",
@ -1283,12 +1285,12 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
/*xiosetsockaddrenv("SOCK", la, lalen, proto);*/
xiosetsockaddrenv("PEER", pa, palen, proto);
applyopts(xfd, -1, opts, PH_FD);
applyopts(sfd, -1, opts, PH_FD);
applyopts(xfd, -1, opts, PH_CONNECTED);
applyopts(sfd, -1, opts, PH_CONNECTED);
xfd->peersa = *(union sockaddr_union *)pa;
xfd->salen = palen;
sfd->peersa = *(union sockaddr_union *)pa;
sfd->salen = palen;
if (dofork) {
Info("Generating socketpair that triggers parent when packet has been consumed");
@ -1296,29 +1298,29 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
Error1("socketpair(PF_UNIX, SOCK_STREAM, 0, ...): %s", strerror(errno));
}
if ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
if ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
Close(trigger[0]);
Close(trigger[1]);
Close(xfd->fd);
Close(sfd->fd);
return STAT_RETRYLATER;
}
if (pid == 0) { /* child */
Close(trigger[0]);
xfd->triggerfd = trigger[1];
Fcntl_l(xfd->triggerfd, F_SETFD, FD_CLOEXEC);
sfd->triggerfd = trigger[1];
Fcntl_l(sfd->triggerfd, F_SETFD, FD_CLOEXEC);
#if WITH_RETRY
/* !? */
xfd->retry = 0;
xfd->forever = 0;
sfd->retry = 0;
sfd->forever = 0;
level = E_ERROR;
#endif /* WITH_RETRY */
#if WITH_UNIX
/* with UNIX sockets: only listening parent is allowed to remove
the socket file */
xfd->opt_unlink_close = false;
sfd->opt_unlink_close = false;
#endif /* WITH_UNIX */
break;
@ -1337,7 +1339,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
break;
}
}
if ((result = _xio_openlate(xfd, opts)) != 0)
if ((result = _xio_openlate(sfd, opts)) != 0)
return STAT_NORETRY;
return STAT_OK;
@ -1345,23 +1347,23 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
/* returns STAT_* */
int _xioopen_dgram_recv(struct single *xfd, int xioflags,
int _xioopen_dgram_recv(struct single *sfd, int xioflags,
struct sockaddr *us, socklen_t uslen,
struct opt *opts, int pf, int socktype, int proto,
int level) {
char *rangename;
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY;
if ((xfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) {
if ((sfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) {
return STAT_RETRYLATER;
}
applyopts(xfd, -1, opts, PH_PASTSOCKET);
applyopts(sfd, -1, opts, PH_PASTSOCKET);
applyopts_cloexec(xfd->fd, opts);
applyopts_cloexec(sfd->fd, opts);
if (xiobind(xfd, (union sockaddr_union *)us, uslen, opts, pf, 0, level) < 0) {
if (xiobind(sfd, (union sockaddr_union *)us, uslen, opts, pf, 0, level) < 0) {
return -1;
}
@ -1375,19 +1377,19 @@ int _xioopen_dgram_recv(struct single *xfd, int xioflags,
#if WITH_IP4 /*|| WITH_IP6*/
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
if (xioparserange(rangename, pf, &xfd->para.socket.range,
xfd->para.socket.ip.ai_flags)
if (xioparserange(rangename, pf, &sfd->para.socket.range,
sfd->para.socket.ip.ai_flags)
< 0) {
free(rangename);
return STAT_NORETRY;
}
free(rangename);
xfd->para.socket.dorange = true;
sfd->para.socket.dorange = true;
}
#endif
#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
xio_retropt_tcpwrap(xfd, opts);
xio_retropt_tcpwrap(sfd, opts);
#endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */
if (xioparms.logopt == 'm') {
@ -1599,15 +1601,15 @@ int xiocheckrange(union sockaddr_union *sa, struct xiorange *range) {
return -1;
}
int xiocheckpeer(xiosingle_t *xfd,
int xiocheckpeer(xiosingle_t *sfd,
union sockaddr_union *pa, union sockaddr_union *la) {
char infobuff[256];
int result;
#if WITH_IP4
if (xfd->para.socket.dorange) {
if (sfd->para.socket.dorange) {
if (pa == NULL) { return -1; }
if (xiocheckrange(pa, &xfd->para.socket.range) < 0) {
if (xiocheckrange(pa, &sfd->para.socket.range) < 0) {
char infobuff[256];
Warn1("refusing connection from %s due to range option",
sockaddr_info(&pa->soa, 0,
@ -1621,11 +1623,11 @@ int xiocheckpeer(xiosingle_t *xfd,
#endif /* WITH_IP4 */
#if WITH_TCP || WITH_UDP
if (xfd->para.socket.ip.dosourceport) {
if (sfd->para.socket.ip.dosourceport) {
if (pa == NULL) { return -1; }
#if WITH_IP4
if (pa->soa.sa_family == AF_INET &&
ntohs(((struct sockaddr_in *)pa)->sin_port) != xfd->para.socket.ip.sourceport) {
ntohs(((struct sockaddr_in *)pa)->sin_port) != sfd->para.socket.ip.sourceport) {
Warn1("refusing connection from %s due to wrong sourceport",
sockaddr_info(&pa->soa, 0,
infobuff, sizeof(infobuff)));
@ -1634,7 +1636,7 @@ int xiocheckpeer(xiosingle_t *xfd,
#endif /* WITH_IP4 */
#if WITH_IP6
if (pa->soa.sa_family == AF_INET6 &&
ntohs(((struct sockaddr_in6 *)pa)->sin6_port) != xfd->para.socket.ip.sourceport) {
ntohs(((struct sockaddr_in6 *)pa)->sin6_port) != sfd->para.socket.ip.sourceport) {
Warn1("refusing connection from %s due to wrong sourceport",
sockaddr_info(&pa->soa, 0,
infobuff, sizeof(infobuff)));
@ -1644,7 +1646,7 @@ int xiocheckpeer(xiosingle_t *xfd,
Info1("permitting connection from %s due to sourceport option",
sockaddr_info(&pa->soa, 0,
infobuff, sizeof(infobuff)));
} else if (xfd->para.socket.ip.lowport) {
} else if (sfd->para.socket.ip.lowport) {
if (pa == NULL) { return -1; }
if (pa->soa.sa_family == AF_INET &&
ntohs(((struct sockaddr_in *)pa)->sin_port) >= IPPORT_RESERVED) {
@ -1670,7 +1672,7 @@ int xiocheckpeer(xiosingle_t *xfd,
#endif /* WITH_TCP || WITH_UDP */
#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
result = xio_tcpwrap_check(xfd, la, pa);
result = xio_tcpwrap_check(sfd, la, pa);
if (result < 0) {
char infobuff[256];
Warn1("refusing connection from %s due to tcpwrapper option",
@ -2052,7 +2054,7 @@ xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]) {
}
int xiobind(
struct single *xfd,
struct single *sfd,
union sockaddr_union *us,
size_t uslen,
struct opt *opts,
@ -2068,8 +2070,8 @@ int xiobind(
applyopts_named(us->un.sun_path, opts, PH_PREOPEN);
}
#endif
applyopts(xfd, xfd->fd, opts, PH_PREBIND);
applyopts(xfd, xfd->fd, opts, PH_BIND);
applyopts(sfd, sfd->fd, opts, PH_PREBIND);
applyopts(sfd, sfd->fd, opts, PH_BIND);
#if WITH_TCP || WITH_UDP
if (alt) {
union sockaddr_union sin, *sinp;
@ -2125,13 +2127,13 @@ int xiobind(
i = N = XIO_IPPORT_LOWER + dv.rem;
do { /* loop over lowport bind() attempts */
*port = htons(i);
if (Bind(xfd->fd, &sinp->soa, sizeof(*sinp)) < 0) {
if (Bind(sfd->fd, &sinp->soa, sizeof(*sinp)) < 0) {
Msg4(errno==EADDRINUSE?E_INFO:level,
"bind(%d, {%s}, "F_Zd"): %s", xfd->fd,
"bind(%d, {%s}, "F_Zd"): %s", sfd->fd,
sockaddr_info(&sinp->soa, sizeof(*sinp), infobuff, sizeof(infobuff)),
sizeof(*sinp), strerror(errno));
if (errno != EADDRINUSE) {
Close(xfd->fd);
Close(sfd->fd);
return STAT_RETRYLATER;
}
} else {
@ -2141,7 +2143,7 @@ int xiobind(
if (i == N) {
Msg(level, "no low port available");
/*errno = EADDRINUSE; still assigned */
Close(xfd->fd);
Close(sfd->fd);
return STAT_RETRYLATER;
}
} while (i != N);
@ -2154,11 +2156,11 @@ int xiobind(
applyopts_named(us->un.sun_path, opts, PH_PREOPEN);
}
#endif
if (Bind(xfd->fd, &us->soa, uslen) < 0) {
if (Bind(sfd->fd, &us->soa, uslen) < 0) {
Msg4(level, "bind(%d, {%s}, "F_Zd"): %s",
xfd->fd, sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)),
sfd->fd, sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)),
uslen, strerror(errno));
Close(xfd->fd);
Close(sfd->fd);
return STAT_RETRYLATER;
}
}
@ -2168,7 +2170,7 @@ int xiobind(
}
#endif
applyopts(xfd, -1, opts, PH_PASTBIND);
applyopts(sfd, -1, opts, PH_PASTBIND);
return 0;
}

View file

@ -14,8 +14,7 @@
#if WITH_SOCKETPAIR
static int xioopen_socketpair(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3);
static int xioopen_socketpair(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
const struct addrdesc xioaddr_socketpair = { "SOCKETPAIR", 3, xioopen_socketpair, GROUP_FD|GROUP_SOCKET, 0, 0, 0 HELP(":<filename>") };
@ -27,10 +26,7 @@ static int xioopen_socketpair(
struct opt *opts,
int xioflags,
xiofile_t *xfd,
groups_t groups ,
int dummy1,
int dummy2,
int dummy3)
const struct addrdesc *addrdesc)
{
struct single *sfd = &xfd->stream;
struct opt *opts2;
@ -41,7 +37,8 @@ static int xioopen_socketpair(
int result;
if (argc != 1) {
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
sfd->para.bipipe.socktype = SOCK_DGRAM;

View file

@ -27,10 +27,7 @@ enum {
#define SOCKSPORT "1080"
#define BUFF_LEN (SIZEOF_STRUCT_SOCKS4+512)
static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *fd,
groups_t groups, int dummy1, int dummy2,
int dummy3);
static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
const struct optdesc opt_socksport = { "socksport", NULL, OPT_SOCKSPORT, GROUP_IP_SOCKS4, PH_LATE, TYPE_STRING, OFUNC_SPEC };
const struct optdesc opt_socksuser = { "socksuser", NULL, OPT_SOCKSUSER, GROUP_IP_SOCKS4, PH_LATE, TYPE_NAME, OFUNC_SPEC };
@ -39,12 +36,17 @@ const struct addrdesc xioaddr_socks4_connect = { "SOCKS4", 3, xioopen_socks4_con
const struct addrdesc xioaddr_socks4a_connect = { "SOCKS4A", 3, xioopen_socks4_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS4|GROUP_CHILD|GROUP_RETRY, 1, 0, 0 HELP(":<socks-server>:<host>:<port>") };
static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd,
groups_t groups, int socks4a, int dummy2,
int dummy3) {
static int xioopen_socks4_connect(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
/* we expect the form: host:host:port */
struct single *xfd = &xxfd->stream;
struct single *sfd = &xxfd->stream;
int socks4a = addrdesc->arg1;
struct opt *opts0 = NULL;
const char *sockdname; char *socksport;
const char *targetname, *targetport;
@ -67,16 +69,16 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
int result;
if (argc != 4) {
Error1("%s: 3 parameters required", argv[0]);
xio_syntax(argv[0], 3, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
sockdname = argv[1];
targetname = argv[2];
targetport = argv[3];
xfd->howtoend = END_SHUTDOWN;
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
applyopts(xfd, 1, opts, PH_INIT);
sfd->howtoend = END_SHUTDOWN;
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
applyopts(sfd, 1, opts, PH_INIT);
retropt_int(opts, OPT_SO_TYPE, &socktype);
@ -99,7 +101,7 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
result =
_xioopen_ipapp_prepare(opts, &opts0, sockdname, socksport,
&pf, ipproto,
xfd->para.socket.ip.ai_flags,
sfd->para.socket.ip.ai_flags,
&themlist, us, &uslen,
&needbind, &lowport, socktype);
@ -119,15 +121,16 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
/* we try to resolve the target address _before_ connecting to the socks
server: this avoids unnecessary socks connects and timeouts */
result =
_xioopen_socks4_connect0(xfd, targetname, socks4a, sockhead,
_xioopen_socks4_connect0(sfd, targetname, socks4a, sockhead,
(ssize_t *)&buflen, level);
switch (result) {
case STAT_OK: break;
#if WITH_RETRY
case STAT_RETRYLATER:
case STAT_RETRYNOW:
if (xfd->forever || xfd->retry--) {
if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL);
if (sfd->forever || sfd->retry--) {
if (result == STAT_RETRYLATER)
Nanosleep(&sfd->intervall, NULL);
continue;
}
#endif /* WITH_RETRY */
@ -143,7 +146,7 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
sockaddr_info(themp->ai_addr, themp->ai_addrlen,
infobuff, sizeof(infobuff)));
#if WITH_RETRY
if (xfd->forever || xfd->retry || ai_sorted[i] != NULL) {
if (sfd->forever || sfd->retry || ai_sorted[i] != NULL) {
level = E_INFO;
} else
#endif /* WITH_RETRY */
@ -151,27 +154,25 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
/* this cannot fork because we retrieved fork option above */
result =
_xioopen_connect(xfd,
_xioopen_connect(sfd,
needbind?us:NULL, sizeof(*us),
themp->ai_addr, themp->ai_addrlen,
opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP,
lowport, level);
opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP, lowport, level);
if (result == STAT_OK)
break;
themp = ai_sorted[i++];
if (themp == NULL) {
themp = ai_sorted[i++];
if (themp == NULL)
result = STAT_RETRYLATER;
}
}
switch (result) {
case STAT_OK: break;
#if WITH_RETRY
case STAT_RETRYLATER:
case STAT_RETRYNOW:
if (xfd->forever || xfd->retry) {
--xfd->retry;
if (sfd->forever || sfd->retry) {
--sfd->retry;
if (result == STAT_RETRYLATER)
Nanosleep(&xfd->intervall, NULL);
Nanosleep(&sfd->intervall, NULL);
continue;
}
#endif /* WITH_RETRY */
@ -181,19 +182,19 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
return result;
}
xiofreeaddrinfo(themlist);
applyopts(xfd, -1, opts, PH_ALL);
applyopts(sfd, -1, opts, PH_ALL);
if ((result = _xio_openlate(xfd, opts)) < 0)
if ((result = _xio_openlate(sfd, opts)) < 0)
return result;
result = _xioopen_socks4_connect(xfd, sockhead, buflen, level);
result = _xioopen_socks4_connect(sfd, sockhead, buflen, level);
switch (result) {
case STAT_OK: break;
#if WITH_RETRY
case STAT_RETRYLATER:
case STAT_RETRYNOW:
if (xfd->forever || xfd->retry--) {
if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL);
if (sfd->forever || sfd->retry--) {
if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL);
continue;
}
#endif /* WITH_RETRY */
@ -209,26 +210,27 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
if (dofork) {
pid_t pid;
int level = E_ERROR;
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
level = E_WARN; /* most users won't expect a problem here,
so Notice is too weak */
}
while ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
if (xfd->forever || --xfd->retry) {
Nanosleep(&xfd->intervall, NULL);
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
if (sfd->forever || --sfd->retry) {
Nanosleep(&sfd->intervall, NULL);
continue;
}
return STAT_RETRYLATER;
}
if (pid == 0) { /* child process */
xfd->forever = false; xfd->retry = 0;
sfd->forever = false;
sfd->retry = 0;
break;
}
/* parent process */
Close(xfd->fd);
Nanosleep(&xfd->intervall, NULL);
Close(sfd->fd);
Nanosleep(&sfd->intervall, NULL);
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
continue;
} else
@ -282,7 +284,7 @@ int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **soc
/* called within retry/fork loop, before connect() */
int
_xioopen_socks4_connect0(struct single *xfd,
_xioopen_socks4_connect0(struct single *sfd,
const char *hostname, /* socks target host */
int socks4a,
struct socks4 *sockhead,
@ -298,7 +300,7 @@ int
if ((result = xioresolve(hostname, NULL,
PF_INET, SOCK_STREAM, IPPROTO_TCP,
&sau, &saulen,
xfd->para.socket.ip.ai_flags))
sfd->para.socket.ip.ai_flags))
!= STAT_OK) {
return result; /*! STAT_RETRY? */
}
@ -330,7 +332,7 @@ int
/* perform socks4 client dialog on existing FD.
Called within fork/retry loop, after connect() */
int _xioopen_socks4_connect(struct single *xfd,
int _xioopen_socks4_connect(struct single *sfd,
struct socks4 *sockhead,
size_t headlen,
int level) {
@ -365,11 +367,11 @@ int _xioopen_socks4_connect(struct single *xfd,
}
}
#endif /* WITH_MSGLEVEL <= E_DEBUG */
if (writefull(xfd->fd, sockhead, headlen) < 0) {
if (writefull(sfd->fd, sockhead, headlen) < 0) {
Msg4(level, "write(%d, %p, "F_Zu"): %s",
xfd->fd, sockhead, headlen, strerror(errno));
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
sfd->fd, sockhead, headlen, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
return STAT_RETRYLATER; /* retry complete open cycle */
}
@ -379,20 +381,20 @@ int _xioopen_socks4_connect(struct single *xfd,
while (bytes >= 0) { /* loop over answer chunks until complete or error */
/* receive socks answer */
do {
result = Read(xfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes);
result = Read(sfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes);
} while (result < 0 && errno == EINTR);
if (result < 0) {
Msg4(level, "read(%d, %p, "F_Zu"): %s",
xfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes,
sfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes,
strerror(errno));
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
}
if (result == 0) {
Msg(level, "read(): EOF during read of socks reply, peer might not be a socks4 server");
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
return STAT_RETRYLATER;
}
@ -431,9 +433,9 @@ int _xioopen_socks4_connect(struct single *xfd,
case SOCKS_CD_GRANTED:
/* Notice("socks: connect request succeeded"); */
#if 0
if (Getsockname(xfd->fd, (struct sockaddr *)&us, &uslen) < 0) {
if (Getsockname(sfd->fd, (struct sockaddr *)&us, &uslen) < 0) {
Warn4("getsockname(%d, %p, {%d}): %s",
xfd->fd, &us, uslen, strerror(errno));
sfd->fd, &us, uslen, strerror(errno));
}
Notice1("successfully connected from %s via socks4",
sockaddr_info((struct sockaddr *)&us, infobuff, sizeof(infobuff)));

View file

@ -48,10 +48,7 @@
#define SOCKS5_STATUS_COMMAND_NOT_SUPPORTED 7
#define SOCKS5_STATUS_ADDRESS_TYPE_NOT_SUPPORTED 8
static int xioopen_socks5(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd,
groups_t groups, int dummy1, int dummy2,
int dummy3);
static int xioopen_socks5(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
const struct addrdesc xioaddr_socks5_connect = { "SOCKS5-CONNECT", 1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_CONNECT, 0, 0 HELP(":<socks-server>:<socks-port>:<target-host>:<target-port>") };
@ -92,7 +89,7 @@ static const char * _xioopen_socks5_strerror(uint8_t r)
* send(0x050100) followed by "return read() == 0x0500", but will be easier to
* extend for other auth mode support.
*/
static int _xioopen_socks5_handshake(struct single *xfd, int level)
static int _xioopen_socks5_handshake(struct single *sfd, int level)
{
int result;
ssize_t bytes;
@ -106,8 +103,8 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level)
if (client_hello == NULL) {
Msg2(level, "malloc(%d): %s",
client_hello_size, strerror(errno));
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
/* malloc failed - could succeed later, so retry then */
@ -138,12 +135,12 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level)
}
#endif
if (writefull(xfd->fd, client_hello, client_hello_size) < 0) {
if (writefull(sfd->fd, client_hello, client_hello_size) < 0) {
Msg4(level, "write(%d, %p, %d): %s",
xfd->fd, client_hello, client_hello_size,
sfd->fd, client_hello, client_hello_size,
strerror(errno));
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
free(client_hello);
@ -156,22 +153,22 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level)
Info("waiting for socks5 reply");
while (bytes >= 0) {
do {
result = Read(xfd->fd, server_hello_ptr + bytes,
result = Read(sfd->fd, server_hello_ptr + bytes,
sizeof(struct socks5_server_hello)-bytes);
} while (result < 0 && errno == EINTR);
if (result < 0) {
Msg4(level, "read(%d, %p, "F_Zu"): %s",
xfd->fd, server_hello_ptr + bytes,
sfd->fd, server_hello_ptr + bytes,
sizeof(struct socks5_server_hello)-bytes,
strerror(errno));
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
}
if (result == 0) {
Msg(level, "read(): EOF during read of SOCKS5 server hello, peer might not be a SOCKS5 server");
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd,
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd,
strerror(errno));
}
@ -197,16 +194,16 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level)
if (server_hello.version != SOCKS5_VERSION) {
Msg2(level, "SOCKS5 Server Hello version was %d, not the expected %d, peer might not be a SOCKS5 server",
server_hello.version, SOCKS5_VERSION);
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
return STAT_RETRYLATER;
}
if (server_hello.method == SOCKS5_AUTH_FAIL) {
Msg(level, "SOCKS5 authentication negotiation failed - client & server have no common supported methods");
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
return STAT_RETRYLATER;
}
@ -214,8 +211,8 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level)
if (server_hello.method != SOCKS5_AUTH_NONE) {
Msg1(level, "SOCKS5 server requested unsupported auth method (%d)",
server_hello.method);
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
return STAT_RETRYLATER;
}
@ -303,7 +300,7 @@ static struct socks5_request *_xioopen_socks5_prepare_request(
* Reads a server reply after a request has been sent
*/
static int _xioopen_socks5_read_reply(
struct single *xfd, struct socks5_reply *reply, int level)
struct single *sfd, struct socks5_reply *reply, int level)
{
int result = 0;
int bytes_read = 0;
@ -313,24 +310,24 @@ static int _xioopen_socks5_read_reply(
while (bytes_to_read >= 0) {
Info("reading SOCKS5 reply");
do {
result = Read(xfd->fd,
result = Read(sfd->fd,
((unsigned char *)reply) + bytes_read,
bytes_to_read-bytes_read);
} while (result < 0 && errno == EINTR);
if (result < 0) {
Msg4(level, "read(%d, %p, %d): %s",
xfd->fd, ((unsigned char *)reply) + bytes_read,
sfd->fd, ((unsigned char *)reply) + bytes_read,
bytes_to_read-bytes_read, strerror(errno));
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
return STAT_RETRYLATER;
}
if (result == 0) {
Msg(level, "read(): EOF during read of SOCKS5 reply");
if (Close(xfd->fd) < 0) {
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s",
xfd->fd, strerror(errno));
sfd->fd, strerror(errno));
}
return STAT_RETRYLATER;
}
@ -356,9 +353,9 @@ static int _xioopen_socks5_read_reply(
default:
Msg1(level, "invalid SOCKS5 reply address type (%d)",
reply->address_type);
if (Close(xfd->fd) < 0) {
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s",
xfd->fd, strerror(errno));
sfd->fd, strerror(errno));
}
return STAT_RETRYLATER;
}
@ -388,7 +385,7 @@ static int _xioopen_socks5_read_reply(
* If command is BIND we receive two replies.
*/
static int _xioopen_socks5_request(
struct single *xfd, const char *target_name, const char *target_port,
struct single *sfd, const char *target_name, const char *target_port,
uint8_t socks_command, int level)
{
struct socks5_request *req;
@ -397,8 +394,8 @@ static int _xioopen_socks5_request(
req = _xioopen_socks5_prepare_request(&bytes, target_name, target_port,
socks_command, level);
if (req == NULL) {
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
/* Prepare_request could fail due to malloc, but most likely
@ -420,11 +417,11 @@ static int _xioopen_socks5_request(
}
#endif
if (writefull(xfd->fd, req, bytes) < 0) {
if (writefull(sfd->fd, req, bytes) < 0) {
Msg4(level, "write(%d, %p, %d): %s",
xfd->fd, req, bytes, strerror(errno));
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
sfd->fd, req, bytes, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
free(req);
return STAT_RETRYLATER;
@ -434,14 +431,14 @@ static int _xioopen_socks5_request(
struct socks5_reply *reply = Malloc(SOCKS5_MAX_REPLY_SIZE);
if (reply == NULL) {
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
return STAT_RETRYLATER;
}
result = _xioopen_socks5_read_reply(xfd, reply, level);
result = _xioopen_socks5_read_reply(sfd, reply, level);
if (result != STAT_OK) {
free(reply);
return result;
@ -454,8 +451,8 @@ static int _xioopen_socks5_request(
if (reply->version != SOCKS5_VERSION) {
Msg2(level, "SOCKS5 reply version was %d, not the expected %d, peer might not be a SOCKS5 server",
reply->version, SOCKS5_VERSION);
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
free(reply);
return STAT_RETRYLATER;
@ -466,7 +463,7 @@ static int _xioopen_socks5_request(
Notice("listening on remote host, waiting for connection");
/* TODO: nicer debug output */
/* For BIND, we read two replies */
result = _xioopen_socks5_read_reply(xfd, reply, level);
result = _xioopen_socks5_read_reply(sfd, reply, level);
if (result != STAT_OK) {
free(reply);
return result;
@ -484,8 +481,8 @@ static int _xioopen_socks5_request(
Msg2(level, "SOCKS5 server error %d: %s",
reply->reply,
_xioopen_socks5_strerror(reply->reply));
if (Close(xfd->fd) < 0) {
Info2("close(%d): %s", xfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {
Info2("close(%d): %s", sfd->fd, strerror(errno));
}
free(reply);
return STAT_RETRYLATER;
@ -497,17 +494,21 @@ static int _xioopen_socks5_request(
/* Same function for all socks5-modes, determined by argv[0] */
static int xioopen_socks5(
int argc, const char *argv[], struct opt *opts, int xioflags,
xiofile_t *xxfd, groups_t groups, int socks_command, int dummy2,
int dummy3)
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
int socks_command = addrdesc->arg1;
bool dofork = false;
int socktype = SOCK_STREAM;
int pf = PF_UNSPEC;
int ipproto = IPPROTO_TCP;
int level, result;
struct opt *opts0 = NULL;
struct single *xfd = &xxfd->stream;
struct single *sfd = &xxfd->stream;
const char *socks_server, *target_name, *target_port, *socks_port;
union sockaddr_union us_sa, *us = &us_sa;
socklen_t uslen = sizeof(us_sa);
@ -521,14 +522,7 @@ static int xioopen_socks5(
return STAT_NORETRY;
}
if (argc != 5) {
#if WITH_HELP
Error2("%s: 4 parameters required like %s", argv[0],
socks_command==SOCKS5_COMMAND_CONNECT ?
xioaddr_socks5_connect.syntax :
xioaddr_socks5_listen.syntax);
#else
Error1("%s: 4 parameters required", argv[0]);
#endif
xio_syntax(argv[0], 4, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
@ -537,16 +531,16 @@ static int xioopen_socks5(
target_name = argv[3];
target_port = argv[4];
xfd->howtoend = END_SHUTDOWN;
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
applyopts(xfd, -1, opts, PH_INIT);
sfd->howtoend = END_SHUTDOWN;
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
applyopts(sfd, -1, opts, PH_INIT);
retropt_int(opts, OPT_SO_TYPE, &socktype);
retropt_bool(opts, OPT_FORK, &dofork);
result = _xioopen_ipapp_prepare(opts, &opts0, socks_server, socks_port,
&pf, ipproto,
xfd->para.socket.ip.ai_flags,
sfd->para.socket.ip.ai_flags,
&themlist, us, &uslen,
&needbind, &lowport, socktype);
@ -555,7 +549,7 @@ static int xioopen_socks5(
do {
#if WITH_RETRY
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
level = E_INFO;
} else {
level = E_ERROR;
@ -568,7 +562,7 @@ static int xioopen_socks5(
Notice1("opening connection to %s",
sockaddr_info(themp->ai_addr, themp->ai_addrlen,
infobuff, sizeof(infobuff)));
result = _xioopen_connect(xfd, needbind?us:NULL, sizeof(*us),
result = _xioopen_connect(sfd, needbind?us:NULL, sizeof(*us),
themp->ai_addr, themp->ai_addrlen,
opts, pf?pf:themp->ai_family, socktype,
IPPROTO_TCP, lowport, level);
@ -583,8 +577,8 @@ static int xioopen_socks5(
#if WITH_RETRY
case STAT_RETRYLATER:
case STAT_RETRYNOW:
if (xfd->forever || xfd->retry-- ) {
if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL);
if (sfd->forever || sfd->retry-- ) {
if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL);
continue;
}
#endif
@ -594,24 +588,24 @@ static int xioopen_socks5(
}
}
xiofreeaddrinfo(themlist);
applyopts(xfd, -1, opts, PH_ALL);
applyopts(sfd, -1, opts, PH_ALL);
if ((result = _xio_openlate(xfd, opts)) < 0)
if ((result = _xio_openlate(sfd, opts)) < 0)
return result;
if ((result = _xioopen_socks5_handshake(xfd, level)) != STAT_OK) {
if ((result = _xioopen_socks5_handshake(sfd, level)) != STAT_OK) {
return result;
}
result = _xioopen_socks5_request(xfd, target_name, target_port, socks_command, level);
result = _xioopen_socks5_request(sfd, target_name, target_port, socks_command, level);
switch (result) {
case STAT_OK:
break;
#if WITH_RETRY
case STAT_RETRYLATER:
case STAT_RETRYNOW:
if ( xfd->forever || xfd->retry-- ) {
if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL);
if ( sfd->forever || sfd->retry-- ) {
if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL);
continue;
}
#endif
@ -627,24 +621,24 @@ static int xioopen_socks5(
if (dofork) {
pid_t pid;
int level = E_ERROR;
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
level = E_WARN;
}
while ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
if (xfd->forever || --xfd->retry) {
Nanosleep(&xfd->intervall, NULL);
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
if (sfd->forever || --sfd->retry) {
Nanosleep(&sfd->intervall, NULL);
continue;
}
return STAT_RETRYLATER;
}
if ( pid == 0 ) {
xfd->forever = false;
xfd->retry = 0;
sfd->forever = false;
sfd->retry = 0;
break;
}
Close(xfd->fd);
Nanosleep(&xfd->intervall, NULL);
Close(sfd->fd);
Nanosleep(&sfd->intervall, NULL);
dropopts(opts, PH_ALL);
opts = copyopts(opts0, GROUP_ALL);
continue;

View file

@ -13,8 +13,8 @@
#if WITH_STDIO
static int xioopen_stdio(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3);
static int xioopen_stdfd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int fd, int dummy2, int dummy3);
static int xioopen_stdio(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
static int xioopen_stdfd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
/* we specify all option groups that we can imagine for a FD, becasue the
@ -135,7 +135,14 @@ int xioopen_stdio_bi(xiofile_t *sock) {
/* wrap around unidirectional xioopensingle and xioopen_fd to automatically determine stdin or stdout fd depending on rw.
Do not set FD_CLOEXEC flag. */
static int xioopen_stdio(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3) {
static int xioopen_stdio(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *fd,
const struct addrdesc *addrdesc)
{
int rw = (xioflags&XIO_ACCMODE);
if (argc != 1) {
@ -149,13 +156,21 @@ static int xioopen_stdio(int argc, const char *argv[], struct opt *opts, int xio
Notice2("using %s for %s",
&("stdin\0\0\0stdout"[rw<<3]),
ddirection[rw]);
return xioopen_fd(opts, rw, &fd->stream, rw, dummy2, dummy3);
return xioopen_fd(opts, rw, &fd->stream, rw);
}
/* wrap around unidirectional xioopensingle and xioopen_fd to automatically determine stdin or stdout fd depending on rw.
Do not set FD_CLOEXEC flag. */
static int xioopen_stdfd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int fd, int dummy2, int dummy3) {
static int xioopen_stdfd(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
int rw = (xioflags&XIO_ACCMODE);
int fd = addrdesc->arg1;
if (argc != 1) {
Error2("%s: wrong number of parameters (%d instead of 0)", argv[0], argc-1);
@ -163,6 +178,6 @@ static int xioopen_stdfd(int argc, const char *argv[], struct opt *opts, int xio
Notice2("using %s for %s",
&("stdin\0\0\0stdout\0\0stderr"[fd<<3]),
ddirection[rw]);
return xioopen_fd(opts, rw, &xfd->stream, fd, dummy2, dummy3);
return xioopen_fd(opts, rw, &xfd->stream, fd);
}
#endif /* WITH_STDIO */

View file

@ -13,22 +13,19 @@
#if WITH_SYSTEM
static int xioopen_system(int arg, const char *argv[], struct opt *opts,
int xioflags, /* XIO_RDONLY etc. */
xiofile_t *fd,
groups_t groups,
int dummy1, int dummy2, int dummy3
);
static int xioopen_system(int arg, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
const struct addrdesc xioaddr_system = { "SYSTEM", 3, xioopen_system, GROUP_FD|GROUP_FORK|GROUP_EXEC|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_TERMIOS|GROUP_FIFO|GROUP_PTY|GROUP_PARENT, 1, 0, 0 HELP(":<shell-command>") };
static int xioopen_system(int argc, const char *argv[], struct opt *opts,
int xioflags, /* XIO_RDONLY etc. */
xiofile_t *xfd,
groups_t groups,
int dummy1, int dummy2, int dummy3
) {
static int xioopen_system(
int argc,
const char *argv[],
struct opt *opts,
int xioflags, /* XIO_RDONLY etc. */
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xfd->stream;
int status;
char *path = NULL;
@ -36,7 +33,13 @@ static int xioopen_system(int argc, const char *argv[], struct opt *opts,
int result;
const char *string = argv[1];
status = _xioopen_foxec(xioflags, sfd, groups, &opts, &duptostderr);
if (argc != 2) {
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
status =
_xioopen_foxec(xioflags, sfd, addrdesc->groups, &opts, &duptostderr);
if (status < 0)
return status;
if (status == 0) { /* child */

View file

@ -32,42 +32,44 @@ int allow_severity=10, deny_severity=10;
/* returns 0 if option was found and could be applied
returns 1 if option was not found
returns -1 if option was found but failed */
int xio_retropt_tcpwrap(xiosingle_t *xfd, struct opt *opts) {
int xio_retropt_tcpwrap(
struct single *sfd,
struct opt *opts) {
bool dolibwrap = false;
dolibwrap =
retropt_string(opts, OPT_TCPWRAPPERS,
&xfd->para.socket.ip.libwrapname) >= 0 || dolibwrap;
&sfd->para.socket.ip.libwrapname) >= 0 || dolibwrap;
dolibwrap =
retropt_string(opts, OPT_TCPWRAP_ETC,
&xfd->para.socket.ip.tcpwrap_etc) >= 0 || dolibwrap;
&sfd->para.socket.ip.tcpwrap_etc) >= 0 || dolibwrap;
#if defined(HAVE_HOSTS_ALLOW_TABLE)
dolibwrap =
retropt_string(opts, OPT_TCPWRAP_HOSTS_ALLOW_TABLE,
&xfd->para.socket.ip.hosts_allow_table) >= 0 || dolibwrap;
&sfd->para.socket.ip.hosts_allow_table) >= 0 || dolibwrap;
#endif
#if defined(HAVE_HOSTS_DENY_TABLE)
dolibwrap =
retropt_string(opts, OPT_TCPWRAP_HOSTS_DENY_TABLE,
&xfd->para.socket.ip.hosts_deny_table) >= 0 || dolibwrap;
&sfd->para.socket.ip.hosts_deny_table) >= 0 || dolibwrap;
#endif
if (dolibwrap) {
xfd->para.socket.ip.dolibwrap = true;
if (xfd->para.socket.ip.libwrapname == NULL) {
xfd->para.socket.ip.libwrapname = (char *)diag_get_string('p');
sfd->para.socket.ip.dolibwrap = true;
if (sfd->para.socket.ip.libwrapname == NULL) {
sfd->para.socket.ip.libwrapname = (char *)diag_get_string('p');
}
#if defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE)
if (xfd->para.socket.ip.tcpwrap_etc) {
if (xfd->para.socket.ip.hosts_allow_table == NULL) {
xfd->para.socket.ip.hosts_allow_table =
Malloc(strlen(xfd->para.socket.ip.tcpwrap_etc)+1+11+1);
sprintf(xfd->para.socket.ip.hosts_allow_table, "%s/hosts.allow",
xfd->para.socket.ip.tcpwrap_etc);
if (sfd->para.socket.ip.tcpwrap_etc) {
if (sfd->para.socket.ip.hosts_allow_table == NULL) {
sfd->para.socket.ip.hosts_allow_table =
Malloc(strlen(sfd->para.socket.ip.tcpwrap_etc)+1+11+1);
sprintf(sfd->para.socket.ip.hosts_allow_table, "%s/hosts.allow",
sfd->para.socket.ip.tcpwrap_etc);
}
if (xfd->para.socket.ip.hosts_deny_table == NULL) {
xfd->para.socket.ip.hosts_deny_table =
Malloc(strlen(xfd->para.socket.ip.tcpwrap_etc)+1+10+1);
sprintf(xfd->para.socket.ip.hosts_deny_table, "%s/hosts.deny",
xfd->para.socket.ip.tcpwrap_etc);
if (sfd->para.socket.ip.hosts_deny_table == NULL) {
sfd->para.socket.ip.hosts_deny_table =
Malloc(strlen(sfd->para.socket.ip.tcpwrap_etc)+1+10+1);
sprintf(sfd->para.socket.ip.hosts_deny_table, "%s/hosts.deny",
sfd->para.socket.ip.tcpwrap_etc);
}
}
#endif /* defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE) */
@ -79,8 +81,10 @@ int xio_retropt_tcpwrap(xiosingle_t *xfd, struct opt *opts) {
/* returns -1 if forbidden, 0 if no tcpwrap check, or 1 if explicitely allowed
*/
int xio_tcpwrap_check(xiosingle_t *xfd, union sockaddr_union *us,
union sockaddr_union *them) {
int xio_tcpwrap_check(
struct single *sfd,
union sockaddr_union *us,
union sockaddr_union *them) {
char *save_hosts_allow_table, *save_hosts_deny_table;
struct request_info ri;
#if WITH_IP6
@ -90,25 +94,25 @@ int xio_tcpwrap_check(xiosingle_t *xfd, union sockaddr_union *us,
#endif
int allow;
if (!xfd->para.socket.ip.dolibwrap) {
if (!sfd->para.socket.ip.dolibwrap) {
return 0;
}
if (us == NULL || them == NULL) { return -1; }
#if defined(HAVE_HOSTS_ALLOW_TABLE)
save_hosts_allow_table = hosts_allow_table;
if (xfd->para.socket.ip.hosts_allow_table) {
if (sfd->para.socket.ip.hosts_allow_table) {
Debug1("hosts_allow_table = \"%s\"",
xfd->para.socket.ip.hosts_allow_table);
hosts_allow_table = xfd->para.socket.ip.hosts_allow_table;
sfd->para.socket.ip.hosts_allow_table);
hosts_allow_table = sfd->para.socket.ip.hosts_allow_table;
}
#endif /* defined(HAVE_HOSTS_ALLOW_TABLE) */
#if defined(HAVE_HOSTS_DENY_TABLE)
save_hosts_deny_table = hosts_deny_table;
if (xfd->para.socket.ip.hosts_deny_table) {
if (sfd->para.socket.ip.hosts_deny_table) {
Debug1("hosts_deny_table = \"%s\"",
xfd->para.socket.ip.hosts_deny_table);
hosts_deny_table = xfd->para.socket.ip.hosts_deny_table;
sfd->para.socket.ip.hosts_deny_table);
hosts_deny_table = sfd->para.socket.ip.hosts_deny_table;
}
#endif /* defined(HAVE_HOSTS_DENY_TABLE) */
@ -132,14 +136,14 @@ int xio_tcpwrap_check(xiosingle_t *xfd, union sockaddr_union *us,
Warn1("inet_ntop(): %s", strerror(errno));
}
Debug7("request_init(%p, RQ_FILE, %d, RQ_CLIENT_SIN, {%s:%u}, RQ_SERVER_SIN, {%s:%u}, RQ_DAEMON, \"%s\", 0",
&ri, xfd->fd, clientaddr,
&ri, sfd->fd, clientaddr,
ntohs(((struct sockaddr_in *)them)->sin_port),
serveraddr, ntohs(us->ip4.sin_port),
xfd->para.socket.ip.libwrapname?xfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'));
request_init(&ri, RQ_FILE, xfd->fd,
sfd->para.socket.ip.libwrapname?sfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'));
request_init(&ri, RQ_FILE, sfd->fd,
RQ_CLIENT_SIN, them,
RQ_SERVER_SIN, &us->soa,
RQ_DAEMON, xfd->para.socket.ip.libwrapname?xfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'), 0);
RQ_DAEMON, sfd->para.socket.ip.libwrapname?sfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'), 0);
Debug("request_init() ->");
Debug1("sock_methods(%p)", &ri);

View file

@ -16,7 +16,7 @@
#include "xio-tun.h"
static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, groups_t groups, int dummy1, int dummy2, int dummy3);
static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
/****** TUN options ******/
const struct optdesc opt_tun_device = { "tun-device", NULL, OPT_TUN_DEVICE, GROUP_TUN, PH_OPEN, TYPE_FILENAME, OFUNC_SPEC };
@ -45,7 +45,14 @@ static const struct optname xio_route_options[] = {
} ;
#endif
static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3) {
static int xioopen_tun(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xfd->stream;
char *tundevice = NULL;
char *tunname = NULL, *tuntype = NULL;
@ -61,8 +68,13 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl
int result;
if (argc > 2 || argc < 0) {
#if WITH_HELP
Error3("%s: wrong number of parameters (%d instead of 0 or 1); usage: %s",
argv[0], argc-1, addrdesc->syntax);
#else
Error2("%s: wrong number of parameters (%d instead of 0 or 1)",
argv[0], argc-1);
#endif
}
if (retropt_string(opts, OPT_TUN_DEVICE, &tundevice) != 0) {
@ -74,7 +86,8 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl
namedargv[1] = tundevice;
/* open the tun cloning device */
if ((result = _xioopen_named_early(2, namedargv, xfd, groups, &exists, opts)) < 0) {
if ((result = _xioopen_named_early(2, namedargv, xfd, addrdesc->groups,
&exists, opts, addrdesc->syntax)) < 0) {
return result;
}

189
xio-udp.c
View file

@ -19,22 +19,10 @@
#include "xio-udp.h"
static
int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int pf, int socktype, int ipproto);
static
int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int pf, int socktype, int ipproto);
static
int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int pf, int socktype, int ipproto);
static
int xioopen_udp_recv(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int pf, int socktype, int ipproto);
static int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
static int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
static int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
static int xioopen_udp_recv(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
static
int _xioopen_udp_sendto(const char *hostname, const char *servname,
@ -283,18 +271,25 @@ int _xioopen_ipdgram_listen(struct single *sfd,
}
/* we expect the form: port */
int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd,
groups_t groups, int pf, int ipproto,
int protname) {
int xioopen_ipdgram_listen(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xfd->stream;
const char *portname = argv[1];
int pf = addrdesc->arg1;
int ipproto = addrdesc->arg2;
union sockaddr_union us;
int socktype = SOCK_DGRAM;
socklen_t uslen;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
xioinit_ip(&pf, xioparms.default_ip);
@ -342,21 +337,27 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
opts, pf, socktype, ipproto);
}
static
int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int pf, int socktype, int ipproto) {
static int xioopen_udp_sendto(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
int pf = addrdesc->arg1;
int socktype = addrdesc->arg2;
int ipproto = addrdesc->arg3;
int result;
if (argc != 3) {
Error2("%s: wrong number of parameters (%d instead of 2)",
argv[0], argc-1);
xio_syntax(argv[0], 2, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
retropt_socket_pf(opts, &pf);
if ((result = _xioopen_udp_sendto(argv[1], argv[2], opts, xioflags, xfd,
groups, pf, socktype, ipproto))
addrdesc->groups, pf, socktype, ipproto))
!= STAT_OK) {
return result;
}
@ -375,75 +376,83 @@ int _xioopen_udp_sendto(const char *hostname, const char *servname,
struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int pf, int socktype, int ipproto) {
xiosingle_t *xfd = &xxfd->stream;
struct single *sfd = &xxfd->stream;
union sockaddr_union us;
socklen_t uslen;
int feats = 3; /* option bind supports address and port */
bool needbind = false;
int result;
xfd->howtoend = END_SHUTDOWN;
sfd->howtoend = END_SHUTDOWN;
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
applyopts(xfd, -1, opts, PH_INIT);
/* ...res_opts[] */
if (applyopts_single(sfd, opts, PH_INIT) < 0)
return -1;
applyopts(sfd, -1, opts, PH_INIT);
xfd->salen = sizeof(xfd->peersa);
sfd->salen = sizeof(sfd->peersa);
if ((result =
xioresolve(hostname, servname, pf, socktype, ipproto,
&xfd->peersa, &xfd->salen,
xfd->para.socket.ip.ai_flags))
&sfd->peersa, &sfd->salen,
sfd->para.socket.ip.ai_flags))
!= STAT_OK) {
return result;
}
if (pf == PF_UNSPEC) {
pf = xfd->peersa.soa.sa_family;
pf = sfd->peersa.soa.sa_family;
}
uslen = socket_init(pf, &us);
if (retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, feats,
xfd->para.socket.ip.ai_flags)
sfd->para.socket.ip.ai_flags)
!= STAT_NOACTION) {
needbind = true;
}
if (retropt_ushort(opts, OPT_SOURCEPORT,
&xfd->para.socket.ip.sourceport) >= 0) {
&sfd->para.socket.ip.sourceport) >= 0) {
switch (pf) {
#if WITH_IP4
case PF_INET:
us.ip4.sin_port = htons(xfd->para.socket.ip.sourceport);
us.ip4.sin_port = htons(sfd->para.socket.ip.sourceport);
break;
#endif
#if WITH_IP6
case PF_INET6:
us.ip6.sin6_port = htons(xfd->para.socket.ip.sourceport);
us.ip6.sin6_port = htons(sfd->para.socket.ip.sourceport);
break;
#endif
}
needbind = true;
}
retropt_bool(opts, OPT_LOWPORT, &xfd->para.socket.ip.lowport);
retropt_bool(opts, OPT_LOWPORT, &sfd->para.socket.ip.lowport);
xfd->dtype = XIODATA_RECVFROM;
sfd->dtype = XIODATA_RECVFROM;
return _xioopen_dgram_sendto(needbind?&us:NULL, uslen,
opts, xioflags, xfd, groups,
opts, xioflags, sfd, groups,
pf, socktype, ipproto,
xfd->para.socket.ip.lowport);
sfd->para.socket.ip.lowport);
}
static
int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int pf, int socktype, int ipproto) {
xiosingle_t *xfd = &xxfd->stream;
static int xioopen_udp_datagram(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xxfd->stream;
int pf = addrdesc->arg1;
int socktype = addrdesc->arg2;
int ipproto = addrdesc->arg3;
char *rangename;
char *hostname;
int result;
if (argc != 3) {
Error2("%s: wrong number of parameters (%d instead of 2)",
argv[0], argc-1);
xio_syntax(argv[0], 2, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
@ -453,65 +462,71 @@ int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts,
}
/* only accept packets with correct remote ports */
if (retropt_ushort(opts, OPT_SOURCEPORT, &xfd->para.socket.ip.sourceport)
if (retropt_ushort(opts, OPT_SOURCEPORT, &sfd->para.socket.ip.sourceport)
>= 0) {
xfd->para.socket.ip.dosourceport = true;
xfd->para.socket.ip.sourceport = ntohs(xfd->peersa.ip4.sin_port);
sfd->para.socket.ip.dosourceport = true;
sfd->para.socket.ip.sourceport = ntohs(sfd->peersa.ip4.sin_port);
}
retropt_socket_pf(opts, &pf);
result =
_xioopen_udp_sendto(hostname, argv[2], opts, xioflags, xxfd, groups,
pf, socktype, ipproto);
_xioopen_udp_sendto(hostname, argv[2], opts, xioflags, xxfd,
addrdesc->groups, pf, socktype, ipproto);
free(hostname);
if (result != STAT_OK) {
return result;
}
xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
sfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
xfd->para.socket.la.soa.sa_family = xfd->peersa.soa.sa_family;
sfd->para.socket.la.soa.sa_family = sfd->peersa.soa.sa_family;
/* 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,
xfd->para.socket.ip.ai_flags)
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
if (xioparserange(rangename, pf, &sfd->para.socket.range,
sfd->para.socket.ip.ai_flags)
< 0) {
free(rangename);
return STAT_NORETRY;
}
xfd->para.socket.dorange = true;
xfd->dtype |= XIOREAD_RECV_CHECKRANGE;
sfd->para.socket.dorange = true;
sfd->dtype |= XIOREAD_RECV_CHECKRANGE;
free(rangename);
}
#if WITH_LIBWRAP
xio_retropt_tcpwrap(xfd, opts);
xio_retropt_tcpwrap(sfd, opts);
#endif /* WITH_LIBWRAP */
_xio_openlate(xfd, opts);
_xio_openlate(sfd, opts);
return STAT_OK;
}
static
int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int pf, int socktype, int ipproto) {
static int xioopen_udp_recvfrom(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
struct single *sfd = &xfd->stream;
int pf = addrdesc->arg1;
int socktype = addrdesc->arg2;
int ipproto = addrdesc->arg3;
union sockaddr_union us;
socklen_t uslen = sizeof(us);
int ai_flags2[2];
int result;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)",
argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
xioinit_ip(&pf, xioparms.default_ip);
xfd->stream.howtoend = END_NONE;
sfd->howtoend = END_NONE;
retropt_socket_pf(opts, &pf);
if (pf == PF_UNSPEC) {
#if WITH_IP4 && WITH_IP6
@ -548,7 +563,7 @@ int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts,
socklen_t lalen = sizeof(la);
if (retropt_bind(opts, pf, socktype, ipproto, &la.soa, &lalen, 1,
xfd->stream.para.socket.ip.ai_flags)
sfd->para.socket.ip.ai_flags)
!= STAT_NOACTION) {
switch (pf) {
#if WITH_IP4
@ -561,14 +576,14 @@ int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts,
}
}
if (retropt_ushort(opts, OPT_SOURCEPORT, &xfd->stream.para.socket.ip.sourceport) >= 0) {
xfd->stream.para.socket.ip.dosourceport = true;
if (retropt_ushort(opts, OPT_SOURCEPORT, &sfd->para.socket.ip.sourceport) >= 0) {
sfd->para.socket.ip.dosourceport = true;
}
retropt_bool(opts, OPT_LOWPORT, &xfd->stream.para.socket.ip.lowport);
retropt_bool(opts, OPT_LOWPORT, &sfd->para.socket.ip.lowport);
xfd->stream.dtype = XIODATA_RECVFROM_ONE;
if ((result =
_xioopen_dgram_recvfrom(&xfd->stream, xioflags, &us.soa, uslen,
_xioopen_dgram_recvfrom(sfd, xioflags, &us.soa, uslen,
opts, pf, socktype, ipproto, E_ERROR))
!= STAT_OK) {
return result;
@ -578,10 +593,17 @@ int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts,
}
static
int xioopen_udp_recv(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xfd, groups_t groups,
int pf, int socktype, int ipproto) {
static int xioopen_udp_recv(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xfd,
const struct addrdesc *addrdesc)
{
int pf = addrdesc->arg1;
int socktype = addrdesc->arg2;
int ipproto = addrdesc->arg3;
union sockaddr_union us;
socklen_t uslen = sizeof(us);
char *rangename;
@ -589,8 +611,7 @@ int xioopen_udp_recv(int argc, const char *argv[], struct opt *opts,
int result;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)",
argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}

View file

@ -28,9 +28,6 @@ extern int _xioopen_ipdgram_listen(struct single *sfd,
int xioflags, union sockaddr_union *us, socklen_t uslen,
struct opt *opts, int pf, int socktype, int ipproto);
extern int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
int rw, xiofile_t *fd,
groups_t groups, int af, int ipproto,
int protname);
extern int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *xfd, const struct addrdesc *addrdesc);
#endif /* !defined(__xio_udp_h_included) */

View file

@ -24,16 +24,12 @@
# define ABSTRACT 0
#endif
static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3);
static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3);
static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3);
static int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3);
static
int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int abstract, int dummy2, int dummy3);
static
int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3);
static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
static int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
static int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
/* the first free parameter is 0 for "normal" unix domain sockets, or 1 for
abstract unix sockets (Linux); the second and third free parameter are
@ -115,10 +111,17 @@ xiosetunix(int pf,
}
#if WITH_LISTEN
static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3) {
static int xioopen_unix_listen(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
/* we expect the form: filename */
const char *name;
xiosingle_t *xfd = &xxfd->stream;
xiosingle_t *sfd = &xxfd->stream;
int pf = PF_UNIX;
int socktype = SOCK_STREAM;
int protocol = 0;
@ -127,35 +130,35 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
struct opt *opts0 = NULL;
pid_t pid = Getpid();
bool opt_unlink_early = false;
bool opt_unlink_close = (abstract != 1);
bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1);
int result;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)",
argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
name = argv[1];
xfd->para.socket.un.tight = true;
sfd->para.socket.un.tight = true;
retropt_socket_pf(opts, &pf);
xfd->howtoend = END_SHUTDOWN;
sfd->howtoend = END_SHUTDOWN;
if (!(ABSTRACT && abstract)) {
if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) {
/* 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_CLOSE, &opt_unlink_close);
}
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
applyopts(xfd, -1, opts, PH_INIT);
if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY;
applyopts(sfd, -1, opts, PH_INIT);
applyopts_named(name, opts, PH_EARLY); /* umask! */
applyopts_offset(xfd, opts);
applyopts(xfd, -1, opts, PH_EARLY);
applyopts_offset(sfd, opts);
applyopts(sfd, -1, opts, PH_EARLY);
uslen = xiosetunix(pf, &us, name, abstract, xfd->para.socket.un.tight);
uslen = xiosetunix(pf, &us, name, addrdesc->arg1/*abstract*/,
sfd->para.socket.un.tight);
if (!(ABSTRACT && abstract)) {
if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) {
if (opt_unlink_early) {
xio_unlink(name, E_ERROR);
} else {
@ -166,10 +169,10 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
}
}
if (opt_unlink_close) {
if ((xfd->unlink_close = strdup(name)) == NULL) {
if ((sfd->unlink_close = strdup(name)) == NULL) {
Error1("strdup(\"%s\"): out of memory", name);
}
xfd->opt_unlink_close = true;
sfd->opt_unlink_close = true;
}
/* trying to set user-early, perm-early etc. here is useless because
@ -180,17 +183,17 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
/* this may fork() */
if ((result =
xioopen_listen(xfd, xioflags,
xioopen_listen(sfd, xioflags,
(struct sockaddr *)&us, uslen,
opts, opts0, pf, socktype, protocol))
!= 0)
return result;
if (!(ABSTRACT && abstract)) {
if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) {
if (opt_unlink_close) {
if (pid != Getpid()) {
/* in a child process - do not unlink-close here! */
xfd->opt_unlink_close = false;
sfd->opt_unlink_close = false;
}
}
}
@ -200,10 +203,17 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
#endif /* WITH_LISTEN */
static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3) {
static int xioopen_unix_connect(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
/* we expect the form: filename */
const char *name;
struct single *xfd = &xxfd->stream;
struct single *sfd = &xxfd->stream;
const struct opt *namedopt;
int pf = PF_UNIX;
int socktype = SOCK_STREAM;
@ -211,7 +221,7 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
struct sockaddr_un them, us;
socklen_t themlen, uslen = sizeof(us);
bool needbind = false;
bool opt_unlink_close = (abstract != 1);
bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1);
bool dofork = false;
struct opt *opts0;
char infobuff[256];
@ -219,29 +229,30 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
int result;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)",
argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
name = argv[1];
xfd->para.socket.un.tight = true;
sfd->para.socket.un.tight = true;
retropt_socket_pf(opts, &pf);
xfd->howtoend = END_SHUTDOWN;
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
applyopts(xfd, -1, opts, PH_INIT);
applyopts_offset(xfd, opts);
applyopts(xfd, -1, opts, PH_EARLY);
sfd->howtoend = END_SHUTDOWN;
if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY;
applyopts(sfd, -1, opts, PH_INIT);
applyopts_offset(sfd, opts);
applyopts(sfd, -1, opts, PH_EARLY);
themlen = xiosetunix(pf, &them, name, abstract, xfd->para.socket.un.tight);
themlen = xiosetunix(pf, &them, name, addrdesc->arg1/*abstract*/,
sfd->para.socket.un.tight);
if (!(ABSTRACT && abstract)) {
/* only for non abstract because abstract do not work in file system */
if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) {
/* Only for non abstract because abstract do not work in file system */
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, NULL)
== STAT_OK) {
(addrdesc->arg1/*abstract*/<<1)|sfd->para.socket.un.tight,
sfd->para.socket.ip.ai_flags)
== STAT_OK) {
needbind = true;
}
@ -251,10 +262,10 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
}
if (opt_unlink_close && needbind) {
if ((xfd->unlink_close = strdup(us.sun_path)) == NULL) {
if ((sfd->unlink_close = strdup(us.sun_path)) == NULL) {
Error1("strdup(\"%s\"): out of memory", name);
}
xfd->opt_unlink_close = true;
sfd->opt_unlink_close = true;
}
retropt_bool(opts, OPT_FORK, &dofork);
@ -267,14 +278,14 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
do { /* loop over retries and forks */
#if WITH_RETRY
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
level = E_INFO;
} else
#endif /* WITH_RETRY */
level = E_ERROR;
result =
_xioopen_connect(xfd,
_xioopen_connect(sfd,
needbind?(union sockaddr_union *)&us:NULL, uslen,
(struct sockaddr *)&them, themlen,
opts, pf, socktype, protocol, false, level);
@ -289,10 +300,10 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
case STAT_OK: break;
#if WITH_RETRY
case STAT_RETRYLATER:
if (xfd->forever || xfd->retry) {
--xfd->retry;
if (sfd->forever || sfd->retry) {
--sfd->retry;
if (result == STAT_RETRYLATER) {
Nanosleep(&xfd->intervall, NULL);
Nanosleep(&sfd->intervall, NULL);
}
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
continue;
@ -311,16 +322,16 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
if (dofork) {
pid_t pid;
int level = E_ERROR;
if (xfd->forever || xfd->retry) {
if (sfd->forever || sfd->retry) {
level = E_WARN; /* most users won't expect a problem here,
so Notice is too weak */
}
while ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
--xfd->retry;
if (xfd->forever || xfd->retry) {
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
--sfd->retry;
if (sfd->forever || sfd->retry) {
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
Nanosleep(&xfd->intervall, NULL); continue;
Nanosleep(&sfd->intervall, NULL); continue;
}
return STAT_RETRYLATER;
}
@ -330,9 +341,9 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
}
/* parent process */
Close(xfd->fd);
Close(sfd->fd);
/* with and without retry */
Nanosleep(&xfd->intervall, NULL);
Nanosleep(&sfd->intervall, NULL);
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
continue; /* with next socket() bind() connect() */
} else
@ -342,17 +353,31 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
}
} while (true);
if ((result = _xio_openlate(xfd, opts)) < 0) {
if (opt_unlink_close && needbind) {
if ((sfd->unlink_close = strndup(us.sun_path, sizeof(us.sun_path))) == NULL) {
Error2("strndup(\"%s\", "F_Zu"): out of memory", name, sizeof(us.sun_path));
}
sfd->opt_unlink_close = true;
}
if ((result = _xio_openlate(sfd, opts)) < 0) {
return result;
}
return STAT_OK;
}
static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy, int dummy3) {
static int xioopen_unix_sendto(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
/* we expect the form: filename */
const char *name;
xiosingle_t *xfd = &xxfd->stream;
xiosingle_t *sfd = &xxfd->stream;
const struct opt *namedopt;
int pf = PF_UNIX;
int socktype = SOCK_DGRAM;
@ -360,33 +385,33 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i
union sockaddr_union us;
socklen_t uslen = sizeof(us);
bool needbind = false;
bool opt_unlink_close = (abstract != 1);
bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1);
int result;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)",
argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
name = argv[1];
xfd->para.socket.un.tight = true;
sfd->para.socket.un.tight = true;
retropt_socket_pf(opts, &pf);
xfd->howtoend = END_SHUTDOWN;
applyopts_offset(xfd, opts);
sfd->howtoend = END_SHUTDOWN;
applyopts_offset(sfd, opts);
xfd->salen = xiosetunix(pf, &xfd->peersa.un, name, abstract, xfd->para.socket.un.tight);
sfd->salen = xiosetunix(pf, &sfd->peersa.un, name, addrdesc->arg1/*abstract*/, sfd->para.socket.un.tight);
if (!(ABSTRACT && abstract)) {
if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) {
/* only for non abstract because abstract do not work in file system */
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
}
xfd->dtype = XIODATA_RECVFROM;
sfd->dtype = XIODATA_RECVFROM;
if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen,
(abstract<<1)| xfd->para.socket.un.tight, NULL)
== STAT_OK) {
(addrdesc->arg1/*abstract*/<<1)| sfd->para.socket.un.tight,
sfd->para.socket.ip.ai_flags)
== STAT_OK) {
needbind = true;
}
@ -395,34 +420,39 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i
Error1("Option \"%s\" only with bind option", namedopt->desc->defname);
}
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
applyopts(xfd, -1, opts, PH_INIT);
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
applyopts(sfd, -1, opts, PH_INIT);
result =
_xioopen_dgram_sendto(needbind?(union sockaddr_union *)&us:NULL, uslen,
opts, xioflags, xfd, groups,
opts, xioflags, sfd, addrdesc->groups,
pf, socktype, protocol, 0);
if (result != 0) {
return result;
}
if (opt_unlink_close && needbind) {
if ((xfd->unlink_close = strdup(us.un.sun_path)) == NULL) {
Error1("strdup(\"%s\"): out of memory", name);
if ((sfd->unlink_close = strndup(us.un.sun_path, sizeof(us.un.sun_path))) == NULL) {
Error2("strndup(\"%s\", "F_Zu"): out of memory", name, sizeof(us.un.sun_path));
}
xfd->opt_unlink_close = true;
sfd->opt_unlink_close = true;
}
return STAT_OK;
}
static
int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int abstract, int dummy2, int dummy3) {
int xioopen_unix_recvfrom(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
/* we expect the form: filename */
const char *name;
xiosingle_t *xfd = &xxfd->stream;
xiosingle_t *sfd = &xxfd->stream;
int pf = PF_UNIX;
int socktype = SOCK_DGRAM;
int protocol = 0;
@ -430,40 +460,41 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
socklen_t uslen;
bool needbind = true;
bool opt_unlink_early = false;
bool opt_unlink_close = (abstract != 1);
bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1);
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)",
argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
name = argv[1];
xfd->para.socket.un.tight = true;
sfd->para.socket.un.tight = true;
retropt_socket_pf(opts, &pf);
xfd->howtoend = END_NONE;
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
applyopts(xfd, -1, opts, PH_INIT);
sfd->howtoend = END_NONE;
if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY;
applyopts(sfd, -1, opts, PH_INIT);
applyopts_named(name, opts, PH_EARLY); /* umask! */
applyopts_offset(xfd, opts);
applyopts_offset(sfd, opts);
if (!(ABSTRACT && abstract)) {
if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) {
/* 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_CLOSE, &opt_unlink_close);
}
applyopts(xfd, -1, opts, PH_EARLY);
applyopts(sfd, -1, opts, PH_EARLY);
uslen = xiosetunix(pf, &us, name, abstract, xfd->para.socket.un.tight);
uslen = xiosetunix(pf, &us, name, addrdesc->arg1/*abstract*/,
sfd->para.socket.un.tight);
#if 0
if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen,
(abstract<<1)|xfd->para.socket.un.tight, NULL)
== STAT_OK) {
(addrdesc->arg1/*abstract*/<<1)|sfd->para.socket.un.tight,
sfd->para.socket.ip.ai_flags)) {
== STAT_OK) {
}
#endif
if (!(ABSTRACT && abstract)) {
if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) {
if (opt_unlink_early) {
xio_unlink(name, E_ERROR);
} else {
@ -474,10 +505,10 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
}
}
if (opt_unlink_close) {
if ((xfd->unlink_close = strdup(name)) == NULL) {
if ((sfd->unlink_close = strdup(name)) == NULL) {
Error1("strdup(\"%s\"): out of memory", name);
}
xfd->opt_unlink_close = true;
sfd->opt_unlink_close = true;
}
/* trying to set user-early, perm-early etc. here is useless because
@ -485,66 +516,71 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
}
applyopts_named(name, opts, PH_EARLY); /* umask! */
xfd->para.socket.la.soa.sa_family = pf;
sfd->para.socket.la.soa.sa_family = pf;
xfd->dtype = XIODATA_RECVFROM_ONE;
sfd->dtype = XIODATA_RECVFROM_ONE;
/* this may fork */
return
_xioopen_dgram_recvfrom(xfd, xioflags,
_xioopen_dgram_recvfrom(sfd, xioflags,
needbind?(struct sockaddr *)&us:NULL, uslen,
opts, pf, socktype, protocol, E_ERROR);
}
static
int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int abstract, int dummy2, int dummy3) {
static int xioopen_unix_recv(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
/* we expect the form: filename */
const char *name;
xiosingle_t *xfd = &xxfd->stream;
xiosingle_t *sfd = &xxfd->stream;
int pf = PF_UNIX;
int socktype = SOCK_DGRAM;
int protocol = 0;
union sockaddr_union us;
socklen_t uslen;
bool opt_unlink_early = false;
bool opt_unlink_close = (abstract != 1);
bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1);
int result;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)",
argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
name = argv[1];
xfd->para.socket.un.tight = true;
sfd->para.socket.un.tight = true;
retropt_socket_pf(opts, &pf);
xfd->howtoend = END_SHUTDOWN;
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
applyopts(xfd, -1, opts, PH_INIT);
sfd->howtoend = END_SHUTDOWN;
if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY;
applyopts(sfd, -1, opts, PH_INIT);
applyopts_named(name, opts, PH_EARLY); /* umask! */
applyopts_offset(xfd, opts);
applyopts_offset(sfd, opts);
if (!(ABSTRACT && abstract)) {
if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) {
/* 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_CLOSE, &opt_unlink_close);
}
applyopts(xfd, -1, opts, PH_EARLY);
applyopts(sfd, -1, opts, PH_EARLY);
uslen = xiosetunix(pf, &us.un, name, abstract, xfd->para.socket.un.tight);
uslen = xiosetunix(pf, &us.un, name, addrdesc->arg1/*abstract*/,
sfd->para.socket.un.tight);
#if 0
if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen,
(abstract<<1)|xfd->para.socket.un.tight, NULL)
(addrdesc->arg1/*abstract*/<<1)|sfd->para.socket.un.tight,
sfd->para.socket.ip.ai_flags)
== STAT_OK) {
}
#endif
if (!(ABSTRACT && abstract)) {
if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) {
if (opt_unlink_early) {
xio_unlink(name, E_ERROR);
} else {
@ -555,33 +591,41 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
}
}
if (opt_unlink_close) {
if ((xfd->unlink_close = strdup(name)) == NULL) {
if ((sfd->unlink_close = strdup(name)) == NULL) {
Error1("strdup(\"%s\"): out of memory", name);
}
xfd->opt_unlink_close = true;
sfd->opt_unlink_close = true;
}
}
applyopts_named(name, opts, PH_EARLY); /* umask! */
xfd->para.socket.la.soa.sa_family = pf;
sfd->para.socket.la.soa.sa_family = pf;
xfd->dtype = XIODATA_RECV;
result = _xioopen_dgram_recv(xfd, xioflags, &us.soa, uslen,
sfd->dtype = XIODATA_RECV;
result = _xioopen_dgram_recv(sfd, xioflags, &us.soa, uslen,
opts, pf, socktype, protocol, E_ERROR);
return result;
}
/* generic UNIX socket client, tries connect, SEQPACKET, send(to) */
static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int abstract, int dummy2, int dummy3) {
static int xioopen_unix_client(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
/* we expect the form: filename */
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
return
_xioopen_unix_client(&xxfd->stream, xioflags, groups, abstract, opts,
argv[1]);
_xioopen_unix_client(&xxfd->stream, xioflags, addrdesc->groups,
addrdesc->arg1/*abstract*/, opts, argv[1]);
}
/* establishes communication with an existing UNIX type socket. supports stream
@ -595,7 +639,7 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i
OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_CLOEXEC, OPT_USER, OPT_GROUP, ?OPT_FORK,
*/
int
_xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups,
_xioopen_unix_client(xiosingle_t *sfd, int xioflags, groups_t groups,
int abstract, struct opt *opts, const char *name) {
const struct opt *namedopt;
int pf = PF_UNIX;
@ -608,23 +652,24 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups,
struct opt *opts0;
int result;
xfd->para.socket.un.tight = true;
sfd->para.socket.un.tight = true;
retropt_socket_pf(opts, &pf);
xfd->howtoend = END_SHUTDOWN;
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
applyopts(xfd, -1, opts, PH_INIT);
applyopts_offset(xfd, opts);
sfd->howtoend = END_SHUTDOWN;
if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY;
applyopts(sfd, -1, opts, PH_INIT);
applyopts_offset(sfd, opts);
retropt_int(opts, OPT_SO_TYPE, &socktype);
retropt_int(opts, OPT_SO_PROTOTYPE, &protocol);
applyopts(xfd, -1, opts, PH_EARLY);
applyopts(sfd, -1, opts, PH_EARLY);
themlen = xiosetunix(pf, &them.un, name, abstract, xfd->para.socket.un.tight);
themlen = xiosetunix(pf, &them.un, name, abstract, sfd->para.socket.un.tight);
if (!(ABSTRACT && abstract)) {
/* only for non abstract because abstract do not work in file system */
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, NULL)
(abstract<<1)|sfd->para.socket.un.tight,
sfd->para.socket.ip.ai_flags)
!= STAT_NOACTION) {
needbind = true;
}
@ -635,10 +680,10 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups,
}
if (opt_unlink_close) {
if ((xfd->unlink_close = strdup(name)) == NULL) {
if ((sfd->unlink_close = strdup(name)) == NULL) {
Error1("strdup(\"%s\"): out of memory", name);
}
xfd->opt_unlink_close = true;
sfd->opt_unlink_close = true;
}
/* save options, because we might have to start again */
@ -646,10 +691,10 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups,
/* just a breakable block, helps to avoid goto */
do {
/* xfd->dtype = DATA_STREAM; // is default */
/* sfd->dtype = DATA_STREAM; // is default */
/* this function handles AF_UNIX with EPROTOTYPE specially for us */
if ((result =
_xioopen_connect(xfd,
_xioopen_connect(sfd,
needbind?&us:NULL, uslen,
&them.soa, themlen,
opts, pf, socktype?socktype:SOCK_STREAM, protocol,
@ -663,7 +708,7 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups,
socktype = SOCK_SEQPACKET;
if ((result =
_xioopen_connect(xfd,
_xioopen_connect(sfd,
needbind?&us:NULL, uslen,
(struct sockaddr *)&them, themlen,
opts, pf, SOCK_SEQPACKET, protocol,
@ -675,14 +720,14 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups,
xio_unlink(us.un.sun_path, E_ERROR);
dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0;
xfd->peersa = them;
xfd->salen = sizeof(struct sockaddr_un);
sfd->peersa = them;
sfd->salen = sizeof(struct sockaddr_un);
if ((result =
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
opts, xioflags, xfd, groups,
opts, xioflags, sfd, groups,
pf, SOCK_DGRAM, protocol, 0))
== 0) {
xfd->dtype = XIODATA_RECVFROM;
sfd->dtype = XIODATA_RECVFROM;
break;
}
} while (0);
@ -694,7 +739,7 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups,
return result;
}
if ((result = _xio_openlate(xfd, opts)) < 0) {
if ((result = _xio_openlate(sfd, opts)) < 0) {
return result;
}
return 0;

View file

@ -13,12 +13,8 @@
#include "xio-socket.h"
#include "xio-vsock.h"
static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups, int abstract,
int dummy2, int dummy3);
static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups, int abstract,
int dummy2, int dummy3);
static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
static void xiolog_vsock_cid(void);
@ -45,26 +41,31 @@ static int vsock_addr_init(struct sockaddr_vm *sa, const char *cid_str,
/* Performs a few steps during opening an address of type VSOCK */
static int vsock_init(struct opt *opts, struct single *xfd) {
static int vsock_init(struct opt *opts, struct single *sfd) {
xfd->howtoend = END_SHUTDOWN;
sfd->howtoend = END_SHUTDOWN;
if (applyopts_single(xfd, opts, PH_INIT) < 0)
if (applyopts_single(sfd, opts, PH_INIT) < 0)
return STAT_NORETRY;
applyopts(xfd, -1, opts, PH_INIT);
applyopts(xfd, -1, opts, PH_EARLY);
applyopts(sfd, -1, opts, PH_INIT);
applyopts(sfd, -1, opts, PH_EARLY);
xfd->dtype = XIODATA_STREAM;
sfd->dtype = XIODATA_STREAM;
return STAT_OK;
}
static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups,
int abstract, int dummy2, int dummy3) {
static int xioopen_vsock_connect(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
/* we expect the form :cid:port */
struct single *xfd = &xxfd->stream;
struct single *sfd = &xxfd->stream;
struct sockaddr_vm sa, sa_local;
socklen_t sa_len = sizeof(sa);
bool needbind = false;
@ -74,8 +75,7 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
int ret;
if (argc != 3) {
Error2("%s: wrong number of parameters (%d instead of 2)",
argv[0], argc-1);
xio_syntax(argv[0], 2, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
@ -88,7 +88,7 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
return ret;
}
ret = vsock_init(opts, xfd);
ret = vsock_init(opts, sfd);
if (ret) {
return ret;
}
@ -96,19 +96,20 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
xiolog_vsock_cid();
ret = retropt_bind(opts, pf, socktype, protocol,
(struct sockaddr *)&sa_local, &sa_len, 3, NULL);
(struct sockaddr *)&sa_local, &sa_len, 3,
sfd->para.socket.ip.ai_flags);
if (ret == STAT_NORETRY)
return ret;
if (ret == STAT_OK)
needbind = true;
ret = xioopen_connect(xfd, needbind ? (union sockaddr_union *)&sa_local : NULL,
ret = xioopen_connect(sfd, needbind ? (union sockaddr_union *)&sa_local : NULL,
sa_len, (struct sockaddr *)&sa, sizeof(sa),
opts, pf, socktype, protocol, false);
if (ret)
return ret;
ret = _xio_openlate(xfd, opts);
ret = _xio_openlate(sfd, opts);
if (ret < 0)
return ret;
@ -117,11 +118,16 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
#if WITH_LISTEN
static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts,
int xioflags, xiofile_t *xxfd, groups_t groups, int abstract,
int dummy2, int dummy3) {
static int xioopen_vsock_listen(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
/* we expect the form :port */
struct single *xfd = &xxfd->stream;
struct single *sfd = &xxfd->stream;
struct sockaddr_vm sa, sa_bind;
socklen_t sa_len = sizeof(sa_bind);
struct opt *opts0;
@ -131,8 +137,7 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts,
int ret;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)",
argv[0], argc-1);
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
return STAT_NORETRY;
}
@ -145,7 +150,7 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts,
return ret;
}
ret = vsock_init(opts, xfd);
ret = vsock_init(opts, sfd);
if (ret) {
return ret;
}
@ -153,7 +158,8 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts,
opts0 = copyopts(opts, GROUP_ALL);
ret = retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&sa_bind,
&sa_len, 1, NULL);
&sa_len, 1,
sfd->para.socket.ip.ai_flags);
if (ret == STAT_NORETRY)
return ret;
if (ret == STAT_OK)
@ -162,7 +168,7 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts,
xiolog_vsock_cid();
/* this may fork() */
return xioopen_listen(xfd, xioflags, (struct sockaddr *)&sa, sizeof(sa),
return xioopen_listen(sfd, xioflags, (struct sockaddr *)&sa, sizeof(sa),
opts, opts0, pf, socktype, protocol);
}
#endif /* WITH_LISTEN */

3
xio.h
View file

@ -355,8 +355,7 @@ typedef union bipipe {
struct addrdesc {
const char *defname; /* main (canonical) name of address */
int directions; /* 1..read, 2..write, 3..both */
int (*func)(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, groups_t groups,
int arg1, int arg2, int arg3);
int (*func)(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, const struct addrdesc *addrdesc);
groups_t groups;
int arg1;
int arg2;

View file

@ -218,4 +218,16 @@ int xioopenhelp(FILE *of,
return 0;
}
/* This function may be used by address handling code to log syntax error */
int xiohelp_syntax(
const char *addr,
int expectnum,
int isnum,
const char *syntax)
{
Error4("%s: wrong number of parameters (%d instead of %d): usage: %s",
addr, isnum, expectnum, syntax);
return -1;
}
#endif /* WITH_HELP */

View file

@ -11,4 +11,6 @@ extern int xioopenhelp(FILE *of,
int level /* 0..only addresses, 1..and options */
);
extern int xiohelp_syntax(const char *addr, int expectnum, int isnum, const char *syntax);
#endif /* !defined(__xiohelp_h_included) */

View file

@ -8,11 +8,11 @@
#include "xioopen.h"
#include "xiomodes.h"
#include "xiohelp.h"
#include "nestlex.h"
static xiofile_t *xioallocfd(void);
xiosingle_t hugo;
static xiosingle_t *xioparse_single(const char **addr);
static xiofile_t *xioparse_dual(const char **addr);
static int xioopen_dual(xiofile_t *xfd, int xioflags);
@ -668,8 +668,7 @@ int xioopen_single(xiofile_t *xfd, int xioflags) {
xfd->stream.flags |= (xioflags & XIO_ACCMODE);
result = (*addrdesc->func)(xfd->stream.argc, xfd->stream.argv,
xfd->stream.opts, xioflags, xfd,
addrdesc->groups, addrdesc->arg1,
addrdesc->arg2, addrdesc->arg3);
addrdesc);
#if HAVE_RESOLV_H
if (do_res)
@ -690,3 +689,11 @@ int xioopen_single(xiofile_t *xfd, int xioflags) {
return result;
}
int xio_syntax(
const char *addr,
int expectnum,
int isnum,
const char *syntax)
{
return xiohelp_syntax(addr, expectnum, isnum, syntax);
}

View file

@ -45,6 +45,12 @@ extern const struct optname optionnames[];
extern int xioopen_makedual(xiofile_t *file);
#if WITH_HELP
extern int xio_syntax(const char *addr, int expectnum, int isnum, const char *syntax);
#else
#define xio_syntax(a,e,i,s) Error3("%s: wrong number of parameters (%d instead of %d)", a, i, e);
#endif
#define retropt_2bytes(o,c,r) retropt_ushort(o,c,r)
/* mode_t might be unsigned short or unsigned int or what else? */

View file

@ -151,7 +151,7 @@ bool xioopts_ignoregroups;
#endif
static int applyopt_offset(struct single *xfd, struct opt *opt);
static int applyopt_offset(struct single *sfd, struct opt *opt);
static int applyopt(struct single *sfd, int fd, struct opt *opt);
@ -4080,10 +4080,10 @@ int applyopts_fchown(int fd, struct opt *opts) {
}
/* caller must make sure that option is not yet consumed */
static int applyopt_offset(struct single *xfd, struct opt *opt) {
static int applyopt_offset(struct single *sfd, struct opt *opt) {
unsigned char *ptr;
ptr = (unsigned char *)xfd + opt->desc->major;
ptr = (unsigned char *)sfd + opt->desc->major;
switch (opt->desc->type) {
case TYPE_BOOL:
*(bool *)ptr = opt->value.u_bool; break;
@ -4117,7 +4117,7 @@ static int applyopt_offset(struct single *xfd, struct opt *opt) {
return 0;
}
int applyopts_offset(struct single *xfd, struct opt *opts) {
int applyopts_offset(struct single *sfd, struct opt *opts) {
struct opt *opt;
opt = opts; while (opt->desc != ODESC_END) {
@ -4125,16 +4125,16 @@ int applyopts_offset(struct single *xfd, struct opt *opts) {
opt->desc->func != OFUNC_OFFSET) {
++opt; continue; }
applyopt_offset(xfd, opt);
applyopt_offset(sfd, opt);
opt->desc = ODESC_DONE;
++opt;
}
return 0;
}
/* applies to xfd all OFUNC_EXT options belonging to phase
/* applies to sfd all OFUNC_EXT options belonging to phase
returns -1 if an error occurred */
int applyopts_single(struct single *xfd, struct opt *opts, enum e_phase phase) {
int applyopts_single(struct single *sfd, struct opt *opts, enum e_phase phase) {
struct opt *opt;
int rc = 0;
@ -4145,9 +4145,9 @@ int applyopts_single(struct single *xfd, struct opt *opts, enum e_phase phase) {
if ((opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR) &&
(opt->desc->phase == phase && phase != PH_ALL)) {
if (opt->desc->func < OFUNC_XIO) {
rc = applyopt(NULL, xfd->fd, opt);
rc = applyopt(NULL, sfd->fd, opt);
} else {
rc = applyopt(xfd, -1, opt);
rc = applyopt(sfd, -1, opt);
}
if (rc == 0)
opt->desc = ODESC_DONE;