mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
On bad parameter number print syntax; struct single pointers are now mostly called sfd
This commit is contained in:
parent
5eebca3a5b
commit
50b199dcd9
42 changed files with 1354 additions and 1163 deletions
4
CHANGES
4
CHANGES
|
@ -188,6 +188,8 @@ Coding:
|
||||||
|
|
||||||
Moved multicast related code from xioopts.c to xio-ip.c and xio-ip6.c
|
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:
|
Porting:
|
||||||
Removed Config/ because its contents have not been maintained for many
|
Removed Config/ because its contents have not been maintained for many
|
||||||
years.
|
years.
|
||||||
|
@ -207,6 +209,8 @@ Documentation:
|
||||||
|
|
||||||
Renamed xiogetpacketsrc() to xiogetancillary()
|
Renamed xiogetpacketsrc() to xiogetancillary()
|
||||||
|
|
||||||
|
On bad parameter number now print syntax.
|
||||||
|
|
||||||
####################### V 1.7.4.5 (not released):
|
####################### V 1.7.4.5 (not released):
|
||||||
|
|
||||||
Corrections:
|
Corrections:
|
||||||
|
|
1
test.sh
1
test.sh
|
@ -17097,7 +17097,6 @@ CMD0="$TRACE $SOCAT $opts -T 2 PIPE EXEC:\"$CAT\",pty,setsid,sigint"
|
||||||
printf "test $F_n $TEST... " $N
|
printf "test $F_n $TEST... " $N
|
||||||
$CMD0 >/dev/null 2>"${te}0" &
|
$CMD0 >/dev/null 2>"${te}0" &
|
||||||
pid0=$!
|
pid0=$!
|
||||||
#echo "pid0=$pid0" >&2 #!!!
|
|
||||||
sleep 1
|
sleep 1
|
||||||
kill -INT $pid0
|
kill -INT $pid0
|
||||||
wait
|
wait
|
||||||
|
|
16
xio-creat.c
16
xio-creat.c
|
@ -13,7 +13,7 @@
|
||||||
#include "xio-creat.h"
|
#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 */
|
/*! 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;
|
struct single *sfd = &xxfd->stream;
|
||||||
const char *filename = argv[1];
|
const char *filename = argv[1];
|
||||||
int rw = (xioflags&XIO_ACCMODE);
|
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;
|
int result;
|
||||||
|
|
||||||
/* remove old file, or set user/permissions on old file; parse options */
|
/* 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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
xio-exec.c
23
xio-exec.c
|
@ -13,23 +13,20 @@
|
||||||
|
|
||||||
#if WITH_EXEC
|
#if WITH_EXEC
|
||||||
|
|
||||||
static int xioopen_exec(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_exec(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
int xioflags, /* XIO_RDONLY etc. */
|
|
||||||
xiofile_t *fd,
|
|
||||||
groups_t groups,
|
|
||||||
int dummy1, int dummy2, int dummy3
|
|
||||||
);
|
|
||||||
|
|
||||||
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 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 };
|
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,
|
static int xioopen_exec(
|
||||||
|
int argc,
|
||||||
|
const char *argv[],
|
||||||
|
struct opt *opts,
|
||||||
int xioflags, /* XIO_RDONLY, XIO_MAYCHILD etc. */
|
int xioflags, /* XIO_RDONLY, XIO_MAYCHILD etc. */
|
||||||
xiofile_t *xfd,
|
xiofile_t *xfd,
|
||||||
groups_t groups,
|
const struct addrdesc *addrdesc)
|
||||||
int dummy1, int dummy2, int dummy3
|
{
|
||||||
) {
|
|
||||||
struct single *sfd = &xfd->stream;
|
struct single *sfd = &xfd->stream;
|
||||||
int status;
|
int status;
|
||||||
bool dash = false;
|
bool dash = false;
|
||||||
|
@ -37,12 +34,14 @@ static int xioopen_exec(int argc, const char *argv[], struct opt *opts,
|
||||||
int numleft;
|
int numleft;
|
||||||
|
|
||||||
if (argc != 2) {
|
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);
|
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)
|
if (status < 0)
|
||||||
return status;
|
return status;
|
||||||
if (status == 0) { /* child */
|
if (status == 0) { /* child */
|
||||||
|
|
49
xio-fdnum.c
49
xio-fdnum.c
|
@ -14,8 +14,8 @@
|
||||||
|
|
||||||
#if WITH_FDNUM
|
#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_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, 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, 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>") };
|
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. */
|
/* 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,
|
static int xioopen_fdnum(
|
||||||
int xioflags, xiofile_t *xfd, groups_t groups,
|
int argc,
|
||||||
int dummy1, int dummy2, int dummy3) {
|
const char *argv[],
|
||||||
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
char *a1;
|
char *a1;
|
||||||
int rw = (xioflags&XIO_ACCMODE);
|
int rw = (xioflags&XIO_ACCMODE);
|
||||||
int numfd;
|
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));
|
Warn2("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", numfd, strerror(errno));
|
||||||
}
|
}
|
||||||
Notice2("using file descriptor %d for %s", numfd, ddirection[rw]);
|
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 result;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -61,10 +66,7 @@ static int xioopen_accept_fd(
|
||||||
struct opt *opts,
|
struct opt *opts,
|
||||||
int xioflags,
|
int xioflags,
|
||||||
xiofile_t *xfd,
|
xiofile_t *xfd,
|
||||||
groups_t groups,
|
const struct addrdesc *addrdesc)
|
||||||
int dummy1,
|
|
||||||
int dummy2,
|
|
||||||
int dummy3)
|
|
||||||
{
|
{
|
||||||
char *a1;
|
char *a1;
|
||||||
int rw = (xioflags&XIO_ACCMODE);
|
int rw = (xioflags&XIO_ACCMODE);
|
||||||
|
@ -74,7 +76,8 @@ static int xioopen_accept_fd(
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 2) {
|
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);
|
numfd = strtoul(argv[1], &a1, 0);
|
||||||
|
@ -103,29 +106,29 @@ static int xioopen_accept_fd(
|
||||||
|
|
||||||
#if WITH_FD
|
#if WITH_FD
|
||||||
|
|
||||||
/* retrieve and apply options to a standard file descriptor.
|
/* Retrieves and apply options to a standard file descriptor.
|
||||||
Do not set FD_CLOEXEC flag. */
|
Does not set FD_CLOEXEC flag. */
|
||||||
int xioopen_fd(struct opt *opts, int rw, xiosingle_t *xfd, int numfd, int dummy2, int dummy3) {
|
int xioopen_fd(struct opt *opts, int rw, struct single *sfd, int numfd) {
|
||||||
|
|
||||||
xfd->fd = numfd;
|
sfd->fd = numfd;
|
||||||
xfd->howtoend = END_NONE;
|
sfd->howtoend = END_NONE;
|
||||||
|
|
||||||
#if WITH_TERMIOS
|
#if WITH_TERMIOS
|
||||||
if (Isatty(xfd->fd)) {
|
if (Isatty(sfd->fd)) {
|
||||||
if (Tcgetattr(xfd->fd, &xfd->savetty) < 0) {
|
if (Tcgetattr(sfd->fd, &sfd->savetty) < 0) {
|
||||||
Warn2("cannot query current terminal settings on fd %d: %s",
|
Warn2("cannot query current terminal settings on fd %d: %s",
|
||||||
xfd->fd, strerror(errno));
|
sfd->fd, strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
xfd->ttyvalid = true;
|
sfd->ttyvalid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* WITH_TERMIOS */
|
#endif /* WITH_TERMIOS */
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0)
|
if (applyopts_single(sfd, opts, PH_INIT) < 0)
|
||||||
return -1;
|
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 */
|
#endif /* WITH_FD */
|
||||||
|
|
|
@ -8,6 +8,6 @@
|
||||||
extern const struct addrdesc xioaddr_fd;
|
extern const struct addrdesc xioaddr_fd;
|
||||||
extern const struct addrdesc xioaddr_accept_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) */
|
#endif /* !defined(__xio_fdnum_h_included) */
|
||||||
|
|
16
xio-file.c
16
xio-file.c
|
@ -11,7 +11,7 @@
|
||||||
#include "xio-file.h"
|
#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
|
#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 the filesystem entry already exists, the data is appended
|
||||||
if it does not exist, a file is created and 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];
|
const char *filename = argv[1];
|
||||||
int rw = (xioflags & XIO_ACCMODE);
|
int rw = (xioflags & XIO_ACCMODE);
|
||||||
struct single *sfd = &xfd->stream;
|
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;
|
int result;
|
||||||
|
|
||||||
/* remove old file, or set user/permissions on old file; parse options */
|
/* 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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
xio-gopen.c
17
xio-gopen.c
|
@ -14,12 +14,19 @@
|
||||||
|
|
||||||
#if WITH_GOPEN
|
#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>") };
|
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;
|
struct single *sfd = &xxfd->stream;
|
||||||
const char *filename = argv[1];
|
const char *filename = argv[1];
|
||||||
flags_t openflags = (xioflags & XIO_ACCMODE);
|
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;
|
int result;
|
||||||
|
|
||||||
if ((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;
|
return result;
|
||||||
}
|
}
|
||||||
st_mode = 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);
|
Info1("\"%s\" is a socket, connecting to it", filename);
|
||||||
|
|
||||||
result =
|
result =
|
||||||
_xioopen_unix_client(sfd, xioflags, groups, 0, opts, filename);
|
_xioopen_unix_client(sfd, xioflags, addrdesc->groups, 0, opts, filename);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,7 @@
|
||||||
#include "xio-interface.h"
|
#include "xio-interface.h"
|
||||||
|
|
||||||
|
|
||||||
static
|
static int xioopen_interface(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
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);
|
|
||||||
|
|
||||||
/*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_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 };*/
|
/*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,
|
int _xioopen_interface(const char *ifname,
|
||||||
struct opt *opts, int xioflags, xiofile_t *xxfd,
|
struct opt *opts, int xioflags, xiofile_t *xxfd,
|
||||||
groups_t groups, int pf) {
|
groups_t groups, int pf) {
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
xiosingle_t *sfd = &xxfd->stream;
|
||||||
union sockaddr_union us = {{0}};
|
union sockaddr_union us = {{0}};
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
int socktype = SOCK_RAW;
|
int socktype = SOCK_RAW;
|
||||||
|
@ -77,21 +74,21 @@ int _xioopen_interface(const char *ifname,
|
||||||
ifidx = 0; /* desparate attempt to continue */
|
ifidx = 0; /* desparate attempt to continue */
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->howtoend = END_INTERFACE;
|
sfd->howtoend = END_INTERFACE;
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
|
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
|
|
||||||
/* ...res_opts[] */
|
/* ...res_opts[] */
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(xfd, -1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
xfd->salen = sizeof(xfd->peersa);
|
sfd->salen = sizeof(sfd->peersa);
|
||||||
if (pf == PF_UNSPEC) {
|
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)) {
|
if (retropt_string(opts, OPT_BIND, &bindstring)) {
|
||||||
needbind = true;
|
needbind = true;
|
||||||
|
@ -102,24 +99,24 @@ int _xioopen_interface(const char *ifname,
|
||||||
us.ll.sll_ifindex = ifidx;
|
us.ll.sll_ifindex = ifidx;
|
||||||
uslen = sizeof(sall);
|
uslen = sizeof(sall);
|
||||||
needbind = true;
|
needbind = true;
|
||||||
xfd->peersa = (union sockaddr_union)us;
|
sfd->peersa = (union sockaddr_union)us;
|
||||||
|
|
||||||
rc =
|
rc =
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
_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)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
strncpy(xfd->para.interface.name, ifname, IFNAMSIZ);
|
strncpy(sfd->para.interface.name, ifname, IFNAMSIZ);
|
||||||
_xiointerface_get_iff(xfd->fd, ifname, &xfd->para.interface.save_iff);
|
_xiointerface_get_iff(sfd->fd, ifname, &sfd->para.interface.save_iff);
|
||||||
_xiointerface_apply_iff(xfd->fd, ifname, xfd->para.interface.iff_opts);
|
_xiointerface_apply_iff(sfd->fd, ifname, sfd->para.interface.iff_opts);
|
||||||
|
|
||||||
#ifdef PACKET_IGNORE_OUTGOING
|
#ifdef PACKET_IGNORE_OUTGOING
|
||||||
/* Raw socket might also provide packets that are outbound - we are not
|
/* Raw socket might also provide packets that are outbound - we are not
|
||||||
interested in these and disable this "feature" in kernel if possible */
|
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",
|
Warn2("setsockopt(%d, SOL_PACKET, PACKET_IGNORE_OUTGOING, {1}): %s",
|
||||||
xfd->fd, strerror(errno));
|
sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
#endif /*defined(PACKET_IGNORE_OUTGOING) */
|
#endif /*defined(PACKET_IGNORE_OUTGOING) */
|
||||||
|
|
||||||
|
@ -144,32 +141,37 @@ int _interface_setsockopt_auxdata(int fd, int auxdata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int xioopen_interface(int argc, const char *argv[], struct opt *opts,
|
int xioopen_interface(
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
int argc,
|
||||||
int pf, int dummy2, int dummy3) {
|
const char *argv[],
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
|
xiosingle_t *sfd = &xxfd->stream;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result =
|
if ((result =
|
||||||
_xioopen_interface(argv[1], opts, xioflags, xxfd, groups, pf))
|
_xioopen_interface(argv[1], opts, xioflags, xxfd, addrdesc->groups,
|
||||||
|
addrdesc->arg1))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
|
sfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
|
||||||
if (pf == PF_INET) {
|
if (addrdesc->arg1 == 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;
|
||||||
|
|
||||||
_xio_openlate(xfd, opts);
|
_xio_openlate(sfd, opts);
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
44
xio-ip.c
44
xio-ip.c
|
@ -731,7 +731,7 @@ int xiotype_ip_add_membership(
|
||||||
|
|
||||||
#if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)
|
#if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN)
|
||||||
int xioapply_ip_add_membership(
|
int xioapply_ip_add_membership(
|
||||||
xiosingle_t *xfd,
|
struct single *sfd,
|
||||||
struct opt *opt)
|
struct opt *opt)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
|
@ -754,9 +754,9 @@ mc:addr
|
||||||
/* First parameter is always multicast address */
|
/* First parameter is always multicast address */
|
||||||
/*! result */
|
/*! result */
|
||||||
xioresolve(opt->value.u_string/*multiaddr*/, NULL,
|
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,
|
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;
|
ip4_mreqn.mreq.imr_multiaddr = sockaddr1.ip4.sin_addr;
|
||||||
if (0) {
|
if (0) {
|
||||||
; /* for canonical reasons */
|
; /* for canonical reasons */
|
||||||
|
@ -765,9 +765,9 @@ mc:addr
|
||||||
/* three parameters */
|
/* three parameters */
|
||||||
/* second parameter is interface address */
|
/* second parameter is interface address */
|
||||||
xioresolve(opt->value2.u_string/*param2*/, NULL,
|
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,
|
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;
|
ip4_mreqn.mreq.imr_interface = sockaddr2.ip4.sin_addr;
|
||||||
/* third parameter is interface */
|
/* third parameter is interface */
|
||||||
if (ifindex(opt->value3.u_string/*ifindex*/,
|
if (ifindex(opt->value3.u_string/*ifindex*/,
|
||||||
|
@ -793,10 +793,10 @@ mc:addr
|
||||||
} else {
|
} else {
|
||||||
/*! result */
|
/*! result */
|
||||||
xioresolve(opt->value2.u_string/*param2*/, NULL,
|
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,
|
SOCK_DGRAM, IPPROTO_IP,
|
||||||
&sockaddr2, &socklen2,
|
&sockaddr2, &socklen2,
|
||||||
xfd->para.socket.ip.ai_flags);
|
sfd->para.socket.ip.ai_flags);
|
||||||
ip4_mreqn.mreq.imr_interface = sockaddr2.ip4.sin_addr;
|
ip4_mreqn.mreq.imr_interface = sockaddr2.ip4.sin_addr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -804,18 +804,18 @@ mc:addr
|
||||||
#if LATER
|
#if LATER
|
||||||
if (0) {
|
if (0) {
|
||||||
; /* for canonical reasons */
|
; /* for canonical reasons */
|
||||||
} else if (xfd->para.socket.la.soa.sa_family == PF_INET) {
|
} else if (sfd->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_INET6) {
|
||||||
ip6_mreqn.mreq.imr_multiaddr = sockaddr1.ip6.sin6_addr;
|
ip6_mreqn.mreq.imr_multiaddr = sockaddr1.ip6.sin6_addr;
|
||||||
ip6_mreqn.mreq.imr_interface = sockaddr2.ip6.sin6_addr;
|
ip6_mreqn.mreq.imr_interface = sockaddr2.ip6.sin6_addr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_STRUCT_IP_MREQN
|
#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) {
|
&ip4_mreqn.mreqn, sizeof(ip4_mreqn.mreqn)) < 0) {
|
||||||
Error8("setsockopt(%d, %d, %d, {0x%08x,0x%08x,%d}, "F_Zu"): %s",
|
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_multiaddr.s_addr,
|
||||||
ip4_mreqn.mreqn.imr_address.s_addr,
|
ip4_mreqn.mreqn.imr_address.s_addr,
|
||||||
ip4_mreqn.mreqn.imr_ifindex,
|
ip4_mreqn.mreqn.imr_ifindex,
|
||||||
|
@ -825,10 +825,10 @@ mc:addr
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#else
|
#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) {
|
&ip4_mreqn.mreq, sizeof(ip4_mreqn.mreq)) < 0) {
|
||||||
Error7("setsockopt(%d, %d, %d, {0x%08x,0x%08x}, "F_Zu"): %s",
|
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_multiaddr,
|
||||||
ip4_mreqn.mreq.imr_interface,
|
ip4_mreqn.mreq.imr_interface,
|
||||||
sizeof(ip4_mreqn.mreq),
|
sizeof(ip4_mreqn.mreq),
|
||||||
|
@ -932,7 +932,7 @@ int xiotype_ip_add_source_membership(char *token, const struct optname *ent, str
|
||||||
return 0;
|
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}};
|
struct ip_mreq_source ip4_mreq_src = {{0}};
|
||||||
/* IPv6 not supported - seems to have different handling */
|
/* IPv6 not supported - seems to have different handling */
|
||||||
union sockaddr_union sockaddr1;
|
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 */
|
/* first parameter is always multicast address */
|
||||||
rc = xioresolve(opt->value.u_string/*mcaddr*/, NULL,
|
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,
|
SOCK_DGRAM, IPPROTO_IP,
|
||||||
&sockaddr1, &socklen1, xfd->para.socket.ip.ai_flags);
|
&sockaddr1, &socklen1, sfd->para.socket.ip.ai_flags);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ip4_mreq_src.imr_multiaddr = sockaddr1.ip4.sin_addr;
|
ip4_mreq_src.imr_multiaddr = sockaddr1.ip4.sin_addr;
|
||||||
/* second parameter is interface address */
|
/* second parameter is interface address */
|
||||||
rc = xioresolve(opt->value.u_string/*ifaddr*/, NULL,
|
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,
|
SOCK_DGRAM, IPPROTO_IP,
|
||||||
&sockaddr2, &socklen2, xfd->para.socket.ip.ai_flags);
|
&sockaddr2, &socklen2, sfd->para.socket.ip.ai_flags);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ip4_mreq_src.imr_interface = sockaddr2.ip4.sin_addr;
|
ip4_mreq_src.imr_interface = sockaddr2.ip4.sin_addr;
|
||||||
/* third parameter is source address */
|
/* third parameter is source address */
|
||||||
rc = xioresolve(opt->value.u_string/*srcaddr*/, NULL,
|
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,
|
SOCK_DGRAM, IPPROTO_IP,
|
||||||
&sockaddr3, &socklen3, xfd->para.socket.ip.ai_flags);
|
&sockaddr3, &socklen3, sfd->para.socket.ip.ai_flags);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ip4_mreq_src.imr_sourceaddr = sockaddr3.ip4.sin_addr;
|
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) {
|
&ip4_mreq_src, sizeof(ip4_mreq_src)) < 0) {
|
||||||
Error8("setsockopt(%d, %d, %d, {0x%08x,0x%08x,0x%08x}, "F_Zu"): %s",
|
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),
|
htonl((uint32_t)ip4_mreq_src.imr_multiaddr.s_addr),
|
||||||
ip4_mreq_src.imr_interface.s_addr,
|
ip4_mreq_src.imr_interface.s_addr,
|
||||||
ip4_mreq_src.imr_sourceaddr.s_addr,
|
ip4_mreq_src.imr_sourceaddr.s_addr,
|
||||||
|
|
26
xio-ip6.c
26
xio-ip6.c
|
@ -259,7 +259,7 @@ int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange *range) {
|
||||||
returns STAT_OK on success
|
returns STAT_OK on success
|
||||||
*/
|
*/
|
||||||
int xiolog_ancillary_ip6(
|
int xiolog_ancillary_ip6(
|
||||||
struct single *xfd,
|
struct single *sfd,
|
||||||
struct cmsghdr *cmsg,
|
struct cmsghdr *cmsg,
|
||||||
int *num,
|
int *num,
|
||||||
char *typbuff, int typlen,
|
char *typbuff, int typlen,
|
||||||
|
@ -476,7 +476,7 @@ xiosetsockaddrenv_ip6(int idx, char *namebuff, size_t namelen,
|
||||||
|
|
||||||
#if defined(HAVE_STRUCT_IPV6_MREQ)
|
#if defined(HAVE_STRUCT_IPV6_MREQ)
|
||||||
int xioapply_ipv6_join_group(
|
int xioapply_ipv6_join_group(
|
||||||
xiosingle_t *xfd,
|
struct single *sfd,
|
||||||
struct opt *opt)
|
struct opt *opt)
|
||||||
{
|
{
|
||||||
struct ipv6_mreq ip6_mreq = {{{{0}}}};
|
struct ipv6_mreq ip6_mreq = {{{{0}}}};
|
||||||
|
@ -488,10 +488,10 @@ int xioapply_ipv6_join_group(
|
||||||
/* First parameter is multicast address */
|
/* First parameter is multicast address */
|
||||||
if ((res =
|
if ((res =
|
||||||
xioresolve(opt->value.u_string/*multiaddr*/, NULL,
|
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,
|
SOCK_DGRAM, IPPROTO_IP,
|
||||||
&sockaddr1, &socklen1,
|
&sockaddr1, &socklen1,
|
||||||
xfd->para.socket.ip.ai_flags))
|
sfd->para.socket.ip.ai_flags))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -504,10 +504,10 @@ int xioapply_ipv6_join_group(
|
||||||
ip6_mreq.ipv6mr_interface = htonl(0);
|
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) {
|
&ip6_mreq, sizeof(ip6_mreq)) < 0) {
|
||||||
Error6("setsockopt(%d, %d, %d, {...,0x%08x}, "F_Zu"): %s",
|
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,
|
ip6_mreq.ipv6mr_interface,
|
||||||
sizeof(ip6_mreq),
|
sizeof(ip6_mreq),
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
@ -618,7 +618,7 @@ int xiotype_ip6_join_source_group(
|
||||||
return 0;
|
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};
|
struct group_source_req ip6_gsr = {0};
|
||||||
union sockaddr_union sockaddr1;
|
union sockaddr_union sockaddr1;
|
||||||
socklen_t socklen1 = sizeof(sockaddr1.ip6);
|
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 */
|
/* First parameter is always multicast address */
|
||||||
if ((res =
|
if ((res =
|
||||||
xioresolve(opt->value.u_string/*mcaddr*/, NULL,
|
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,
|
SOCK_DGRAM, IPPROTO_IP, &sockaddr1, &socklen1,
|
||||||
xfd->para.socket.ip.ai_flags))
|
sfd->para.socket.ip.ai_flags))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -647,17 +647,17 @@ int xioapply_ip6_join_source_group(struct single *xfd, struct opt *opt) {
|
||||||
/* Third parameter is source address */
|
/* Third parameter is source address */
|
||||||
if ((res =
|
if ((res =
|
||||||
xioresolve(opt->value3.u_string/*srcaddr*/, NULL,
|
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,
|
SOCK_DGRAM, IPPROTO_IP, &sockaddr2, &socklen2,
|
||||||
xfd->para.socket.ip.ai_flags))
|
sfd->para.socket.ip.ai_flags))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
memcpy(&ip6_gsr.gsr_source, &sockaddr2.ip6, socklen2);
|
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) {
|
&ip6_gsr, sizeof(ip6_gsr)) < 0) {
|
||||||
Error6("setsockopt(%d, %d, %d, {%d,...}, "F_Zu"): %s",
|
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,
|
ip6_gsr.gsr_interface,
|
||||||
sizeof(ip6_gsr),
|
sizeof(ip6_gsr),
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
|
81
xio-ipapp.c
81
xio-ipapp.c
|
@ -21,12 +21,19 @@ const struct optdesc opt_lowport = { "lowport", NULL, OPT_LOWPORT, GROUP_IPAPP,
|
||||||
|
|
||||||
#if WITH_IP4
|
#if WITH_IP4
|
||||||
/* we expect the form "host:port" */
|
/* we expect the form "host:port" */
|
||||||
int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
|
int xioopen_ipapp_connect(
|
||||||
int xioflags, xiofile_t *xxfd,
|
int argc,
|
||||||
groups_t groups, int socktype, int ipproto,
|
const char *argv[],
|
||||||
int pf) {
|
struct opt *opts,
|
||||||
struct single *xfd = &xxfd->stream;
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
|
struct single *sfd = &xxfd->stream;
|
||||||
struct opt *opts0 = NULL;
|
struct opt *opts0 = NULL;
|
||||||
|
int socktype = addrdesc->arg1;
|
||||||
|
int ipproto = addrdesc->arg2;
|
||||||
|
int pf = addrdesc->arg3;
|
||||||
const char *hostname = argv[1], *portname = argv[2];
|
const char *hostname = argv[1], *portname = argv[2];
|
||||||
bool dofork = false;
|
bool dofork = false;
|
||||||
union sockaddr_union us_sa, *us = &us_sa;
|
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;
|
int result;
|
||||||
|
|
||||||
if (argc != 3) {
|
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;
|
return -1;
|
||||||
applyopts(xfd, -1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_bool(opts, OPT_FORK, &dofork);
|
retropt_bool(opts, OPT_FORK, &dofork);
|
||||||
|
|
||||||
if (_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto,
|
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,
|
&themlist, us, &uslen, &needbind, &lowport,
|
||||||
socktype) != STAT_OK) {
|
socktype) != STAT_OK) {
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
|
@ -95,14 +104,14 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
infobuff, sizeof(infobuff)));
|
infobuff, sizeof(infobuff)));
|
||||||
|
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
if (xfd->forever || xfd->retry || ai_sorted[i] != NULL) {
|
if (sfd->forever || sfd->retry || ai_sorted[i] != NULL) {
|
||||||
level = E_INFO;
|
level = E_INFO;
|
||||||
} else
|
} else
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
level = E_ERROR;
|
level = E_ERROR;
|
||||||
|
|
||||||
result =
|
result =
|
||||||
_xioopen_connect(xfd,
|
_xioopen_connect(sfd,
|
||||||
needbind?us:NULL, uslen,
|
needbind?us:NULL, uslen,
|
||||||
themp->ai_addr, themp->ai_addrlen,
|
themp->ai_addr, themp->ai_addrlen,
|
||||||
opts, pf?pf:themp->ai_family, socktype, ipproto,
|
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
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
case STAT_RETRYNOW:
|
case STAT_RETRYNOW:
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
--xfd->retry;
|
--sfd->retry;
|
||||||
if (result == STAT_RETRYLATER) {
|
if (result == STAT_RETRYLATER) {
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
}
|
}
|
||||||
dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL);
|
||||||
continue;
|
continue;
|
||||||
|
@ -138,13 +147,13 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
if (dofork) {
|
if (dofork) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int level = E_ERROR;
|
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,
|
level = E_WARN; /* most users won't expect a problem here,
|
||||||
so Notice is too weak */
|
so Notice is too weak */
|
||||||
}
|
}
|
||||||
while ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
|
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
|
||||||
if (xfd->forever || --xfd->retry) {
|
if (sfd->forever || --sfd->retry) {
|
||||||
Nanosleep(&xfd->intervall, NULL); continue;
|
Nanosleep(&sfd->intervall, NULL); continue;
|
||||||
}
|
}
|
||||||
free(ai_sorted);
|
free(ai_sorted);
|
||||||
free(opts0);
|
free(opts0);
|
||||||
|
@ -152,14 +161,14 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid == 0) { /* child process */
|
if (pid == 0) { /* child process */
|
||||||
xfd->forever = false; xfd->retry = 0;
|
sfd->forever = false; sfd->retry = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parent process */
|
/* parent process */
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
/* with and without retry */
|
/* with and without retry */
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL);
|
||||||
continue; /* with next socket() bind() connect() */
|
continue; /* with next socket() bind() connect() */
|
||||||
} else
|
} else
|
||||||
|
@ -172,7 +181,7 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
free(ai_sorted);
|
free(ai_sorted);
|
||||||
xiofreeaddrinfo(themlist);
|
xiofreeaddrinfo(themlist);
|
||||||
|
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0) {
|
if ((result = _xio_openlate(sfd, opts)) < 0) {
|
||||||
free(opts0);free(opts);
|
free(opts0);free(opts);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -302,18 +311,26 @@ int _xioopen_ipapp_listen_prepare(
|
||||||
|
|
||||||
/* we expect the form: port */
|
/* we expect the form: port */
|
||||||
/* currently only used for TCP4 */
|
/* currently only used for TCP4 */
|
||||||
int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts,
|
int xioopen_ipapp_listen(
|
||||||
int xioflags, xiofile_t *xfd,
|
int argc,
|
||||||
groups_t groups, int socktype,
|
const char *argv[],
|
||||||
int ipproto, int pf) {
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
struct single *sfd = &xfd->stream;
|
struct single *sfd = &xfd->stream;
|
||||||
struct opt *opts0 = NULL;
|
struct opt *opts0 = NULL;
|
||||||
|
int socktype = addrdesc->arg1;
|
||||||
|
int ipproto = addrdesc->arg2;
|
||||||
|
int pf = addrdesc->arg3;
|
||||||
union sockaddr_union us_sa, *us = &us_sa;
|
union sockaddr_union us_sa, *us = &us_sa;
|
||||||
socklen_t uslen = sizeof(us_sa);
|
socklen_t uslen = sizeof(us_sa);
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 2) {
|
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);
|
xioinit_ip(&pf, xioparms.default_ip);
|
||||||
|
@ -331,21 +348,21 @@ int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
#endif
|
#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_INIT);
|
||||||
applyopts(sfd, -1, opts, PH_EARLY);
|
applyopts(sfd, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
if (_xioopen_ipapp_listen_prepare(opts, &opts0, argv[1], &pf, ipproto,
|
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)
|
us, &uslen, socktype)
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result =
|
if ((result =
|
||||||
xioopen_listen(&xfd->stream, xioflags,
|
xioopen_listen(sfd, xioflags,
|
||||||
(struct sockaddr *)us, uslen,
|
(struct sockaddr *)us, uslen,
|
||||||
opts, opts0, pf, socktype, ipproto))
|
opts, opts0, pf, socktype, ipproto))
|
||||||
!= 0)
|
!= 0)
|
||||||
|
|
12
xio-ipapp.h
12
xio-ipapp.h
|
@ -14,19 +14,13 @@ extern const struct optdesc opt_sourceport;
|
||||||
/*extern const struct optdesc opt_port;*/
|
/*extern const struct optdesc opt_port;*/
|
||||||
extern const struct optdesc opt_lowport;
|
extern const struct optdesc opt_lowport;
|
||||||
|
|
||||||
extern int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd,
|
extern int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
|
||||||
groups_t groups, int socktype,
|
extern int _xioopen_ipapp_prepare(struct opt *opts, struct opt **opts0, const char *hostname, const char *portname, int *pf, int protocol, const int ai_flags[2], struct addrinfo **res, union sockaddr_union *us, socklen_t *uslen, bool *needbind, bool *lowport, 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_ip4app_connect(const char *hostname, const char *portname,
|
extern int _xioopen_ip4app_connect(const char *hostname, const char *portname,
|
||||||
struct single *xfd,
|
struct single *xfd,
|
||||||
int socktype, int ipproto, void *protname,
|
int socktype, int ipproto, void *protname,
|
||||||
struct opt *opts);
|
struct opt *opts);
|
||||||
extern int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts,
|
extern int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
|
||||||
int xioflags, xiofile_t *fd,
|
|
||||||
groups_t groups, int socktype,
|
|
||||||
int ipproto, int protname);
|
|
||||||
extern int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0, const char *portname, int *pf, int ipproto, const int ai_flags[2], union sockaddr_union *us, socklen_t *uslen, int socktype);
|
extern int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0, const char *portname, int *pf, int ipproto, const int ai_flags[2], union sockaddr_union *us, socklen_t *uslen, int socktype);
|
||||||
extern int _xio_sort_ip_addresses(struct addrinfo *themlist, struct addrinfo **ai_sorted);
|
extern int _xio_sort_ip_addresses(struct addrinfo *themlist, struct addrinfo **ai_sorted);
|
||||||
|
|
||||||
|
|
134
xio-listen.c
134
xio-listen.c
|
@ -35,7 +35,7 @@ const struct optdesc opt_accept_timeout = { "accept-timeout", "listen-timeout",
|
||||||
OPT_SOURCEPORT, OPT_LOWPORT, cloexec
|
OPT_SOURCEPORT, OPT_LOWPORT, cloexec
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xioopen_listen(struct single *xfd, int xioflags,
|
xioopen_listen(struct single *sfd, int xioflags,
|
||||||
struct sockaddr *us, socklen_t uslen,
|
struct sockaddr *us, socklen_t uslen,
|
||||||
struct opt *opts, struct opt *opts0,
|
struct opt *opts, struct opt *opts0,
|
||||||
int pf, int socktype, int proto) {
|
int pf, int socktype, int proto) {
|
||||||
|
@ -43,7 +43,7 @@ int
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
level = E_INFO;
|
level = E_INFO;
|
||||||
} else
|
} else
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
|
@ -53,7 +53,7 @@ int
|
||||||
|
|
||||||
/* tcp listen; this can fork() for us; it only returns on error or on
|
/* tcp listen; this can fork() for us; it only returns on error or on
|
||||||
successful establishment of tcp connection */
|
successful establishment of tcp connection */
|
||||||
result = _xioopen_listen(xfd, xioflags,
|
result = _xioopen_listen(sfd, xioflags,
|
||||||
(struct sockaddr *)us, uslen,
|
(struct sockaddr *)us, uslen,
|
||||||
opts, pf, socktype, proto, level);
|
opts, pf, socktype, proto, level);
|
||||||
/*! not sure if we should try again on retry/forever */
|
/*! not sure if we should try again on retry/forever */
|
||||||
|
@ -62,13 +62,13 @@ int
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
case STAT_RETRYNOW:
|
case STAT_RETRYNOW:
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
if (result == STAT_RETRYLATER) {
|
if (result == STAT_RETRYLATER) {
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
}
|
}
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
--xfd->retry;
|
--sfd->retry;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
|
@ -103,31 +103,31 @@ int
|
||||||
OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_BACKLOG, OPT_RANGE, tcpwrap,
|
OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_BACKLOG, OPT_RANGE, tcpwrap,
|
||||||
OPT_SOURCEPORT, OPT_LOWPORT, cloexec
|
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) {
|
struct opt *opts, int pf, int socktype, int proto, int level) {
|
||||||
int backlog = 5; /* why? 1 seems to cause problems under some load */
|
int backlog = 5; /* why? 1 seems to cause problems under some load */
|
||||||
char infobuff[256];
|
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;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
applyopts(xfd, -1, opts, PH_PASTSOCKET);
|
applyopts(sfd, -1, opts, PH_PASTSOCKET);
|
||||||
|
|
||||||
applyopts_offset(xfd, opts);
|
applyopts_offset(sfd, opts);
|
||||||
applyopts_cloexec(xfd->fd, opts);
|
applyopts_cloexec(sfd->fd, opts);
|
||||||
|
|
||||||
/* Phase prebind */
|
/* Phase prebind */
|
||||||
xiosock_reuseaddr(xfd->fd, proto, opts);
|
xiosock_reuseaddr(sfd->fd, proto, opts);
|
||||||
applyopts(xfd, -1, opts, PH_PREBIND);
|
applyopts(sfd, -1, opts, PH_PREBIND);
|
||||||
|
|
||||||
applyopts(xfd, -1, opts, PH_BIND);
|
applyopts(sfd, -1, opts, PH_BIND);
|
||||||
if (Bind(xfd->fd, (struct sockaddr *)us, uslen) < 0) {
|
if (Bind(sfd->fd, (struct sockaddr *)us, uslen) < 0) {
|
||||||
Msg4(level, "bind(%d, {%s}, "F_socklen"): %s", xfd->fd,
|
Msg4(level, "bind(%d, {%s}, "F_socklen"): %s", sfd->fd,
|
||||||
sockaddr_info(us, uslen, infobuff, sizeof(infobuff)), uslen,
|
sockaddr_info(us, uslen, infobuff, sizeof(infobuff)), uslen,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
return STAT_RETRYLATER;
|
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') {
|
if (((union sockaddr_union *)us)->un.sun_path[0] != '\0') {
|
||||||
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_FD);
|
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_FD);
|
||||||
} else {
|
} else {
|
||||||
applyopts(xfd, -1, opts, PH_FD);
|
applyopts(sfd, -1, opts, PH_FD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
applyopts(xfd, -1, opts, PH_PASTBIND);
|
applyopts(sfd, -1, opts, PH_PASTBIND);
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
if (us->sa_family == AF_UNIX) {
|
if (us->sa_family == AF_UNIX) {
|
||||||
if (((union sockaddr_union *)us)->un.sun_path[0] != '\0') {
|
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_EARLY);
|
||||||
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_PREOPEN);
|
applyopts_named(((struct sockaddr_un *)us)->sun_path, opts, PH_PREOPEN);
|
||||||
} else {
|
} else {
|
||||||
applyopts(xfd, -1, opts, PH_EARLY);
|
applyopts(sfd, -1, opts, PH_EARLY);
|
||||||
applyopts(xfd, -1, opts, PH_PREOPEN);
|
applyopts(sfd, -1, opts, PH_PREOPEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* WITH_UNIX */
|
#endif /* WITH_UNIX */
|
||||||
|
|
||||||
applyopts(xfd, -1, opts, PH_PRELISTEN);
|
applyopts(sfd, -1, opts, PH_PRELISTEN);
|
||||||
retropt_int(opts, OPT_BACKLOG, &backlog);
|
retropt_int(opts, OPT_BACKLOG, &backlog);
|
||||||
applyopts(xfd, -1, opts, PH_LISTEN);
|
applyopts(sfd, -1, opts, PH_LISTEN);
|
||||||
if (Listen(xfd->fd, backlog) < 0) {
|
if (Listen(sfd->fd, backlog) < 0) {
|
||||||
Error3("listen(%d, %d): %s", xfd->fd, backlog, strerror(errno));
|
Error3("listen(%d, %d): %s", sfd->fd, backlog, strerror(errno));
|
||||||
return STAT_RETRYLATER;
|
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(
|
int _xioopen_accept_fd(
|
||||||
struct single *xfd,
|
struct single *sfd,
|
||||||
int xioflags,
|
int xioflags,
|
||||||
struct sockaddr *us,
|
struct sockaddr *us,
|
||||||
socklen_t uslen,
|
socklen_t uslen,
|
||||||
|
@ -196,7 +196,7 @@ int _xioopen_accept_fd(
|
||||||
Error("option fork not allowed here");
|
Error("option fork not allowed here");
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
xfd->flags |= XIO_DOESFORK;
|
sfd->flags |= XIO_DOESFORK;
|
||||||
}
|
}
|
||||||
|
|
||||||
retropt_int(opts, OPT_MAX_CHILDREN, &maxchildren);
|
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
|
/* Under some circumstances (e.g., TCP listen on port 0) bind() fills empty
|
||||||
fields that we want to know. */
|
fields that we want to know. */
|
||||||
salen = sizeof(sa);
|
salen = sizeof(sa);
|
||||||
if (Getsockname(xfd->fd, us, &uslen) < 0) {
|
if (Getsockname(sfd->fd, us, &uslen) < 0) {
|
||||||
Warn4("getsockname(%d, %p, {%d}): %s",
|
Warn4("getsockname(%d, %p, {%d}): %s",
|
||||||
xfd->fd, &us, uslen, strerror(errno));
|
sfd->fd, &us, uslen, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WITH_IP4 /*|| WITH_IP6*/
|
#if WITH_IP4 /*|| WITH_IP6*/
|
||||||
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
||||||
if (xioparserange(rangename, pf, &xfd->para.socket.range,
|
if (xioparserange(rangename, pf, &sfd->para.socket.range,
|
||||||
xfd->para.socket.ip.ai_flags)
|
sfd->para.socket.ip.ai_flags)
|
||||||
< 0) {
|
< 0) {
|
||||||
free(rangename);
|
free(rangename);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
free(rangename);
|
free(rangename);
|
||||||
xfd->para.socket.dorange = true;
|
sfd->para.socket.dorange = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
|
#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
|
||||||
xio_retropt_tcpwrap(xfd, opts);
|
xio_retropt_tcpwrap(sfd, opts);
|
||||||
#endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */
|
#endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */
|
||||||
|
|
||||||
#if WITH_TCP || WITH_UDP
|
#if WITH_TCP || WITH_UDP
|
||||||
if (retropt_ushort(opts, OPT_SOURCEPORT, &xfd->para.socket.ip.sourceport) >= 0) {
|
if (retropt_ushort(opts, OPT_SOURCEPORT, &sfd->para.socket.ip.sourceport) >= 0) {
|
||||||
xfd->para.socket.ip.dosourceport = true;
|
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 */
|
#endif /* WITH_TCP || WITH_UDP */
|
||||||
|
|
||||||
if (xioparms.logopt == 'm') {
|
if (xioparms.logopt == 'm') {
|
||||||
|
@ -259,30 +259,30 @@ int _xioopen_accept_fd(
|
||||||
do {
|
do {
|
||||||
/*? int level = E_ERROR;*/
|
/*? int level = E_ERROR;*/
|
||||||
Notice1("listening on %s", sockaddr_info(us, uslen, lisname, sizeof(lisname)));
|
Notice1("listening on %s", sockaddr_info(us, uslen, lisname, sizeof(lisname)));
|
||||||
if (xfd->para.socket.accept_timeout.tv_sec > 0 ||
|
if (sfd->para.socket.accept_timeout.tv_sec > 0 ||
|
||||||
xfd->para.socket.accept_timeout.tv_usec > 0) {
|
sfd->para.socket.accept_timeout.tv_usec > 0) {
|
||||||
fd_set rfd;
|
fd_set rfd;
|
||||||
struct timeval tmo;
|
struct timeval tmo;
|
||||||
FD_ZERO(&rfd);
|
FD_ZERO(&rfd);
|
||||||
FD_SET(xfd->fd, &rfd);
|
FD_SET(sfd->fd, &rfd);
|
||||||
tmo.tv_sec = xfd->para.socket.accept_timeout.tv_sec;
|
tmo.tv_sec = sfd->para.socket.accept_timeout.tv_sec;
|
||||||
tmo.tv_usec = xfd->para.socket.accept_timeout.tv_usec;
|
tmo.tv_usec = sfd->para.socket.accept_timeout.tv_usec;
|
||||||
while (1) {
|
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) {
|
if (errno != EINTR) {
|
||||||
Error5("Select(%d, &0x%lx, NULL, NULL, {%ld.%06ld}): %s", xfd->fd+1, 1L<<(xfd->fd+1),
|
Error5("Select(%d, &0x%lx, NULL, NULL, {%ld.%06ld}): %s", sfd->fd+1, 1L<<(sfd->fd+1),
|
||||||
xfd->para.socket.accept_timeout.tv_sec, xfd->para.socket.accept_timeout.tv_usec,
|
sfd->para.socket.accept_timeout.tv_sec, sfd->para.socket.accept_timeout.tv_usec,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!FD_ISSET(xfd->fd, &rfd)) {
|
if (!FD_ISSET(sfd->fd, &rfd)) {
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
|
|
||||||
Warn1("accept: %s", strerror(ETIMEDOUT));
|
Warn1("accept: %s", strerror(ETIMEDOUT));
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
Notice("Waiting for child processes to terminate");
|
Notice("Waiting for child processes to terminate");
|
||||||
memset(&act, 0, sizeof(struct sigaction));
|
memset(&act, 0, sizeof(struct sigaction));
|
||||||
act.sa_flags = SA_NOCLDSTOP/*|SA_RESTART*/
|
act.sa_flags = SA_NOCLDSTOP/*|SA_RESTART*/
|
||||||
|
@ -304,9 +304,9 @@ int _xioopen_accept_fd(
|
||||||
Exit(0);
|
Exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ps = Accept(xfd->fd, (struct sockaddr *)&sa, &salen);
|
ps = Accept(sfd->fd, (struct sockaddr *)&sa, &salen);
|
||||||
if (ps >= 0) {
|
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 */
|
break; /* success, break out of loop */
|
||||||
}
|
}
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
|
@ -314,12 +314,12 @@ int _xioopen_accept_fd(
|
||||||
}
|
}
|
||||||
if (errno == ECONNABORTED) {
|
if (errno == ECONNABORTED) {
|
||||||
Notice4("accept(%d, %p, {"F_socklen"}): %s",
|
Notice4("accept(%d, %p, {"F_socklen"}): %s",
|
||||||
xfd->fd, &sa, salen, strerror(errno));
|
sfd->fd, &sa, salen, strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Msg4(level, "accept(%d, %p, {"F_socklen"}): %s",
|
Msg4(level, "accept(%d, %p, {"F_socklen"}): %s",
|
||||||
xfd->fd, &sa, salen, strerror(errno));
|
sfd->fd, &sa, salen, strerror(errno));
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
} while (true);
|
} while (true);
|
||||||
applyopts_cloexec(ps, opts);
|
applyopts_cloexec(ps, opts);
|
||||||
|
@ -339,7 +339,7 @@ int _xioopen_accept_fd(
|
||||||
la?
|
la?
|
||||||
sockaddr_info(&la->soa, las, sockname, sizeof(sockname)):"NULL");
|
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) {
|
if (Shutdown(ps, 2) < 0) {
|
||||||
Info2("shutdown(%d, 2): %s", ps, strerror(errno));
|
Info2("shutdown(%d, 2): %s", ps, strerror(errno));
|
||||||
}
|
}
|
||||||
|
@ -363,9 +363,9 @@ int _xioopen_accept_fd(
|
||||||
|
|
||||||
if ((pid =
|
if ((pid =
|
||||||
xio_fork(false, level==E_ERROR?level:E_WARN,
|
xio_fork(false, level==E_ERROR?level:E_WARN,
|
||||||
xfd->shutup))
|
sfd->shutup))
|
||||||
< 0) {
|
< 0) {
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL);
|
Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
@ -376,14 +376,14 @@ int _xioopen_accept_fd(
|
||||||
Info1("just born: child process "F_pid, cpid);
|
Info1("just born: child process "F_pid, cpid);
|
||||||
xiosetenvulong("PID", cpid, 1);
|
xiosetenvulong("PID", cpid, 1);
|
||||||
|
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
xfd->fd = ps;
|
sfd->fd = ps;
|
||||||
|
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
/* !? */
|
/* !? */
|
||||||
xfd->forever = false; xfd->retry = 0;
|
sfd->forever = false; sfd->retry = 0;
|
||||||
level = E_ERROR;
|
level = E_ERROR;
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
|
|
||||||
|
@ -410,18 +410,18 @@ int _xioopen_accept_fd(
|
||||||
}
|
}
|
||||||
Info("still listening");
|
Info("still listening");
|
||||||
} else {
|
} else {
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
xfd->fd = ps;
|
sfd->fd = ps;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts(xfd, -1, opts, PH_FD);
|
applyopts(sfd, -1, opts, PH_FD);
|
||||||
applyopts(xfd, -1, opts, PH_PASTSOCKET);
|
applyopts(sfd, -1, opts, PH_PASTSOCKET);
|
||||||
applyopts(xfd, -1, opts, PH_CONNECTED);
|
applyopts(sfd, -1, opts, PH_CONNECTED);
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0)
|
if ((result = _xio_openlate(sfd, opts)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
/* set the env vars describing the local and remote sockets */
|
/* set the env vars describing the local and remote sockets */
|
||||||
|
|
13
xio-named.c
13
xio-named.c
|
@ -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.
|
If the path exists, its st_mode field is returned.
|
||||||
After this sub you may proceed with open() or whatever...
|
After this sub you may proceed with open() or whatever...
|
||||||
*/
|
*/
|
||||||
int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd,
|
int _xioopen_named_early(
|
||||||
groups_t groups, bool *exists, struct opt *opts)
|
int argc,
|
||||||
|
const char *argv[],
|
||||||
|
xiofile_t *xfd,
|
||||||
|
groups_t groups,
|
||||||
|
bool *exists,
|
||||||
|
struct opt *opts,
|
||||||
|
const char *syntax)
|
||||||
{
|
{
|
||||||
const char *path = argv[1];
|
const char *path = argv[1];
|
||||||
struct single *sfd = &xfd->stream;
|
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;
|
bool opt_unlink_early = false;
|
||||||
|
|
||||||
if (argc != 2) {
|
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;
|
statbuf.st_mode = 0;
|
||||||
/* find the appropriate groupbits */
|
/* find the appropriate groupbits */
|
||||||
|
|
|
@ -18,9 +18,7 @@ extern const struct optdesc opt_umask;
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
applyopts_named(const char *filename, struct opt *opts, unsigned int phase);
|
applyopts_named(const char *filename, struct opt *opts, unsigned int phase);
|
||||||
extern int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd,
|
extern int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd, groups_t groups, bool *exists, struct opt *opts, const char *syntax);
|
||||||
groups_t groups,
|
|
||||||
bool *exists, struct opt *opts);
|
|
||||||
extern int _xioopen_open(const char *path, int rw, struct opt *opts);
|
extern int _xioopen_open(const char *path, int rw, struct opt *opts);
|
||||||
|
|
||||||
extern int xio_unlink(const char *pathname, int level);
|
extern int xio_unlink(const char *pathname, int level);
|
||||||
|
|
226
xio-openssl.c
226
xio-openssl.c
|
@ -43,21 +43,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* static declaration of ssl's open function */
|
/* static declaration of ssl's open function */
|
||||||
static int xioopen_openssl_connect(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_openssl_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
|
||||||
int xioflags, xiofile_t *fd, groups_t groups,
|
|
||||||
int dummy1, int dummy2, int dummy3);
|
|
||||||
|
|
||||||
/* static declaration of ssl's open function */
|
/* static declaration of ssl's open function */
|
||||||
static int xioopen_openssl_listen(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_openssl_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
|
||||||
int xioflags, xiofile_t *fd, groups_t groups,
|
|
||||||
int dummy1, int dummy2, int dummy3);
|
|
||||||
static int openssl_SSL_ERROR_SSL(int level, const char *funcname);
|
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,
|
const char *peername,
|
||||||
bool opt_ver,
|
bool opt_ver,
|
||||||
int level);
|
int level);
|
||||||
static int xioSSL_set_fd(struct single *xfd, int level);
|
static int xioSSL_set_fd(struct single *sfd, int level);
|
||||||
static int xioSSL_connect(struct single *xfd, const char *opt_commonname, bool opt_ver, 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);
|
static int openssl_delete_cert_info(void);
|
||||||
|
|
||||||
|
|
||||||
|
@ -223,26 +220,20 @@ static void openssl_conn_loginfo(SSL *ssl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the open function for OpenSSL client */
|
/* the open function for OpenSSL client */
|
||||||
static int
|
static int xioopen_openssl_connect(
|
||||||
xioopen_openssl_connect(int argc,
|
int argc,
|
||||||
const char *argv[], /* the arguments in the address string */
|
const char *argv[], /* the arguments in the address string */
|
||||||
struct opt *opts,
|
struct opt *opts,
|
||||||
int xioflags, /* is the open meant for reading (0),
|
int xioflags, /* is the open meant for reading (0),
|
||||||
writing (1), or both (2) ? */
|
writing (1), or both (2) ? */
|
||||||
xiofile_t *xxfd, /* a xio file descriptor structure,
|
xiofile_t *xxfd, /* a xio file descriptor structure,
|
||||||
already allocated */
|
already allocated */
|
||||||
groups_t groups, /* the matching address groups... */
|
const struct addrdesc *addrdesc) /* the above descriptor */
|
||||||
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 */
|
|
||||||
{
|
{
|
||||||
struct single *xfd = &xxfd->stream;
|
struct single *sfd = &xxfd->stream;
|
||||||
struct single *sfd = xfd;
|
|
||||||
struct opt *opts0 = NULL;
|
struct opt *opts0 = NULL;
|
||||||
const char *hostname, *portname;
|
const char *hostname, *portname;
|
||||||
|
int protogrp = addrdesc->arg1;
|
||||||
int pf = PF_UNSPEC;
|
int pf = PF_UNSPEC;
|
||||||
bool use_dtls = (protogrp != 0);
|
bool use_dtls = (protogrp != 0);
|
||||||
int socktype = SOCK_STREAM;
|
int socktype = SOCK_STREAM;
|
||||||
|
@ -268,10 +259,10 @@ static int
|
||||||
Error("address with data processing not allowed here");
|
Error("address with data processing not allowed here");
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
xfd->flags |= XIO_DOESCONVERT;
|
sfd->flags |= XIO_DOESCONVERT;
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
Error1("%s: 2 parameters required", argv[0]);
|
xio_syntax(argv[0], 2, argc-1, addrdesc->syntax);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
hostname = argv[1];
|
hostname = argv[1];
|
||||||
|
@ -283,8 +274,10 @@ static int
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xioinit_ip(&pf, xioparms.default_ip);
|
||||||
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);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_bool(opts, OPT_FORK, &dofork);
|
retropt_bool(opts, OPT_FORK, &dofork);
|
||||||
|
@ -317,7 +310,7 @@ static int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
result =
|
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 (result != STAT_OK) return STAT_NORETRY;
|
||||||
|
|
||||||
if (use_dtls) {
|
if (use_dtls) {
|
||||||
|
@ -329,7 +322,7 @@ static int
|
||||||
|
|
||||||
result =
|
result =
|
||||||
_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto,
|
_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto,
|
||||||
xfd->para.socket.ip.ai_flags,
|
sfd->para.socket.ip.ai_flags,
|
||||||
&themlist, us, &uslen,
|
&themlist, us, &uslen,
|
||||||
&needbind, &lowport, socktype);
|
&needbind, &lowport, socktype);
|
||||||
if (result != STAT_OK) return STAT_NORETRY;
|
if (result != STAT_OK) return STAT_NORETRY;
|
||||||
|
@ -362,7 +355,7 @@ static int
|
||||||
while (themp != NULL) {
|
while (themp != NULL) {
|
||||||
|
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
if (xfd->forever || xfd->retry || ai_sorted[i] != NULL) {
|
if (sfd->forever || sfd->retry || ai_sorted[i] != NULL) {
|
||||||
level = E_INFO;
|
level = E_INFO;
|
||||||
} else
|
} else
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
|
@ -370,7 +363,7 @@ static int
|
||||||
|
|
||||||
/* This cannot fork because we retrieved fork option above */
|
/* This cannot fork because we retrieved fork option above */
|
||||||
result =
|
result =
|
||||||
_xioopen_connect(xfd,
|
_xioopen_connect(sfd,
|
||||||
needbind?us:NULL, uslen,
|
needbind?us:NULL, uslen,
|
||||||
themp->ai_addr, themp->ai_addrlen,
|
themp->ai_addr, themp->ai_addrlen,
|
||||||
opts, pf?pf:themp->ai_addr->sa_family, socktype, ipproto, lowport, level);
|
opts, pf?pf:themp->ai_addr->sa_family, socktype, ipproto, lowport, level);
|
||||||
|
@ -386,12 +379,12 @@ static int
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
case STAT_RETRYNOW:
|
case STAT_RETRYNOW:
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
if (result == STAT_RETRYLATER) {
|
if (result == STAT_RETRYLATER) {
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
}
|
}
|
||||||
--xfd->retry;
|
--sfd->retry;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
free(ai_sorted);
|
free(ai_sorted);
|
||||||
|
@ -402,25 +395,25 @@ static int
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/*! isn't this too early? */
|
/*! isn't this too early? */
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0) {
|
if ((result = _xio_openlate(sfd, opts)) < 0) {
|
||||||
free(ai_sorted);
|
free(ai_sorted);
|
||||||
return result;
|
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);
|
opt_no_sni, opt_snihost, ctx, level);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case STAT_OK: break;
|
case STAT_OK: break;
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
case STAT_RETRYNOW:
|
case STAT_RETRYNOW:
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
if (result == STAT_RETRYLATER) {
|
if (result == STAT_RETRYLATER) {
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
}
|
}
|
||||||
--xfd->retry;
|
--sfd->retry;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
|
@ -437,28 +430,28 @@ static int
|
||||||
if (dofork) {
|
if (dofork) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int level = E_ERROR;
|
int level = E_ERROR;
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
level = E_WARN;
|
level = E_WARN;
|
||||||
}
|
}
|
||||||
while ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
|
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
|
||||||
if (xfd->forever || --xfd->retry) {
|
if (sfd->forever || --sfd->retry) {
|
||||||
Nanosleep(&xfd->intervall, NULL); continue;
|
Nanosleep(&sfd->intervall, NULL); continue;
|
||||||
}
|
}
|
||||||
xiofreeaddrinfo(themlist);
|
xiofreeaddrinfo(themlist);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid == 0) { /* child process */
|
if (pid == 0) { /* child process */
|
||||||
xfd->forever = false; xfd->retry = 0;
|
sfd->forever = false; sfd->retry = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parent process */
|
/* parent process */
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
sycSSL_free(xfd->para.openssl.ssl);
|
sycSSL_free(sfd->para.openssl.ssl);
|
||||||
xfd->para.openssl.ssl = NULL;
|
sfd->para.openssl.ssl = NULL;
|
||||||
/* with and without retry */
|
/* with and without retry */
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
continue; /* with next socket() bind() connect() */
|
continue; /* with next socket() bind() connect() */
|
||||||
}
|
}
|
||||||
|
@ -468,7 +461,7 @@ static int
|
||||||
free(ai_sorted);
|
free(ai_sorted);
|
||||||
xiofreeaddrinfo(themlist);
|
xiofreeaddrinfo(themlist);
|
||||||
|
|
||||||
openssl_conn_loginfo(xfd->para.openssl.ssl);
|
openssl_conn_loginfo(sfd->para.openssl.ssl);
|
||||||
|
|
||||||
free((void *)opt_commonname);
|
free((void *)opt_commonname);
|
||||||
free((void *)opt_snihost);
|
free((void *)opt_snihost);
|
||||||
|
@ -479,10 +472,10 @@ static int
|
||||||
|
|
||||||
|
|
||||||
/* this function is typically called within the OpenSSL client fork/retry loop.
|
/* 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
|
descriptor. this function then performs all SSL related step to make a valid
|
||||||
SSL connection from an FD and a CTX. */
|
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,
|
bool opt_ver,
|
||||||
const char *opt_commonname,
|
const char *opt_commonname,
|
||||||
bool no_sni,
|
bool no_sni,
|
||||||
|
@ -502,12 +495,12 @@ int _xioopen_openssl_connect(struct single *xfd,
|
||||||
/*Error("SSL_new()");*/
|
/*Error("SSL_new()");*/
|
||||||
return STAT_RETRYLATER;
|
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) {
|
if (result != STAT_OK) {
|
||||||
sycSSL_free(xfd->para.openssl.ssl);
|
sycSSL_free(sfd->para.openssl.ssl);
|
||||||
xfd->para.openssl.ssl = NULL;
|
sfd->para.openssl.ssl = NULL;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,25 +510,25 @@ int _xioopen_openssl_connect(struct single *xfd,
|
||||||
Warn("refusing to set empty SNI host name");
|
Warn("refusing to set empty SNI host name");
|
||||||
} else if (!SSL_set_tlsext_host_name(ssl, snihost)) {
|
} else if (!SSL_set_tlsext_host_name(ssl, snihost)) {
|
||||||
Error1("Failed to set SNI host \"%s\"", snihost);
|
Error1("Failed to set SNI host \"%s\"", snihost);
|
||||||
sycSSL_free(xfd->para.openssl.ssl);
|
sycSSL_free(sfd->para.openssl.ssl);
|
||||||
xfd->para.openssl.ssl = NULL;
|
sfd->para.openssl.ssl = NULL;
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
result = xioSSL_connect(xfd, opt_commonname, opt_ver, level);
|
result = xioSSL_connect(sfd, opt_commonname, opt_ver, level);
|
||||||
if (result != STAT_OK) {
|
if (result != STAT_OK) {
|
||||||
sycSSL_free(xfd->para.openssl.ssl);
|
sycSSL_free(sfd->para.openssl.ssl);
|
||||||
xfd->para.openssl.ssl = NULL;
|
sfd->para.openssl.ssl = NULL;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = openssl_handle_peer_certificate(xfd, opt_commonname,
|
result = openssl_handle_peer_certificate(sfd, opt_commonname,
|
||||||
opt_ver, level);
|
opt_ver, level);
|
||||||
if (result != STAT_OK) {
|
if (result != STAT_OK) {
|
||||||
sycSSL_free(xfd->para.openssl.ssl);
|
sycSSL_free(sfd->para.openssl.ssl);
|
||||||
xfd->para.openssl.ssl = NULL;
|
sfd->para.openssl.ssl = NULL;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,25 +538,19 @@ int _xioopen_openssl_connect(struct single *xfd,
|
||||||
|
|
||||||
#if WITH_LISTEN
|
#if WITH_LISTEN
|
||||||
|
|
||||||
static int
|
static int xioopen_openssl_listen(
|
||||||
xioopen_openssl_listen(int argc,
|
int argc,
|
||||||
const char *argv[], /* the arguments in the address string */
|
const char *argv[], /* the arguments in the address string */
|
||||||
struct opt *opts,
|
struct opt *opts,
|
||||||
int xioflags, /* is the open meant for reading (0),
|
int xioflags, /* is the open meant for reading (0),
|
||||||
writing (1), or both (2) ? */
|
writing (1), or both (2) ? */
|
||||||
xiofile_t *xxfd, /* a xio file descriptor structure,
|
xiofile_t *xxfd, /* a xio file descriptor structure,
|
||||||
already allocated */
|
already allocated */
|
||||||
groups_t groups, /* the matching address groups... */
|
const struct addrdesc *addrdesc) /* the above descriptor */
|
||||||
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 */
|
|
||||||
{
|
{
|
||||||
struct single *xfd = &xxfd->stream;
|
struct single *sfd = &xxfd->stream;
|
||||||
struct single *sfd = xfd;
|
|
||||||
const char *portname;
|
const char *portname;
|
||||||
|
int protogrp = addrdesc->arg1;
|
||||||
struct opt *opts0 = NULL;
|
struct opt *opts0 = NULL;
|
||||||
union sockaddr_union us_sa, *us = &us_sa;
|
union sockaddr_union us_sa, *us = &us_sa;
|
||||||
socklen_t uslen = sizeof(us_sa);
|
socklen_t uslen = sizeof(us_sa);
|
||||||
|
@ -583,13 +570,14 @@ static int
|
||||||
Error("address with data processing not allowed here");
|
Error("address with data processing not allowed here");
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
xfd->flags |= XIO_DOESCONVERT;
|
sfd->flags |= XIO_DOESCONVERT;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error1("%s: 1 parameter required", argv[0]);
|
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xioinit_ip(&pf, xioparms.default_ip);
|
||||||
#if WITH_IP4 && WITH_IP6
|
#if WITH_IP4 && WITH_IP6
|
||||||
switch (xioparms.default_ip) {
|
switch (xioparms.default_ip) {
|
||||||
case '4': pf = PF_INET; break;
|
case '4': pf = PF_INET; break;
|
||||||
|
@ -604,8 +592,8 @@ static int
|
||||||
|
|
||||||
portname = argv[1];
|
portname = argv[1];
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, 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_INIT);
|
||||||
|
|
||||||
retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert);
|
retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert);
|
||||||
|
@ -618,7 +606,7 @@ static int
|
||||||
applyopts(sfd, -1, opts, PH_EARLY);
|
applyopts(sfd, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
result =
|
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 (result != STAT_OK) return STAT_NORETRY;
|
||||||
|
|
||||||
if (use_dtls) {
|
if (use_dtls) {
|
||||||
|
@ -629,7 +617,7 @@ static int
|
||||||
retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto);
|
retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto);
|
||||||
|
|
||||||
if (_xioopen_ipapp_listen_prepare(opts, &opts0, portname, &pf, 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)
|
us, &uslen, socktype)
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
|
@ -637,12 +625,12 @@ static int
|
||||||
if (pf == 0)
|
if (pf == 0)
|
||||||
pf = us->soa.sa_family;
|
pf = us->soa.sa_family;
|
||||||
|
|
||||||
xfd->dtype = XIODATA_OPENSSL;
|
sfd->dtype = XIODATA_OPENSSL;
|
||||||
|
|
||||||
while (true) { /* loop over failed attempts */
|
while (true) { /* loop over failed attempts */
|
||||||
|
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
level = E_INFO;
|
level = E_INFO;
|
||||||
} else
|
} else
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
|
@ -651,18 +639,18 @@ static int
|
||||||
/* this can fork() for us; it only returns on error or on
|
/* this can fork() for us; it only returns on error or on
|
||||||
successful establishment of connection */
|
successful establishment of connection */
|
||||||
if (ipproto == IPPROTO_TCP) {
|
if (ipproto == IPPROTO_TCP) {
|
||||||
result = _xioopen_listen(xfd, xioflags,
|
result = _xioopen_listen(sfd, xioflags,
|
||||||
(struct sockaddr *)us, uslen,
|
(struct sockaddr *)us, uslen,
|
||||||
opts, pf, socktype, ipproto,
|
opts, pf, socktype, ipproto,
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
(xfd->retry||xfd->forever)?E_INFO:E_ERROR
|
(sfd->retry||sfd->forever)?E_INFO:E_ERROR
|
||||||
#else
|
#else
|
||||||
E_ERROR
|
E_ERROR
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
);
|
);
|
||||||
#if WITH_UDP
|
#if WITH_UDP
|
||||||
} else {
|
} else {
|
||||||
result = _xioopen_ipdgram_listen(xfd, xioflags,
|
result = _xioopen_ipdgram_listen(sfd, xioflags,
|
||||||
us, uslen, opts, pf, socktype, ipproto);
|
us, uslen, opts, pf, socktype, ipproto);
|
||||||
#endif /* WITH_UDP */
|
#endif /* WITH_UDP */
|
||||||
}
|
}
|
||||||
|
@ -672,13 +660,13 @@ static int
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
case STAT_RETRYNOW:
|
case STAT_RETRYNOW:
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
if (result == STAT_RETRYLATER) {
|
if (result == STAT_RETRYLATER) {
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
}
|
}
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
--xfd->retry;
|
--sfd->retry;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
|
@ -687,19 +675,19 @@ static int
|
||||||
return result;
|
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) {
|
switch (result) {
|
||||||
case STAT_OK: break;
|
case STAT_OK: break;
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
case STAT_RETRYNOW:
|
case STAT_RETRYNOW:
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
if (result == STAT_RETRYLATER) {
|
if (result == STAT_RETRYLATER) {
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
}
|
}
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
--xfd->retry;
|
--sfd->retry;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
|
@ -708,7 +696,7 @@ static int
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
openssl_conn_loginfo(xfd->para.openssl.ssl);
|
openssl_conn_loginfo(sfd->para.openssl.ssl);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} /* drop out on success */
|
} /* 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,
|
bool opt_ver,
|
||||||
const char *opt_commonname,
|
const char *opt_commonname,
|
||||||
SSL_CTX *ctx,
|
SSL_CTX *ctx,
|
||||||
|
@ -729,7 +717,7 @@ int _xioopen_openssl_listen(struct single *xfd,
|
||||||
int errint, ret;
|
int errint, ret;
|
||||||
|
|
||||||
/* create an SSL object */
|
/* 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");
|
if (ERR_peek_error() == 0) Msg(level, "SSL_new() failed");
|
||||||
while (err = ERR_get_error()) {
|
while (err = ERR_get_error()) {
|
||||||
Msg1(level, "SSL_new(): %s", ERR_error_string(err, NULL));
|
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 */
|
/* 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");
|
if (ERR_peek_error() == 0) Msg(level, "SSL_set_fd() failed");
|
||||||
while (err = ERR_get_error()) {
|
while (err = ERR_get_error()) {
|
||||||
Msg2(level, "SSL_set_fd(, %d): %s",
|
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;
|
const char *ciphers = NULL;
|
||||||
Debug("available ciphers:");
|
Debug("available ciphers:");
|
||||||
do {
|
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;
|
if (ciphers == NULL) break;
|
||||||
Debug2("CIPHERS pri=%d: %s", i, ciphers);
|
Debug2("CIPHERS pri=%d: %s", i, ciphers);
|
||||||
++i;
|
++i;
|
||||||
|
@ -762,9 +750,9 @@ int _xioopen_openssl_listen(struct single *xfd,
|
||||||
#endif /* WITH_DEBUG */
|
#endif /* WITH_DEBUG */
|
||||||
|
|
||||||
/* connect via SSL by performing handshake */
|
/* 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");*/
|
/*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) {
|
switch (errint) {
|
||||||
case SSL_ERROR_NONE:
|
case SSL_ERROR_NONE:
|
||||||
Msg(level, "ok"); break;
|
Msg(level, "ok"); break;
|
||||||
|
@ -803,7 +791,7 @@ int _xioopen_openssl_listen(struct single *xfd,
|
||||||
return STAT_RETRYLATER;
|
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;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -978,7 +966,7 @@ static int _xio_openssl_parse_version(const char *verstring, int vergroups) {
|
||||||
|
|
||||||
int
|
int
|
||||||
_xioopen_openssl_prepare(struct opt *opts,
|
_xioopen_openssl_prepare(struct opt *opts,
|
||||||
struct single *xfd,/* a xio file descriptor
|
struct single *sfd,/* a xio file descriptor
|
||||||
structure, already allocated
|
structure, already allocated
|
||||||
*/
|
*/
|
||||||
bool server, /* SSL client: false */
|
bool server, /* SSL client: false */
|
||||||
|
@ -1004,7 +992,7 @@ int
|
||||||
unsigned long err;
|
unsigned long err;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
xfd->dtype = XIODATA_OPENSSL;
|
sfd->dtype = XIODATA_OPENSSL;
|
||||||
|
|
||||||
retropt_bool(opts, OPT_OPENSSL_FIPS, &opt_fips);
|
retropt_bool(opts, OPT_OPENSSL_FIPS, &opt_fips);
|
||||||
retropt_string(opts, OPT_OPENSSL_METHOD, &me_str);
|
retropt_string(opts, OPT_OPENSSL_METHOD, &me_str);
|
||||||
|
@ -1237,35 +1225,35 @@ int
|
||||||
/*ERR_clear_error;*/
|
/*ERR_clear_error;*/
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
xfd->para.openssl.ctx = ctx;
|
sfd->para.openssl.ctx = ctx;
|
||||||
*ctxp = ctx;
|
*ctxp = ctx;
|
||||||
|
|
||||||
#if HAVE_SSL_CTX_set_min_proto_version || defined(SSL_CTX_set_min_proto_version)
|
#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;
|
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);
|
XIO_OPENSSL_VERSIONGROUP_TLS|XIO_OPENSSL_VERSIONGROUP_DTLS);
|
||||||
if (sslver < 0)
|
if (sslver < 0)
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
if ((rc = SSL_CTX_set_min_proto_version(ctx, sslver)) <= 0) {
|
if ((rc = SSL_CTX_set_min_proto_version(ctx, sslver)) <= 0) {
|
||||||
Debug1("version: %ld", SSL_CTX_get_min_proto_version(ctx));
|
Debug1("version: %ld", SSL_CTX_get_min_proto_version(ctx));
|
||||||
Error3("_xioopen_openssl_prepare(): SSL_CTX_set_min_proto_version(\"%s\"->%d): failed (%d)",
|
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;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
Debug1("version: %ld", SSL_CTX_get_min_proto_version(ctx));
|
Debug1("version: %ld", SSL_CTX_get_min_proto_version(ctx));
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SSL_set_min_proto_version || defined(SSL_set_min_proto_version) */
|
#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 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;
|
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);
|
XIO_OPENSSL_VERSIONGROUP_TLS|XIO_OPENSSL_VERSIONGROUP_DTLS);
|
||||||
if (sslver < 0)
|
if (sslver < 0)
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
if (SSL_CTX_set_max_proto_version(ctx, sslver) <= 0) {
|
if (SSL_CTX_set_max_proto_version(ctx, sslver) <= 0) {
|
||||||
Error2("_xioopen_openssl_prepare(): SSL_CTX_set_max_proto_version(\"%s\"->%d): failed",
|
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;
|
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
|
/* peername is, with OpenSSL client, the server name, or the value of option
|
||||||
commonname if provided;
|
commonname if provided;
|
||||||
With OpenSSL server, it is the value of option commonname */
|
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,
|
const char *peername,
|
||||||
bool opt_ver, int level) {
|
bool opt_ver, int level) {
|
||||||
X509 *peer_cert;
|
X509 *peer_cert;
|
||||||
|
@ -1802,7 +1790,7 @@ static int openssl_handle_peer_certificate(struct single *xfd,
|
||||||
int extcount, i, ok = 0;
|
int extcount, i, ok = 0;
|
||||||
int status;
|
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) {
|
if (opt_ver) {
|
||||||
Msg(level, "no peer certificate");
|
Msg(level, "no peer certificate");
|
||||||
status = STAT_RETRYLATER;
|
status = STAT_RETRYLATER;
|
||||||
|
@ -1816,7 +1804,7 @@ static int openssl_handle_peer_certificate(struct single *xfd,
|
||||||
/* verify peer certificate (trust, signature, validity dates) */
|
/* verify peer certificate (trust, signature, validity dates) */
|
||||||
if (opt_ver) {
|
if (opt_ver) {
|
||||||
long verify_result;
|
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;
|
const char *message = NULL;
|
||||||
if (verify_result >= 0 &&
|
if (verify_result >= 0 &&
|
||||||
(size_t)verify_result <
|
(size_t)verify_result <
|
||||||
|
@ -1912,7 +1900,7 @@ static int openssl_handle_peer_certificate(struct single *xfd,
|
||||||
case 16: /* IPv6 */
|
case 16: /* IPv6 */
|
||||||
inet_ntop(AF_INET6, data, aBuffer, sizeof(aBuffer));
|
inet_ntop(AF_INET6, data, aBuffer, sizeof(aBuffer));
|
||||||
if (peername != NULL) {
|
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) {
|
if (memcmp(data, &ip6bin, sizeof(ip6bin)) == 0) {
|
||||||
Debug2("subjectAltName \"%s\" matches peername \"%s\"",
|
Debug2("subjectAltName \"%s\" matches peername \"%s\"",
|
||||||
aBuffer, peername);
|
aBuffer, peername);
|
||||||
|
@ -1964,15 +1952,15 @@ static int openssl_handle_peer_certificate(struct single *xfd,
|
||||||
return status;
|
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;
|
unsigned long err;
|
||||||
|
|
||||||
/* assign a network connection to the SSL object */
|
/* 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");
|
Msg(level, "SSL_set_fd() failed");
|
||||||
while (err = ERR_get_error()) {
|
while (err = ERR_get_error()) {
|
||||||
Msg2(level, "SSL_set_fd(, %d): %s",
|
Msg2(level, "SSL_set_fd(, %d): %s",
|
||||||
xfd->fd, ERR_error_string(err, NULL));
|
sfd->fd, ERR_error_string(err, NULL));
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
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
|
in case of an error condition, this function check forever and retry
|
||||||
options and ev. sleeps an interval. It returns NORETRY when the caller
|
options and ev. sleeps an interval. It returns NORETRY when the caller
|
||||||
should not retry for any reason. */
|
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) {
|
bool opt_ver, int level) {
|
||||||
char error_string[120];
|
char error_string[120];
|
||||||
int errint, status, ret;
|
int errint, status, ret;
|
||||||
unsigned long err;
|
unsigned long err;
|
||||||
|
|
||||||
/* connect via SSL by performing handshake */
|
/* 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");*/
|
/*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) {
|
switch (errint) {
|
||||||
case SSL_ERROR_NONE:
|
case SSL_ERROR_NONE:
|
||||||
/* this is not an error, but I dare not continue for security reasons*/
|
/* 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;
|
break;
|
||||||
case SSL_ERROR_SSL:
|
case SSL_ERROR_SSL:
|
||||||
status = openssl_SSL_ERROR_SSL(level, "SSL_connect");
|
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;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
14
xio-pipe.c
14
xio-pipe.c
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#if WITH_PIPE
|
#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);
|
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 */
|
/* 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;
|
struct single *sfd = &xfd->stream;
|
||||||
const char *pipename = argv[1];
|
const char *pipename = argv[1];
|
||||||
int rw = (xioflags & XIO_ACCMODE);
|
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) {
|
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)
|
if (applyopts_single(sfd, opts, PH_INIT) < 0)
|
||||||
|
|
|
@ -19,7 +19,7 @@ static int _posixmq_unlink(
|
||||||
const char *name,
|
const char *name,
|
||||||
int level); /* message level on error */
|
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_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>") };
|
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,
|
struct opt *opts,
|
||||||
int xioflags,
|
int xioflags,
|
||||||
xiofile_t *xfd,
|
xiofile_t *xfd,
|
||||||
groups_t groups,
|
const struct addrdesc *addrdesc)
|
||||||
int dirs,
|
|
||||||
int oneshot,
|
|
||||||
int dummy3)
|
|
||||||
{
|
{
|
||||||
/* We expect the form: /mqname */
|
/* We expect the form: /mqname */
|
||||||
xiosingle_t *sfd = &xfd->stream;
|
xiosingle_t *sfd = &xfd->stream;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
int dirs = addrdesc->arg1;
|
||||||
|
int oneshot = addrdesc->arg2;
|
||||||
bool opt_unlink_early = false;
|
bool opt_unlink_early = false;
|
||||||
int oflag;
|
int oflag;
|
||||||
bool opt_o_excl = false;
|
bool opt_o_excl = false;
|
||||||
|
@ -61,8 +60,7 @@ static int xioopen_posixmq(
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -312,8 +312,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
|
|
||||||
if (rw != XIO_WRONLY) {
|
if (rw != XIO_WRONLY) {
|
||||||
applyopts_cloexec(rdpip[0], popts);
|
applyopts_cloexec(rdpip[0], popts);
|
||||||
applyopts(NULL, rdpip[0], popts, PH_FD);
|
applyopts(sfd, rdpip[0], popts, PH_FD);
|
||||||
applyopts(NULL, rdpip[1], copts, PH_FD);
|
applyopts(sfd, rdpip[1], copts, PH_FD);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rw != XIO_RDONLY) {
|
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 */
|
/* wrpip[1]: write by socat; wrpip[0]: read by child */
|
||||||
if (rw != XIO_RDONLY) {
|
if (rw != XIO_RDONLY) {
|
||||||
applyopts_cloexec(wrpip[1], popts);
|
applyopts_cloexec(wrpip[1], popts);
|
||||||
applyopts(NULL, wrpip[1], popts, PH_FD);
|
applyopts(sfd, wrpip[1], popts, PH_FD);
|
||||||
applyopts(NULL, wrpip[0], copts, PH_FD);
|
applyopts(sfd, wrpip[0], copts, PH_FD);
|
||||||
}
|
}
|
||||||
if (sfd->howtoend == END_UNSPEC) {
|
if (sfd->howtoend == END_UNSPEC) {
|
||||||
sfd->howtoend = END_CLOSE_KILL;
|
sfd->howtoend = END_CLOSE_KILL;
|
||||||
|
@ -362,19 +362,19 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
popts = opts;
|
popts = opts;
|
||||||
applyopts(NULL, sv[0], copts, PH_PASTSOCKET);
|
applyopts(sfd, sv[0], copts, PH_PASTSOCKET);
|
||||||
applyopts(NULL, sv[1], popts, PH_PASTSOCKET);
|
applyopts(sfd, sv[1], popts, PH_PASTSOCKET);
|
||||||
|
|
||||||
applyopts_cloexec(sv[0], copts);
|
applyopts_cloexec(sv[0], copts);
|
||||||
applyopts(NULL, sv[0], copts, PH_FD);
|
applyopts(sfd, sv[0], copts, PH_FD);
|
||||||
applyopts(NULL, sv[1], popts, PH_FD);
|
applyopts(sfd, sv[1], popts, PH_FD);
|
||||||
|
|
||||||
applyopts(NULL, sv[0], copts, PH_PREBIND);
|
applyopts(sfd, sv[0], copts, PH_PREBIND);
|
||||||
applyopts(NULL, sv[0], copts, PH_BIND);
|
applyopts(sfd, sv[0], copts, PH_BIND);
|
||||||
applyopts(NULL, sv[0], copts, PH_PASTBIND);
|
applyopts(sfd, sv[0], copts, PH_PASTBIND);
|
||||||
applyopts(NULL, sv[1], popts, PH_PREBIND);
|
applyopts(sfd, sv[1], popts, PH_PREBIND);
|
||||||
applyopts(NULL, sv[1], popts, PH_BIND);
|
applyopts(sfd, sv[1], popts, PH_BIND);
|
||||||
applyopts(NULL, sv[1], popts, PH_PASTBIND);
|
applyopts(sfd, sv[1], popts, PH_PASTBIND);
|
||||||
|
|
||||||
if (sfd->howtoend == END_UNSPEC) {
|
if (sfd->howtoend == END_UNSPEC) {
|
||||||
sfd->howtoend = END_SHUTDOWN_KILL;
|
sfd->howtoend = END_SHUTDOWN_KILL;
|
||||||
|
@ -437,7 +437,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* this for child, was after fork */
|
/* this for child, was after fork */
|
||||||
applyopts(NULL, ttyfd, copts, PH_FD);
|
applyopts(sfd, ttyfd, copts, PH_FD);
|
||||||
|
|
||||||
Info1("opened pseudo terminal %s", tn);
|
Info1("opened pseudo terminal %s", tn);
|
||||||
Close(ptyfd);
|
Close(ptyfd);
|
||||||
|
@ -464,8 +464,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
applyopts_cloexec(ttyfd, copts);
|
applyopts_cloexec(ttyfd, copts);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts(NULL, ttyfd, copts, PH_LATE);
|
applyopts(sfd, ttyfd, copts, PH_LATE);
|
||||||
applyopts(NULL, ttyfd, copts, PH_LATE2);
|
applyopts(sfd, ttyfd, copts, PH_LATE2);
|
||||||
} else
|
} else
|
||||||
#endif /* HAVE_PTY */
|
#endif /* HAVE_PTY */
|
||||||
if (usepipes) {
|
if (usepipes) {
|
||||||
|
@ -515,10 +515,10 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
/* applyopts_cloexec(fdi, *copts);*/ /* option is already consumed! */
|
/* applyopts_cloexec(fdi, *copts);*/ /* option is already consumed! */
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts(NULL, fdi, copts, PH_LATE);
|
applyopts(sfd, fdi, copts, PH_LATE);
|
||||||
applyopts(NULL, fdo, copts, PH_LATE);
|
applyopts(sfd, fdo, copts, PH_LATE);
|
||||||
applyopts(NULL, fdi, copts, PH_LATE2);
|
applyopts(sfd, fdi, copts, PH_LATE2);
|
||||||
applyopts(NULL, fdo, copts, PH_LATE2);
|
applyopts(sfd, fdo, copts, PH_LATE2);
|
||||||
|
|
||||||
} else { /* socketpair */
|
} else { /* socketpair */
|
||||||
Close(sv[0]);
|
Close(sv[0]);
|
||||||
|
@ -545,8 +545,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
Close(sv[1]);
|
Close(sv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts(NULL, fdi, copts, PH_LATE);
|
applyopts(sfd, fdi, copts, PH_LATE);
|
||||||
applyopts(NULL, fdi, copts, PH_LATE2);
|
applyopts(sfd, fdi, copts, PH_LATE2);
|
||||||
}
|
}
|
||||||
if (withfork) {
|
if (withfork) {
|
||||||
Info("notifying parent that child process is ready");
|
Info("notifying parent that child process is ready");
|
||||||
|
@ -554,8 +554,8 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
||||||
}
|
}
|
||||||
} /* withfork */
|
} /* withfork */
|
||||||
else {
|
else {
|
||||||
applyopts(NULL, -1, copts, PH_LATE);
|
applyopts(sfd, -1, copts, PH_LATE);
|
||||||
applyopts(NULL, -1, copts, PH_LATE2);
|
applyopts(sfd, -1, copts, PH_LATE2);
|
||||||
}
|
}
|
||||||
_xioopen_setdelayeduser();
|
_xioopen_setdelayeduser();
|
||||||
if (withstderr) {
|
if (withstderr) {
|
||||||
|
|
100
xio-proxy.c
100
xio-proxy.c
|
@ -20,10 +20,7 @@
|
||||||
|
|
||||||
#define PROXYPORT "8080"
|
#define PROXYPORT "8080"
|
||||||
|
|
||||||
static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
|
||||||
int xioflags, xiofile_t *fd,
|
|
||||||
groups_t groups, int dummy1, int dummy2,
|
|
||||||
int dummy3);
|
|
||||||
|
|
||||||
const struct optdesc opt_proxyport = { "proxyport", NULL, OPT_PROXYPORT, GROUP_HTTP, PH_LATE, TYPE_STRING, OFUNC_SPEC };
|
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 };
|
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
|
returns <0 when error occurs
|
||||||
*/
|
*/
|
||||||
static ssize_t
|
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;
|
ssize_t result;
|
||||||
do {
|
do {
|
||||||
/* we need at least buflen bytes... */
|
/* we need at least buflen bytes... */
|
||||||
result = Read(xfd->fd, buff, buflen);
|
result = Read(sfd->fd, buff, buflen);
|
||||||
} while (result < 0 && errno == EINTR); /*! EAGAIN? */
|
} while (result < 0 && errno == EINTR); /*! EAGAIN? */
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
Msg4(level, "read(%d, %p, "F_Zu"): %s",
|
Msg4(level, "read(%d, %p, "F_Zu"): %s",
|
||||||
xfd->fd, buff, buflen, strerror(errno));
|
sfd->fd, buff, buflen, strerror(errno));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
|
@ -78,12 +75,16 @@ static ssize_t
|
||||||
#define BUFLEN 2048
|
#define BUFLEN 2048
|
||||||
|
|
||||||
|
|
||||||
static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_proxy_connect(
|
||||||
int xioflags, xiofile_t *xxfd,
|
int argc,
|
||||||
groups_t groups, int dummy1, int dummy2,
|
const char *argv[],
|
||||||
int dummy3) {
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
/* we expect the form: host:host:port */
|
/* we expect the form: host:host:port */
|
||||||
struct single *xfd = &xxfd->stream;
|
struct single *sfd = &xxfd->stream;
|
||||||
struct opt *opts0 = NULL;
|
struct opt *opts0 = NULL;
|
||||||
struct proxyvars struct_proxyvars = { 0 }, *proxyvars = &struct_proxyvars;
|
struct proxyvars struct_proxyvars = { 0 }, *proxyvars = &struct_proxyvars;
|
||||||
/* variables to be filled with address option values */
|
/* 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;
|
int result;
|
||||||
|
|
||||||
if (argc != 4) {
|
if (argc != 4) {
|
||||||
Error1("%s: 3 parameters required", argv[0]);
|
xio_syntax(argv[0], 3, argc-1, addrdesc->syntax);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
proxyname = argv[1];
|
proxyname = argv[1];
|
||||||
targetname = argv[2];
|
targetname = argv[2];
|
||||||
targetport = argv[3];
|
targetport = argv[3];
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0)
|
||||||
applyopts(xfd, 1, opts, PH_INIT);
|
return -1;
|
||||||
|
applyopts(sfd, 1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
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,
|
result = _xioopen_proxy_prepare(proxyvars, opts, targetname, targetport,
|
||||||
xfd->para.socket.ip.ai_flags);
|
sfd->para.socket.ip.ai_flags);
|
||||||
if (result != STAT_OK)
|
if (result != STAT_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
@ -142,7 +144,7 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
result =
|
result =
|
||||||
_xioopen_ipapp_prepare(opts, &opts0, proxyname, proxyport,
|
_xioopen_ipapp_prepare(opts, &opts0, proxyname, proxyport,
|
||||||
&pf, ipproto,
|
&pf, ipproto,
|
||||||
xfd->para.socket.ip.ai_flags,
|
sfd->para.socket.ip.ai_flags,
|
||||||
&themlist, us, &uslen,
|
&themlist, us, &uslen,
|
||||||
&needbind, &lowport, socktype);
|
&needbind, &lowport, socktype);
|
||||||
if (result != STAT_OK)
|
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",
|
Notice4("opening connection to %s:%u via proxy %s:%s",
|
||||||
proxyvars->targetaddr, proxyvars->targetport, proxyname, proxyport);
|
proxyvars->targetaddr, proxyvars->targetport, proxyname, proxyport);
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
if (xfd->forever || xfd->retry || ai_sorted[i] != NULL) {
|
if (sfd->forever || sfd->retry || ai_sorted[i] != NULL) {
|
||||||
level = E_INFO;
|
level = E_INFO;
|
||||||
} else
|
} else
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
level = E_ERROR;
|
level = E_ERROR;
|
||||||
|
|
||||||
result =
|
result =
|
||||||
_xioopen_connect(xfd,
|
_xioopen_connect(sfd,
|
||||||
needbind?us:NULL, sizeof(*us),
|
needbind?us:NULL, sizeof(*us),
|
||||||
themp->ai_addr, themp->ai_addrlen,
|
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);
|
||||||
|
@ -190,10 +192,10 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
case STAT_RETRYNOW:
|
case STAT_RETRYNOW:
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
--xfd->retry;
|
--sfd->retry;
|
||||||
if (result == STAT_RETRYLATER)
|
if (result == STAT_RETRYLATER)
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
|
@ -204,19 +206,19 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xiofreeaddrinfo(themlist);
|
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;
|
return result;
|
||||||
|
|
||||||
result = _xioopen_proxy_connect(xfd, proxyvars, level);
|
result = _xioopen_proxy_connect(sfd, proxyvars, level);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case STAT_OK: break;
|
case STAT_OK: break;
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
case STAT_RETRYNOW:
|
case STAT_RETRYNOW:
|
||||||
if (xfd->forever || xfd->retry--) {
|
if (sfd->forever || sfd->retry--) {
|
||||||
if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL);
|
if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
|
@ -232,24 +234,24 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
if (dofork) {
|
if (dofork) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int level = E_ERROR;
|
int level = E_ERROR;
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
level = E_WARN;
|
level = E_WARN;
|
||||||
}
|
}
|
||||||
while ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
|
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
|
||||||
if (xfd->forever || --xfd->retry) {
|
if (sfd->forever || --sfd->retry) {
|
||||||
Nanosleep(&xfd->intervall, NULL); continue;
|
Nanosleep(&sfd->intervall, NULL); continue;
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid == 0) { /* child process */
|
if (pid == 0) { /* child process */
|
||||||
xfd->forever = false; xfd->retry = 0;
|
sfd->forever = false; sfd->retry = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parent process */
|
/* parent process */
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
continue;
|
continue;
|
||||||
} else
|
} else
|
||||||
|
@ -357,7 +359,7 @@ int _xioopen_proxy_prepare(
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _xioopen_proxy_connect(struct single *xfd,
|
int _xioopen_proxy_connect(struct single *sfd,
|
||||||
struct proxyvars *proxyvars,
|
struct proxyvars *proxyvars,
|
||||||
int level) {
|
int level) {
|
||||||
size_t offset;
|
size_t offset;
|
||||||
|
@ -387,11 +389,11 @@ int _xioopen_proxy_connect(struct single *xfd,
|
||||||
* xiosanitize(request, strlen(request), textbuff) = '\0';
|
* xiosanitize(request, strlen(request), textbuff) = '\0';
|
||||||
Info1("sending \"%s\"", textbuff);
|
Info1("sending \"%s\"", textbuff);
|
||||||
/* write errors are assumed to always be hard errors, no retry */
|
/* 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",
|
Msg4(level, "write(%d, %p, "F_Zu"): %s",
|
||||||
xfd->fd, request, strlen(request), strerror(errno));
|
sfd->fd, request, strlen(request), strerror(errno));
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
@ -417,11 +419,11 @@ int _xioopen_proxy_connect(struct single *xfd,
|
||||||
*next = '\0';
|
*next = '\0';
|
||||||
Info1("sending \"%s\\r\\n\"", header);
|
Info1("sending \"%s\\r\\n\"", header);
|
||||||
*next++ = '\r'; *next++ = '\n'; *next++ = '\0';
|
*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",
|
Msg4(level, "write(%d, %p, "F_Zu"): %s",
|
||||||
xfd->fd, header, strlen(header), strerror(errno));
|
sfd->fd, header, strlen(header), strerror(errno));
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
@ -430,11 +432,11 @@ int _xioopen_proxy_connect(struct single *xfd,
|
||||||
}
|
}
|
||||||
|
|
||||||
Info("sending \"\\r\\n\"");
|
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",
|
Msg2(level, "write(%d, \"\\r\\n\", 2): %s",
|
||||||
xfd->fd, strerror(errno));
|
sfd->fd, strerror(errno));
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
@ -450,7 +452,7 @@ int _xioopen_proxy_connect(struct single *xfd,
|
||||||
offset = 0; /* up to where the buffer is filled (relative) */
|
offset = 0; /* up to where the buffer is filled (relative) */
|
||||||
/*eol;*/ /* points to the first lineterm of the current line */
|
/*eol;*/ /* points to the first lineterm of the current line */
|
||||||
do {
|
do {
|
||||||
sresult = xioproxy_recvbytes(xfd, buff+offset, 1, level);
|
sresult = xioproxy_recvbytes(sfd, buff+offset, 1, level);
|
||||||
if (sresult <= 0) {
|
if (sresult <= 0) {
|
||||||
state = XIOSTATE_ERROR;
|
state = XIOSTATE_ERROR;
|
||||||
break; /* leave read cycles */
|
break; /* leave read cycles */
|
||||||
|
|
14
xio-pty.c
14
xio-pty.c
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#define MAXPTYNAMELEN 64
|
#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("") };
|
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 };
|
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 */
|
#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 */
|
/* we expect the form: filename */
|
||||||
struct single *sfd = &xfd->stream;
|
struct single *sfd = &xfd->stream;
|
||||||
int ptyfd = -1, ttyfd = -1;
|
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 };
|
struct timespec pollintv = { PTY_INTERVALL };
|
||||||
|
|
||||||
if (argc != 1) {
|
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;
|
sfd->howtoend = END_CLOSE;
|
||||||
|
|
143
xio-rawip.c
143
xio-rawip.c
|
@ -17,22 +17,10 @@
|
||||||
#include "xio-rawip.h"
|
#include "xio-rawip.h"
|
||||||
|
|
||||||
|
|
||||||
static
|
static int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
|
||||||
int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_rawip_datagram(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
|
||||||
int xioflags, xiofile_t *fd, groups_t groups, int pf,
|
static int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
int dummy2, int dummy3);
|
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_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
|
static
|
||||||
int _xioopen_rawip_sendto(const char *hostname, const char *protname,
|
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 */
|
/* we expect the form: host:protocol */
|
||||||
/* struct sockaddr_in sa;*/
|
/* struct sockaddr_in sa;*/
|
||||||
/* socklen_t salen;*/
|
/* socklen_t salen;*/
|
||||||
static
|
static int xioopen_rawip_sendto(
|
||||||
int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts,
|
int argc,
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
const char *argv[],
|
||||||
int pf, int dummy2, int dummy3) {
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
|
int pf = addrdesc->arg1;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 2)",
|
xio_syntax(argv[0], 2, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
xioinit_ip(&pf, xioparms.preferred_ip);
|
xioinit_ip(&pf, xioparms.preferred_ip);
|
||||||
if ((result = _xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd,
|
if ((result = _xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd,
|
||||||
groups, &pf)) != STAT_OK) {
|
addrdesc->groups, &pf)) != STAT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
_xio_openlate(&xxfd->stream, opts);
|
_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,
|
struct opt *opts, int xioflags, xiofile_t *xxfd,
|
||||||
groups_t groups, int *pf) {
|
groups_t groups, int *pf) {
|
||||||
char *garbage;
|
char *garbage;
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
xiosingle_t *sfd = &xxfd->stream;
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
int feats = 1; /* option bind supports only address, not port */
|
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;*/
|
/*return STAT_NORETRY;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
retropt_int(opts, OPT_PROTOCOL_FAMILY, pf);
|
retropt_int(opts, OPT_PROTOCOL_FAMILY, pf);
|
||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(xfd, -1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
xfd->salen = sizeof(xfd->peersa);
|
sfd->salen = sizeof(sfd->peersa);
|
||||||
if ((result =
|
if ((result =
|
||||||
xioresolve(hostname, NULL, *pf, socktype, ipproto,
|
xioresolve(hostname, NULL, *pf, socktype, ipproto,
|
||||||
&xfd->peersa, &xfd->salen,
|
&sfd->peersa, &sfd->salen,
|
||||||
xfd->para.socket.ip.ai_flags))
|
sfd->para.socket.ip.ai_flags))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (*pf == PF_UNSPEC) {
|
if (*pf == PF_UNSPEC) {
|
||||||
*pf = xfd->peersa.soa.sa_family;
|
*pf = sfd->peersa.soa.sa_family;
|
||||||
}
|
}
|
||||||
|
|
||||||
uslen = socket_init(*pf, &us);
|
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,
|
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) {
|
!= STAT_NOACTION) {
|
||||||
needbind = true;
|
needbind = true;
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
_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 */
|
/* we expect the form: address:protocol */
|
||||||
static
|
static int xioopen_rawip_datagram(
|
||||||
int xioopen_rawip_datagram(int argc, const char *argv[], struct opt *opts,
|
int argc,
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
const char *argv[],
|
||||||
int pf, int dummy2, int dummy3) {
|
struct opt *opts,
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
|
xiosingle_t *sfd = &xxfd->stream;
|
||||||
|
int pf = addrdesc->arg1;
|
||||||
char *rangename;
|
char *rangename;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 2)",
|
xio_syntax(argv[0], 2, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
xioinit_ip(&pf, xioparms.preferred_ip);
|
xioinit_ip(&pf, xioparms.preferred_ip);
|
||||||
if ((result =
|
if ((result =
|
||||||
_xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd,
|
_xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd,
|
||||||
groups, &pf)) != STAT_OK) {
|
addrdesc->groups, &pf)) != STAT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
|
sfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
|
||||||
if (pf == PF_INET) {
|
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 */
|
/* which reply packets will be accepted - determine by range option */
|
||||||
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
||||||
if (xioparserange(rangename, pf, &xfd->para.socket.range,
|
if (xioparserange(rangename, pf, &sfd->para.socket.range,
|
||||||
xfd->para.socket.ip.ai_flags)
|
sfd->para.socket.ip.ai_flags)
|
||||||
< 0) {
|
< 0) {
|
||||||
free(rangename);
|
free(rangename);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
xfd->para.socket.dorange = true;
|
sfd->para.socket.dorange = true;
|
||||||
xfd->dtype |= XIOREAD_RECV_CHECKRANGE;
|
sfd->dtype |= XIOREAD_RECV_CHECKRANGE;
|
||||||
free(rangename);
|
free(rangename);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WITH_LIBWRAP
|
#if WITH_LIBWRAP
|
||||||
xio_retropt_tcpwrap(xfd, opts);
|
xio_retropt_tcpwrap(sfd, opts);
|
||||||
#endif /* WITH_LIBWRAP */
|
#endif /* WITH_LIBWRAP */
|
||||||
|
|
||||||
_xio_openlate(xfd, opts);
|
_xio_openlate(sfd, opts);
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static int xioopen_rawip_recvfrom(
|
||||||
int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts,
|
int argc,
|
||||||
int xioflags, xiofile_t *xfd, groups_t groups,
|
const char *argv[],
|
||||||
int pf, int socktype, int dummy3) {
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
|
struct single *sfd = &xfd->stream;
|
||||||
const char *protname = argv[1];
|
const char *protname = argv[1];
|
||||||
|
int pf = addrdesc->arg1;
|
||||||
|
int socktype = addrdesc->arg2;
|
||||||
char *garbage;
|
char *garbage;
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
socklen_t uslen = sizeof(us);
|
socklen_t uslen = sizeof(us);
|
||||||
|
@ -211,8 +214,7 @@ int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts,
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,7 +228,7 @@ int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts,
|
||||||
protname);
|
protname);
|
||||||
/*return STAT_NORETRY;*/
|
/*return STAT_NORETRY;*/
|
||||||
}
|
}
|
||||||
xfd->stream.howtoend = END_NONE;
|
sfd->howtoend = END_NONE;
|
||||||
|
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
if (pf == PF_UNSPEC) {
|
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,
|
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) {
|
!= STAT_NOACTION) {
|
||||||
needbind = true;
|
needbind = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->stream.dtype = XIODATA_RECVFROM_SKIPIP_ONE;
|
sfd->dtype = XIODATA_RECVFROM_SKIPIP_ONE;
|
||||||
if ((result =
|
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))
|
uslen, opts, pf, socktype, ipproto, E_ERROR))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
_xio_openlate(&xfd->stream, opts);
|
_xio_openlate(sfd, opts);
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static int xioopen_rawip_recv(
|
||||||
int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts,
|
int argc,
|
||||||
int xioflags, xiofile_t *xfd, groups_t groups,
|
const char *argv[],
|
||||||
int pf, int socktype, int dummy3) {
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
const char *protname = argv[1];
|
const char *protname = argv[1];
|
||||||
|
int pf = addrdesc->arg1;
|
||||||
|
int socktype = addrdesc->arg2;
|
||||||
char *garbage;
|
char *garbage;
|
||||||
bool needbind = false;
|
bool needbind = false;
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
|
@ -274,8 +282,7 @@ int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,7 @@ uses stdin!!
|
||||||
/* length of buffer for dynamic prompt */
|
/* length of buffer for dynamic prompt */
|
||||||
#define READLINE_MAXPROMPT 512
|
#define READLINE_MAXPROMPT 512
|
||||||
|
|
||||||
static int xioopen_readline(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_readline(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
int rw, xiofile_t *xfd, groups_t groups,
|
|
||||||
int dummy1, int dummy2, int dummy3);
|
|
||||||
|
|
||||||
|
|
||||||
const struct addrdesc xioaddr_readline = { "READLINE", 3, xioopen_readline, GROUP_FD|GROUP_TERMIOS|GROUP_READLINE, 0, 0, 0 HELP(NULL) };
|
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_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 };
|
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,
|
static int xioopen_readline(
|
||||||
int xioflags, xiofile_t *xfd, groups_t groups,
|
int argc,
|
||||||
int dummy1, int dummy2, int dummy3) {
|
const char *argv[],
|
||||||
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
struct single *sfd = &xfd->stream;
|
struct single *sfd = &xfd->stream;
|
||||||
int rw = (xioflags & XIO_ACCMODE);
|
int rw = (xioflags & XIO_ACCMODE);
|
||||||
char msgbuf[256], *cp = msgbuf;
|
char msgbuf[256], *cp = msgbuf;
|
||||||
|
@ -47,7 +50,7 @@ static int xioopen_readline(int argc, const char *argv[], struct opt *opts,
|
||||||
char *noecho = NULL;
|
char *noecho = NULL;
|
||||||
|
|
||||||
if (argc != 1) {
|
if (argc != 1) {
|
||||||
Error1("%s: 0 parameters required", argv[0]);
|
xio_syntax(argv[0], 0, argc-1, addrdesc->syntax);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
338
xio-socket.c
338
xio-socket.c
|
@ -30,30 +30,12 @@
|
||||||
#include "xio-tcpwrap.h"
|
#include "xio-tcpwrap.h"
|
||||||
|
|
||||||
|
|
||||||
static
|
static int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
int xioflags, xiofile_t *xfd, groups_t groups,
|
static int xioopen_socket_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
int dummy1, int dummy2, int dummy3);
|
static int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
static
|
static int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
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
|
static
|
||||||
int _xioopen_socket_sendto(const char *pfname, const char *type,
|
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 *envbuff, int envlen,
|
||||||
char *valbuff, int vallen);
|
char *valbuff, int vallen);
|
||||||
static int xiobind(
|
static int xiobind(
|
||||||
struct single *xfd,
|
struct single *sfd,
|
||||||
union sockaddr_union *us,
|
union sockaddr_union *us,
|
||||||
size_t uslen,
|
size_t uslen,
|
||||||
struct opt *opts,
|
struct opt *opts,
|
||||||
|
@ -215,10 +197,14 @@ const struct optdesc opt_null_eof = { "null-eof", NULL, OPT_NULL_EOF, GROUP_SOCK
|
||||||
|
|
||||||
#if WITH_GENERICSOCKET
|
#if WITH_GENERICSOCKET
|
||||||
|
|
||||||
static
|
static int xioopen_socket_connect(
|
||||||
int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts,
|
int argc,
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
const char *argv[],
|
||||||
int dummy1, int dummy2, int dummy3) {
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
struct single *sfd = &xxfd->stream;
|
struct single *sfd = &xxfd->stream;
|
||||||
const char *pfname = argv[1];
|
const char *pfname = argv[1];
|
||||||
const char *protname = argv[2];
|
const char *protname = argv[2];
|
||||||
|
@ -233,8 +219,7 @@ int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 4) {
|
if (argc != 4) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 3)",
|
xio_syntax(argv[0], 3, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,10 +282,14 @@ int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WITH_LISTEN
|
#if WITH_LISTEN
|
||||||
static
|
static int xioopen_socket_listen(
|
||||||
int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts,
|
int argc,
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
const char *argv[],
|
||||||
int dummy1, int dummy2, int dummy3) {
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
struct single *sfd = &xxfd->stream;
|
struct single *sfd = &xxfd->stream;
|
||||||
const char *pfname = argv[1];
|
const char *pfname = argv[1];
|
||||||
const char *protname = argv[2];
|
const char *protname = argv[2];
|
||||||
|
@ -314,8 +303,7 @@ int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 4) {
|
if (argc != 4) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 3)",
|
xio_syntax(argv[0], 3, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,20 +356,23 @@ int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
#endif /* WITH_LISTEN */
|
#endif /* WITH_LISTEN */
|
||||||
|
|
||||||
/* we expect the form: ...:domain:type:protocol:remote-address */
|
/* we expect the form: ...:domain:type:protocol:remote-address */
|
||||||
static
|
static int xioopen_socket_sendto(
|
||||||
int xioopen_socket_sendto(int argc, const char *argv[], struct opt *opts,
|
int argc,
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
const char *argv[],
|
||||||
int dummy1, int dummy2, int dummy3) {
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 5) {
|
if (argc != 5) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 4)",
|
xio_syntax(argv[0], 4, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
if ((result =
|
if ((result =
|
||||||
_xioopen_socket_sendto(argv[1], argv[2], argv[3], argv[4],
|
_xioopen_socket_sendto(argv[1], argv[2], argv[3], argv[4],
|
||||||
opts, xioflags, xxfd, groups))
|
opts, xioflags, xxfd, addrdesc->groups))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return result;
|
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 */
|
/* we expect the form: ...:domain:socktype:protocol:local-address */
|
||||||
static
|
static
|
||||||
int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts,
|
int xioopen_socket_recvfrom(
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
int argc,
|
||||||
int dummy, int summy2, int dummy3) {
|
const char *argv[],
|
||||||
struct single *xfd = &xxfd->stream;
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
|
struct single *sfd = &xxfd->stream;
|
||||||
const char *pfname = argv[1];
|
const char *pfname = argv[1];
|
||||||
const char *typename = argv[2];
|
const char *typename = argv[2];
|
||||||
const char *protname = argv[3];
|
const char *protname = argv[3];
|
||||||
const char *address = argv[4];
|
const char *address = argv[4];
|
||||||
char *garbage;
|
char *garbage;
|
||||||
union sockaddr_union *us = &xfd->para.socket.la;
|
union sockaddr_union *us = &sfd->para.socket.la;
|
||||||
socklen_t uslen; size_t ussize;
|
socklen_t uslen; size_t ussize;
|
||||||
int pf, socktype, proto;
|
int pf, socktype, proto;
|
||||||
char *rangename;
|
char *rangename;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 5) {
|
if (argc != 5) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 4)",
|
xio_syntax(argv[0], 4, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
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_socket_pf(opts, &pf);
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
|
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
|
||||||
xfd->howtoend = END_NONE;
|
sfd->howtoend = END_NONE;
|
||||||
|
|
||||||
ussize = 0;
|
ussize = 0;
|
||||||
if ((result =
|
if ((result =
|
||||||
|
@ -537,35 +532,40 @@ int xioopen_socket_recvfrom(int argc, const char *argv[], struct opt *opts,
|
||||||
+ sizeof(us->soa.sa_len);
|
+ sizeof(us->soa.sa_len);
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
xfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
|
sfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO;
|
||||||
|
|
||||||
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
||||||
if (xioparserange(rangename, 0, &xfd->para.socket.range,
|
if (xioparserange(rangename, 0, &sfd->para.socket.range,
|
||||||
xfd->para.socket.ip.ai_flags)
|
sfd->para.socket.ip.ai_flags)
|
||||||
< 0) {
|
< 0) {
|
||||||
free(rangename);
|
free(rangename);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
xfd->para.socket.dorange = true;
|
sfd->para.socket.dorange = true;
|
||||||
free(rangename);
|
free(rangename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result =
|
if ((result =
|
||||||
_xioopen_dgram_recvfrom(xfd, xioflags, &us->soa, uslen,
|
_xioopen_dgram_recvfrom(sfd, xioflags, &us->soa, uslen,
|
||||||
opts, pf, socktype, proto, E_ERROR))
|
opts, pf, socktype, proto, E_ERROR))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
_xio_openlate(xfd, opts);
|
_xio_openlate(sfd, opts);
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we expect the form: ...:domain:type:protocol:local-address */
|
/* we expect the form: ...:domain:type:protocol:local-address */
|
||||||
static
|
static
|
||||||
int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts,
|
int xioopen_socket_recv(
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
int argc,
|
||||||
int dummy1, int dummy2, int dummy3) {
|
const char *argv[],
|
||||||
struct single *xfd = &xxfd->stream;
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
|
struct single *sfd = &xxfd->stream;
|
||||||
const char *pfname = argv[1];
|
const char *pfname = argv[1];
|
||||||
const char *typename = argv[2];
|
const char *typename = argv[2];
|
||||||
const char *protname = argv[3];
|
const char *protname = argv[3];
|
||||||
|
@ -578,8 +578,7 @@ int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 5) {
|
if (argc != 5) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 4)",
|
xio_syntax(argv[0], 4, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
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_socket_pf(opts, &pf);
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
|
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
|
||||||
xfd->howtoend = END_NONE;
|
sfd->howtoend = END_NONE;
|
||||||
|
|
||||||
ussize = 0;
|
ussize = 0;
|
||||||
if ((result =
|
if ((result =
|
||||||
|
@ -617,37 +616,41 @@ int xioopen_socket_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
+sizeof(us.soa.sa_len)
|
+sizeof(us.soa.sa_len)
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
xfd->dtype = XIOREAD_RECV;
|
sfd->dtype = XIOREAD_RECV;
|
||||||
xfd->para.socket.la.soa.sa_family = pf;
|
sfd->para.socket.la.soa.sa_family = pf;
|
||||||
|
|
||||||
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
||||||
if (xioparserange(rangename, 0, &xfd->para.socket.range,
|
if (xioparserange(rangename, 0, &sfd->para.socket.range,
|
||||||
xfd->para.socket.ip.ai_flags)
|
sfd->para.socket.ip.ai_flags)
|
||||||
< 0) {
|
< 0) {
|
||||||
free(rangename);
|
free(rangename);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
xfd->para.socket.dorange = true;
|
sfd->para.socket.dorange = true;
|
||||||
free(rangename);
|
free(rangename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result =
|
if ((result =
|
||||||
_xioopen_dgram_recv(xfd, xioflags, &us.soa,
|
_xioopen_dgram_recv(sfd, xioflags, &us.soa,
|
||||||
uslen, opts, pf, socktype, proto, E_ERROR))
|
uslen, opts, pf, socktype, proto, E_ERROR))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
_xio_openlate(xfd, opts);
|
_xio_openlate(sfd, opts);
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* we expect the form: ...:domain:type:protocol:remote-address */
|
/* we expect the form: ...:domain:type:protocol:remote-address */
|
||||||
static
|
static int xioopen_socket_datagram(
|
||||||
int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts,
|
int argc,
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
const char *argv[],
|
||||||
int dummy1, int dummy2, int dummy3) {
|
struct opt *opts,
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
|
xiosingle_t *sfd = &xxfd->stream;
|
||||||
const char *pfname = argv[1];
|
const char *pfname = argv[1];
|
||||||
const char *typename = argv[2];
|
const char *typename = argv[2];
|
||||||
const char *protname = argv[3];
|
const char *protname = argv[3];
|
||||||
|
@ -659,8 +662,7 @@ int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts,
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 5) {
|
if (argc != 5) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 4)",
|
xio_syntax(argv[0], 4, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
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_socket_pf(opts, &pf);
|
||||||
/*retropt_int(opts, OPT_IP_PROTOCOL, &proto);*/
|
/*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;
|
themsize = 0;
|
||||||
if ((result =
|
if ((result =
|
||||||
dalan(address, (uint8_t *)&xfd->peersa.soa.sa_data, &themsize,
|
dalan(address, (uint8_t *)&sfd->peersa.soa.sa_data, &themsize,
|
||||||
sizeof(xfd->peersa), 'i'))
|
sizeof(sfd->peersa), 'i'))
|
||||||
< 0) {
|
< 0) {
|
||||||
Error1("data too long: \"%s\"", address);
|
Error1("data too long: \"%s\"", address);
|
||||||
} else if (result > 0) {
|
} else if (result > 0) {
|
||||||
Error1("syntax error in \"%s\"", address);
|
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
|
#if HAVE_STRUCT_SOCKADDR_SALEN
|
||||||
xfd->peersa.soa.sa_len =
|
sfd->peersa.soa.sa_len =
|
||||||
sizeof(xfd->peersa.soa.sa_len) + sizeof(xfd->peersa.soa.sa_family) +
|
sizeof(sfd->peersa.soa.sa_len) + sizeof(sfd->peersa.soa.sa_family) +
|
||||||
themsize;
|
themsize;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((result =
|
if ((result =
|
||||||
_xioopen_socket_sendto(pfname, typename, protname, address,
|
_xioopen_socket_sendto(pfname, typename, protname, address,
|
||||||
opts, xioflags, xxfd, groups))
|
opts, xioflags, xxfd, addrdesc->groups))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return result;
|
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 */
|
/* which reply sockets will accept - determine by range option */
|
||||||
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
||||||
if (xioparserange(rangename, 0, &xfd->para.socket.range,
|
if (xioparserange(rangename, 0, &sfd->para.socket.range,
|
||||||
xfd->para.socket.ip.ai_flags)
|
sfd->para.socket.ip.ai_flags)
|
||||||
< 0) {
|
< 0) {
|
||||||
free(rangename);
|
free(rangename);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
xfd->para.socket.dorange = true;
|
sfd->para.socket.dorange = true;
|
||||||
xfd->dtype |= XIOREAD_RECV_CHECKRANGE;
|
sfd->dtype |= XIOREAD_RECV_CHECKRANGE;
|
||||||
free(rangename);
|
free(rangename);
|
||||||
}
|
}
|
||||||
|
|
||||||
_xio_openlate(xfd, opts);
|
_xio_openlate(sfd, opts);
|
||||||
return STAT_OK;
|
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
|
OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC
|
||||||
returns 0 on success.
|
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 sockaddr *them, size_t themlen,
|
||||||
struct opt *opts, int pf, int socktype, int protocol,
|
struct opt *opts, int pf, int socktype, int protocol,
|
||||||
bool alt) {
|
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 */
|
do { /* loop over retries and forks */
|
||||||
|
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
level = E_INFO;
|
level = E_INFO;
|
||||||
} else
|
} else
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
level = E_ERROR;
|
level = E_ERROR;
|
||||||
result =
|
result =
|
||||||
_xioopen_connect(xfd, us, uslen, them, themlen, opts,
|
_xioopen_connect(sfd, us, uslen, them, themlen, opts,
|
||||||
pf, socktype, protocol, alt, level);
|
pf, socktype, protocol, alt, level);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case STAT_OK: break;
|
case STAT_OK: break;
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
--xfd->retry;
|
--sfd->retry;
|
||||||
if (result == STAT_RETRYLATER) {
|
if (result == STAT_RETRYLATER) {
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
}
|
}
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
continue;
|
continue;
|
||||||
|
@ -997,16 +999,16 @@ int xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen,
|
||||||
if (dofork) {
|
if (dofork) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int level = E_ERROR;
|
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,
|
level = E_WARN; /* most users won't expect a problem here,
|
||||||
so Notice is too weak */
|
so Notice is too weak */
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
|
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
|
||||||
--xfd->retry;
|
--sfd->retry;
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
Nanosleep(&xfd->intervall, NULL); continue;
|
Nanosleep(&sfd->intervall, NULL); continue;
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
@ -1016,9 +1018,9 @@ int xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parent process */
|
/* parent process */
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
/* with and without retry */
|
/* with and without retry */
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
continue; /* with next socket() bind() connect() */
|
continue; /* with next socket() bind() connect() */
|
||||||
} else
|
} 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
|
OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, cloexec, OPT_RANGE, tcpwrap
|
||||||
EINTR is not handled specially.
|
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 sockaddr *us, socklen_t uslen,
|
||||||
struct opt *opts,
|
struct opt *opts,
|
||||||
int pf, int socktype, int proto, int level) {
|
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");
|
Error("option fork not allowed here");
|
||||||
return STAT_NORETRY;
|
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;
|
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) {
|
opts, pf, 0, level) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts(xfd, -1, opts, PH_PASTBIND);
|
applyopts(sfd, -1, opts, PH_PASTBIND);
|
||||||
|
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
if (pf == AF_UNIX && us != NULL) {
|
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 */
|
/* for generic sockets, this has already been retrieved */
|
||||||
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
||||||
if (xioparserange(rangename, pf, &xfd->para.socket.range,
|
if (xioparserange(rangename, pf, &sfd->para.socket.range,
|
||||||
xfd->para.socket.ip.ai_flags)
|
sfd->para.socket.ip.ai_flags)
|
||||||
< 0) {
|
< 0) {
|
||||||
free(rangename);
|
free(rangename);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
free(rangename);
|
free(rangename);
|
||||||
xfd->para.socket.dorange = true;
|
sfd->para.socket.dorange = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
|
#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
|
||||||
xio_retropt_tcpwrap(xfd, opts);
|
xio_retropt_tcpwrap(sfd, opts);
|
||||||
#endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */
|
#endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */
|
||||||
|
|
||||||
if (xioparms.logopt == 'm') {
|
if (xioparms.logopt == 'm') {
|
||||||
|
@ -1215,7 +1217,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
if (drop) {
|
if (drop) {
|
||||||
char *dummy[2];
|
char *dummy[2];
|
||||||
|
|
||||||
Recv(xfd->fd, dummy, sizeof(dummy), 0);
|
Recv(sfd->fd, dummy, sizeof(dummy), 0);
|
||||||
drop = true;
|
drop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1229,7 +1231,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
} else {
|
} else {
|
||||||
Notice1("receiving IP protocol %u", proto);
|
Notice1("receiving IP protocol %u", proto);
|
||||||
}
|
}
|
||||||
readfd.fd = xfd->fd;
|
readfd.fd = sfd->fd;
|
||||||
readfd.events = POLLIN;
|
readfd.events = POLLIN;
|
||||||
if (xiopoll(&readfd, 1, NULL) > 0) {
|
if (xiopoll(&readfd, 1, NULL) > 0) {
|
||||||
break;
|
break;
|
||||||
|
@ -1239,8 +1241,8 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Msg2(level, "poll({%d,,},,-1): %s", xfd->fd, strerror(errno));
|
Msg2(level, "poll({%d,,},,-1): %s", sfd->fd, strerror(errno));
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
} while (true);
|
} while (true);
|
||||||
|
|
||||||
|
@ -1252,7 +1254,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN
|
#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN
|
||||||
msgh.msg_controllen = sizeof(ctrlbuff);
|
msgh.msg_controllen = sizeof(ctrlbuff);
|
||||||
#endif
|
#endif
|
||||||
while ((rc = xiogetancillary(xfd->fd,
|
while ((rc = xiogetancillary(sfd->fd,
|
||||||
&msgh,
|
&msgh,
|
||||||
MSG_PEEK
|
MSG_PEEK
|
||||||
#ifdef MSG_TRUNC
|
#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(&pa->soa, palen, peername, sizeof(peername))/*,
|
||||||
sockaddr_info(&la->soa, sockname, sizeof(sockname))*/);
|
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 */
|
/* drop packet */
|
||||||
char buff[512];
|
char buff[512];
|
||||||
Recv(xfd->fd, buff, sizeof(buff), 0);
|
Recv(sfd->fd, buff, sizeof(buff), 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Info1("permitting packet from %s",
|
Info1("permitting packet from %s",
|
||||||
|
@ -1283,12 +1285,12 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
/*xiosetsockaddrenv("SOCK", la, lalen, proto);*/
|
/*xiosetsockaddrenv("SOCK", la, lalen, proto);*/
|
||||||
xiosetsockaddrenv("PEER", pa, palen, 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;
|
sfd->peersa = *(union sockaddr_union *)pa;
|
||||||
xfd->salen = palen;
|
sfd->salen = palen;
|
||||||
|
|
||||||
if (dofork) {
|
if (dofork) {
|
||||||
Info("Generating socketpair that triggers parent when packet has been consumed");
|
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));
|
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[0]);
|
||||||
Close(trigger[1]);
|
Close(trigger[1]);
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid == 0) { /* child */
|
if (pid == 0) { /* child */
|
||||||
Close(trigger[0]);
|
Close(trigger[0]);
|
||||||
xfd->triggerfd = trigger[1];
|
sfd->triggerfd = trigger[1];
|
||||||
Fcntl_l(xfd->triggerfd, F_SETFD, FD_CLOEXEC);
|
Fcntl_l(sfd->triggerfd, F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
/* !? */
|
/* !? */
|
||||||
xfd->retry = 0;
|
sfd->retry = 0;
|
||||||
xfd->forever = 0;
|
sfd->forever = 0;
|
||||||
level = E_ERROR;
|
level = E_ERROR;
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
|
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
/* with UNIX sockets: only listening parent is allowed to remove
|
/* with UNIX sockets: only listening parent is allowed to remove
|
||||||
the socket file */
|
the socket file */
|
||||||
xfd->opt_unlink_close = false;
|
sfd->opt_unlink_close = false;
|
||||||
#endif /* WITH_UNIX */
|
#endif /* WITH_UNIX */
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1337,7 +1339,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((result = _xio_openlate(xfd, opts)) != 0)
|
if ((result = _xio_openlate(sfd, opts)) != 0)
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
|
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
|
@ -1345,23 +1347,23 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
|
|
||||||
|
|
||||||
/* returns STAT_* */
|
/* 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 sockaddr *us, socklen_t uslen,
|
||||||
struct opt *opts, int pf, int socktype, int proto,
|
struct opt *opts, int pf, int socktype, int proto,
|
||||||
int level) {
|
int level) {
|
||||||
char *rangename;
|
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;
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1375,19 +1377,19 @@ int _xioopen_dgram_recv(struct single *xfd, int xioflags,
|
||||||
|
|
||||||
#if WITH_IP4 /*|| WITH_IP6*/
|
#if WITH_IP4 /*|| WITH_IP6*/
|
||||||
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
||||||
if (xioparserange(rangename, pf, &xfd->para.socket.range,
|
if (xioparserange(rangename, pf, &sfd->para.socket.range,
|
||||||
xfd->para.socket.ip.ai_flags)
|
sfd->para.socket.ip.ai_flags)
|
||||||
< 0) {
|
< 0) {
|
||||||
free(rangename);
|
free(rangename);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
free(rangename);
|
free(rangename);
|
||||||
xfd->para.socket.dorange = true;
|
sfd->para.socket.dorange = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
|
#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
|
||||||
xio_retropt_tcpwrap(xfd, opts);
|
xio_retropt_tcpwrap(sfd, opts);
|
||||||
#endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */
|
#endif /* && (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */
|
||||||
|
|
||||||
if (xioparms.logopt == 'm') {
|
if (xioparms.logopt == 'm') {
|
||||||
|
@ -1599,15 +1601,15 @@ int xiocheckrange(union sockaddr_union *sa, struct xiorange *range) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xiocheckpeer(xiosingle_t *xfd,
|
int xiocheckpeer(xiosingle_t *sfd,
|
||||||
union sockaddr_union *pa, union sockaddr_union *la) {
|
union sockaddr_union *pa, union sockaddr_union *la) {
|
||||||
char infobuff[256];
|
char infobuff[256];
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
#if WITH_IP4
|
#if WITH_IP4
|
||||||
if (xfd->para.socket.dorange) {
|
if (sfd->para.socket.dorange) {
|
||||||
if (pa == NULL) { return -1; }
|
if (pa == NULL) { return -1; }
|
||||||
if (xiocheckrange(pa, &xfd->para.socket.range) < 0) {
|
if (xiocheckrange(pa, &sfd->para.socket.range) < 0) {
|
||||||
char infobuff[256];
|
char infobuff[256];
|
||||||
Warn1("refusing connection from %s due to range option",
|
Warn1("refusing connection from %s due to range option",
|
||||||
sockaddr_info(&pa->soa, 0,
|
sockaddr_info(&pa->soa, 0,
|
||||||
|
@ -1621,11 +1623,11 @@ int xiocheckpeer(xiosingle_t *xfd,
|
||||||
#endif /* WITH_IP4 */
|
#endif /* WITH_IP4 */
|
||||||
|
|
||||||
#if WITH_TCP || WITH_UDP
|
#if WITH_TCP || WITH_UDP
|
||||||
if (xfd->para.socket.ip.dosourceport) {
|
if (sfd->para.socket.ip.dosourceport) {
|
||||||
if (pa == NULL) { return -1; }
|
if (pa == NULL) { return -1; }
|
||||||
#if WITH_IP4
|
#if WITH_IP4
|
||||||
if (pa->soa.sa_family == AF_INET &&
|
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",
|
Warn1("refusing connection from %s due to wrong sourceport",
|
||||||
sockaddr_info(&pa->soa, 0,
|
sockaddr_info(&pa->soa, 0,
|
||||||
infobuff, sizeof(infobuff)));
|
infobuff, sizeof(infobuff)));
|
||||||
|
@ -1634,7 +1636,7 @@ int xiocheckpeer(xiosingle_t *xfd,
|
||||||
#endif /* WITH_IP4 */
|
#endif /* WITH_IP4 */
|
||||||
#if WITH_IP6
|
#if WITH_IP6
|
||||||
if (pa->soa.sa_family == AF_INET6 &&
|
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",
|
Warn1("refusing connection from %s due to wrong sourceport",
|
||||||
sockaddr_info(&pa->soa, 0,
|
sockaddr_info(&pa->soa, 0,
|
||||||
infobuff, sizeof(infobuff)));
|
infobuff, sizeof(infobuff)));
|
||||||
|
@ -1644,7 +1646,7 @@ int xiocheckpeer(xiosingle_t *xfd,
|
||||||
Info1("permitting connection from %s due to sourceport option",
|
Info1("permitting connection from %s due to sourceport option",
|
||||||
sockaddr_info(&pa->soa, 0,
|
sockaddr_info(&pa->soa, 0,
|
||||||
infobuff, sizeof(infobuff)));
|
infobuff, sizeof(infobuff)));
|
||||||
} else if (xfd->para.socket.ip.lowport) {
|
} else if (sfd->para.socket.ip.lowport) {
|
||||||
if (pa == NULL) { return -1; }
|
if (pa == NULL) { return -1; }
|
||||||
if (pa->soa.sa_family == AF_INET &&
|
if (pa->soa.sa_family == AF_INET &&
|
||||||
ntohs(((struct sockaddr_in *)pa)->sin_port) >= IPPORT_RESERVED) {
|
ntohs(((struct sockaddr_in *)pa)->sin_port) >= IPPORT_RESERVED) {
|
||||||
|
@ -1670,7 +1672,7 @@ int xiocheckpeer(xiosingle_t *xfd,
|
||||||
#endif /* WITH_TCP || WITH_UDP */
|
#endif /* WITH_TCP || WITH_UDP */
|
||||||
|
|
||||||
#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
|
#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
|
||||||
result = xio_tcpwrap_check(xfd, la, pa);
|
result = xio_tcpwrap_check(sfd, la, pa);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
char infobuff[256];
|
char infobuff[256];
|
||||||
Warn1("refusing connection from %s due to tcpwrapper option",
|
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(
|
int xiobind(
|
||||||
struct single *xfd,
|
struct single *sfd,
|
||||||
union sockaddr_union *us,
|
union sockaddr_union *us,
|
||||||
size_t uslen,
|
size_t uslen,
|
||||||
struct opt *opts,
|
struct opt *opts,
|
||||||
|
@ -2068,8 +2070,8 @@ int xiobind(
|
||||||
applyopts_named(us->un.sun_path, opts, PH_PREOPEN);
|
applyopts_named(us->un.sun_path, opts, PH_PREOPEN);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
applyopts(xfd, xfd->fd, opts, PH_PREBIND);
|
applyopts(sfd, sfd->fd, opts, PH_PREBIND);
|
||||||
applyopts(xfd, xfd->fd, opts, PH_BIND);
|
applyopts(sfd, sfd->fd, opts, PH_BIND);
|
||||||
#if WITH_TCP || WITH_UDP
|
#if WITH_TCP || WITH_UDP
|
||||||
if (alt) {
|
if (alt) {
|
||||||
union sockaddr_union sin, *sinp;
|
union sockaddr_union sin, *sinp;
|
||||||
|
@ -2125,13 +2127,13 @@ int xiobind(
|
||||||
i = N = XIO_IPPORT_LOWER + dv.rem;
|
i = N = XIO_IPPORT_LOWER + dv.rem;
|
||||||
do { /* loop over lowport bind() attempts */
|
do { /* loop over lowport bind() attempts */
|
||||||
*port = htons(i);
|
*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,
|
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)),
|
sockaddr_info(&sinp->soa, sizeof(*sinp), infobuff, sizeof(infobuff)),
|
||||||
sizeof(*sinp), strerror(errno));
|
sizeof(*sinp), strerror(errno));
|
||||||
if (errno != EADDRINUSE) {
|
if (errno != EADDRINUSE) {
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2141,7 +2143,7 @@ int xiobind(
|
||||||
if (i == N) {
|
if (i == N) {
|
||||||
Msg(level, "no low port available");
|
Msg(level, "no low port available");
|
||||||
/*errno = EADDRINUSE; still assigned */
|
/*errno = EADDRINUSE; still assigned */
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
} while (i != N);
|
} while (i != N);
|
||||||
|
@ -2154,11 +2156,11 @@ int xiobind(
|
||||||
applyopts_named(us->un.sun_path, opts, PH_PREOPEN);
|
applyopts_named(us->un.sun_path, opts, PH_PREOPEN);
|
||||||
}
|
}
|
||||||
#endif
|
#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",
|
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));
|
uslen, strerror(errno));
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2168,7 +2170,7 @@ int xiobind(
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
applyopts(xfd, -1, opts, PH_PASTBIND);
|
applyopts(sfd, -1, opts, PH_PASTBIND);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,7 @@
|
||||||
|
|
||||||
#if WITH_SOCKETPAIR
|
#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>") };
|
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,
|
struct opt *opts,
|
||||||
int xioflags,
|
int xioflags,
|
||||||
xiofile_t *xfd,
|
xiofile_t *xfd,
|
||||||
groups_t groups ,
|
const struct addrdesc *addrdesc)
|
||||||
int dummy1,
|
|
||||||
int dummy2,
|
|
||||||
int dummy3)
|
|
||||||
{
|
{
|
||||||
struct single *sfd = &xfd->stream;
|
struct single *sfd = &xfd->stream;
|
||||||
struct opt *opts2;
|
struct opt *opts2;
|
||||||
|
@ -41,7 +37,8 @@ static int xioopen_socketpair(
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 1) {
|
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;
|
sfd->para.bipipe.socktype = SOCK_DGRAM;
|
||||||
|
|
108
xio-socks.c
108
xio-socks.c
|
@ -27,10 +27,7 @@ enum {
|
||||||
#define SOCKSPORT "1080"
|
#define SOCKSPORT "1080"
|
||||||
#define BUFF_LEN (SIZEOF_STRUCT_SOCKS4+512)
|
#define BUFF_LEN (SIZEOF_STRUCT_SOCKS4+512)
|
||||||
|
|
||||||
static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
|
||||||
int xioflags, xiofile_t *fd,
|
|
||||||
groups_t groups, int dummy1, int dummy2,
|
|
||||||
int dummy3);
|
|
||||||
|
|
||||||
const struct optdesc opt_socksport = { "socksport", NULL, OPT_SOCKSPORT, GROUP_IP_SOCKS4, PH_LATE, TYPE_STRING, OFUNC_SPEC };
|
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 };
|
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>") };
|
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,
|
static int xioopen_socks4_connect(
|
||||||
int xioflags, xiofile_t *xxfd,
|
int argc,
|
||||||
groups_t groups, int socks4a, int dummy2,
|
const char *argv[],
|
||||||
int dummy3) {
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
/* we expect the form: host:host:port */
|
/* 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;
|
struct opt *opts0 = NULL;
|
||||||
const char *sockdname; char *socksport;
|
const char *sockdname; char *socksport;
|
||||||
const char *targetname, *targetport;
|
const char *targetname, *targetport;
|
||||||
|
@ -67,16 +69,16 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 4) {
|
if (argc != 4) {
|
||||||
Error1("%s: 3 parameters required", argv[0]);
|
xio_syntax(argv[0], 3, argc-1, addrdesc->syntax);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
sockdname = argv[1];
|
sockdname = argv[1];
|
||||||
targetname = argv[2];
|
targetname = argv[2];
|
||||||
targetport = argv[3];
|
targetport = argv[3];
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(xfd, 1, opts, PH_INIT);
|
applyopts(sfd, 1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
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 =
|
result =
|
||||||
_xioopen_ipapp_prepare(opts, &opts0, sockdname, socksport,
|
_xioopen_ipapp_prepare(opts, &opts0, sockdname, socksport,
|
||||||
&pf, ipproto,
|
&pf, ipproto,
|
||||||
xfd->para.socket.ip.ai_flags,
|
sfd->para.socket.ip.ai_flags,
|
||||||
&themlist, us, &uslen,
|
&themlist, us, &uslen,
|
||||||
&needbind, &lowport, socktype);
|
&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
|
/* we try to resolve the target address _before_ connecting to the socks
|
||||||
server: this avoids unnecessary socks connects and timeouts */
|
server: this avoids unnecessary socks connects and timeouts */
|
||||||
result =
|
result =
|
||||||
_xioopen_socks4_connect0(xfd, targetname, socks4a, sockhead,
|
_xioopen_socks4_connect0(sfd, targetname, socks4a, sockhead,
|
||||||
(ssize_t *)&buflen, level);
|
(ssize_t *)&buflen, level);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case STAT_OK: break;
|
case STAT_OK: break;
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
case STAT_RETRYNOW:
|
case STAT_RETRYNOW:
|
||||||
if (xfd->forever || xfd->retry--) {
|
if (sfd->forever || sfd->retry--) {
|
||||||
if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL);
|
if (result == STAT_RETRYLATER)
|
||||||
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif /* WITH_RETRY */
|
#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,
|
sockaddr_info(themp->ai_addr, themp->ai_addrlen,
|
||||||
infobuff, sizeof(infobuff)));
|
infobuff, sizeof(infobuff)));
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
if (xfd->forever || xfd->retry || ai_sorted[i] != NULL) {
|
if (sfd->forever || sfd->retry || ai_sorted[i] != NULL) {
|
||||||
level = E_INFO;
|
level = E_INFO;
|
||||||
} else
|
} else
|
||||||
#endif /* WITH_RETRY */
|
#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 */
|
/* this cannot fork because we retrieved fork option above */
|
||||||
result =
|
result =
|
||||||
_xioopen_connect(xfd,
|
_xioopen_connect(sfd,
|
||||||
needbind?us:NULL, sizeof(*us),
|
needbind?us:NULL, sizeof(*us),
|
||||||
themp->ai_addr, themp->ai_addrlen,
|
themp->ai_addr, themp->ai_addrlen,
|
||||||
opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP,
|
opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP, lowport, level);
|
||||||
lowport, level);
|
|
||||||
if (result == STAT_OK)
|
if (result == STAT_OK)
|
||||||
break;
|
break;
|
||||||
themp = ai_sorted[i++];
|
themp = ai_sorted[i++];
|
||||||
if (themp == NULL) {
|
if (themp == NULL)
|
||||||
result = STAT_RETRYLATER;
|
result = STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case STAT_OK: break;
|
case STAT_OK: break;
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
case STAT_RETRYNOW:
|
case STAT_RETRYNOW:
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
--xfd->retry;
|
--sfd->retry;
|
||||||
if (result == STAT_RETRYLATER)
|
if (result == STAT_RETRYLATER)
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
|
@ -181,19 +182,19 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
xiofreeaddrinfo(themlist);
|
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;
|
return result;
|
||||||
|
|
||||||
result = _xioopen_socks4_connect(xfd, sockhead, buflen, level);
|
result = _xioopen_socks4_connect(sfd, sockhead, buflen, level);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case STAT_OK: break;
|
case STAT_OK: break;
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
case STAT_RETRYNOW:
|
case STAT_RETRYNOW:
|
||||||
if (xfd->forever || xfd->retry--) {
|
if (sfd->forever || sfd->retry--) {
|
||||||
if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL);
|
if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
|
@ -209,26 +210,27 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
|
||||||
if (dofork) {
|
if (dofork) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int level = E_ERROR;
|
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,
|
level = E_WARN; /* most users won't expect a problem here,
|
||||||
so Notice is too weak */
|
so Notice is too weak */
|
||||||
}
|
}
|
||||||
while ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
|
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
|
||||||
if (xfd->forever || --xfd->retry) {
|
if (sfd->forever || --sfd->retry) {
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid == 0) { /* child process */
|
if (pid == 0) { /* child process */
|
||||||
xfd->forever = false; xfd->retry = 0;
|
sfd->forever = false;
|
||||||
|
sfd->retry = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parent process */
|
/* parent process */
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
continue;
|
continue;
|
||||||
} else
|
} else
|
||||||
|
@ -282,7 +284,7 @@ int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **soc
|
||||||
|
|
||||||
/* called within retry/fork loop, before connect() */
|
/* called within retry/fork loop, before connect() */
|
||||||
int
|
int
|
||||||
_xioopen_socks4_connect0(struct single *xfd,
|
_xioopen_socks4_connect0(struct single *sfd,
|
||||||
const char *hostname, /* socks target host */
|
const char *hostname, /* socks target host */
|
||||||
int socks4a,
|
int socks4a,
|
||||||
struct socks4 *sockhead,
|
struct socks4 *sockhead,
|
||||||
|
@ -298,7 +300,7 @@ int
|
||||||
if ((result = xioresolve(hostname, NULL,
|
if ((result = xioresolve(hostname, NULL,
|
||||||
PF_INET, SOCK_STREAM, IPPROTO_TCP,
|
PF_INET, SOCK_STREAM, IPPROTO_TCP,
|
||||||
&sau, &saulen,
|
&sau, &saulen,
|
||||||
xfd->para.socket.ip.ai_flags))
|
sfd->para.socket.ip.ai_flags))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return result; /*! STAT_RETRY? */
|
return result; /*! STAT_RETRY? */
|
||||||
}
|
}
|
||||||
|
@ -330,7 +332,7 @@ int
|
||||||
|
|
||||||
/* perform socks4 client dialog on existing FD.
|
/* perform socks4 client dialog on existing FD.
|
||||||
Called within fork/retry loop, after connect() */
|
Called within fork/retry loop, after connect() */
|
||||||
int _xioopen_socks4_connect(struct single *xfd,
|
int _xioopen_socks4_connect(struct single *sfd,
|
||||||
struct socks4 *sockhead,
|
struct socks4 *sockhead,
|
||||||
size_t headlen,
|
size_t headlen,
|
||||||
int level) {
|
int level) {
|
||||||
|
@ -365,11 +367,11 @@ int _xioopen_socks4_connect(struct single *xfd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* WITH_MSGLEVEL <= E_DEBUG */
|
#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",
|
Msg4(level, "write(%d, %p, "F_Zu"): %s",
|
||||||
xfd->fd, sockhead, headlen, strerror(errno));
|
sfd->fd, sockhead, headlen, strerror(errno));
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER; /* retry complete open cycle */
|
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 */
|
while (bytes >= 0) { /* loop over answer chunks until complete or error */
|
||||||
/* receive socks answer */
|
/* receive socks answer */
|
||||||
do {
|
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);
|
} while (result < 0 && errno == EINTR);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
Msg4(level, "read(%d, %p, "F_Zu"): %s",
|
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));
|
strerror(errno));
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
Msg(level, "read(): EOF during read of socks reply, peer might not be a socks4 server");
|
Msg(level, "read(): EOF during read of socks reply, peer might not be a socks4 server");
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
@ -431,9 +433,9 @@ int _xioopen_socks4_connect(struct single *xfd,
|
||||||
case SOCKS_CD_GRANTED:
|
case SOCKS_CD_GRANTED:
|
||||||
/* Notice("socks: connect request succeeded"); */
|
/* Notice("socks: connect request succeeded"); */
|
||||||
#if 0
|
#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",
|
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",
|
Notice1("successfully connected from %s via socks4",
|
||||||
sockaddr_info((struct sockaddr *)&us, infobuff, sizeof(infobuff)));
|
sockaddr_info((struct sockaddr *)&us, infobuff, sizeof(infobuff)));
|
||||||
|
|
156
xio-socks5.c
156
xio-socks5.c
|
@ -48,10 +48,7 @@
|
||||||
#define SOCKS5_STATUS_COMMAND_NOT_SUPPORTED 7
|
#define SOCKS5_STATUS_COMMAND_NOT_SUPPORTED 7
|
||||||
#define SOCKS5_STATUS_ADDRESS_TYPE_NOT_SUPPORTED 8
|
#define SOCKS5_STATUS_ADDRESS_TYPE_NOT_SUPPORTED 8
|
||||||
|
|
||||||
static int xioopen_socks5(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_socks5(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
|
||||||
int xioflags, xiofile_t *xxfd,
|
|
||||||
groups_t groups, int dummy1, int dummy2,
|
|
||||||
int dummy3);
|
|
||||||
|
|
||||||
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>") };
|
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
|
* send(0x050100) followed by "return read() == 0x0500", but will be easier to
|
||||||
* extend for other auth mode support.
|
* 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;
|
int result;
|
||||||
ssize_t bytes;
|
ssize_t bytes;
|
||||||
|
@ -106,8 +103,8 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level)
|
||||||
if (client_hello == NULL) {
|
if (client_hello == NULL) {
|
||||||
Msg2(level, "malloc(%d): %s",
|
Msg2(level, "malloc(%d): %s",
|
||||||
client_hello_size, strerror(errno));
|
client_hello_size, strerror(errno));
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* malloc failed - could succeed later, so retry then */
|
/* malloc failed - could succeed later, so retry then */
|
||||||
|
@ -138,12 +135,12 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level)
|
||||||
}
|
}
|
||||||
#endif
|
#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",
|
Msg4(level, "write(%d, %p, %d): %s",
|
||||||
xfd->fd, client_hello, client_hello_size,
|
sfd->fd, client_hello, client_hello_size,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
free(client_hello);
|
free(client_hello);
|
||||||
|
|
||||||
|
@ -156,22 +153,22 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level)
|
||||||
Info("waiting for socks5 reply");
|
Info("waiting for socks5 reply");
|
||||||
while (bytes >= 0) {
|
while (bytes >= 0) {
|
||||||
do {
|
do {
|
||||||
result = Read(xfd->fd, server_hello_ptr + bytes,
|
result = Read(sfd->fd, server_hello_ptr + bytes,
|
||||||
sizeof(struct socks5_server_hello)-bytes);
|
sizeof(struct socks5_server_hello)-bytes);
|
||||||
} while (result < 0 && errno == EINTR);
|
} while (result < 0 && errno == EINTR);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
Msg4(level, "read(%d, %p, "F_Zu"): %s",
|
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,
|
sizeof(struct socks5_server_hello)-bytes,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
Msg(level, "read(): EOF during read of SOCKS5 server hello, peer might not be a SOCKS5 server");
|
Msg(level, "read(): EOF during read of SOCKS5 server hello, peer might not be a SOCKS5 server");
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd,
|
Info2("close(%d): %s", sfd->fd,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,16 +194,16 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level)
|
||||||
if (server_hello.version != SOCKS5_VERSION) {
|
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",
|
Msg2(level, "SOCKS5 Server Hello version was %d, not the expected %d, peer might not be a SOCKS5 server",
|
||||||
server_hello.version, SOCKS5_VERSION);
|
server_hello.version, SOCKS5_VERSION);
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server_hello.method == SOCKS5_AUTH_FAIL) {
|
if (server_hello.method == SOCKS5_AUTH_FAIL) {
|
||||||
Msg(level, "SOCKS5 authentication negotiation failed - client & server have no common supported methods");
|
Msg(level, "SOCKS5 authentication negotiation failed - client & server have no common supported methods");
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
@ -214,8 +211,8 @@ static int _xioopen_socks5_handshake(struct single *xfd, int level)
|
||||||
if (server_hello.method != SOCKS5_AUTH_NONE) {
|
if (server_hello.method != SOCKS5_AUTH_NONE) {
|
||||||
Msg1(level, "SOCKS5 server requested unsupported auth method (%d)",
|
Msg1(level, "SOCKS5 server requested unsupported auth method (%d)",
|
||||||
server_hello.method);
|
server_hello.method);
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
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
|
* Reads a server reply after a request has been sent
|
||||||
*/
|
*/
|
||||||
static int _xioopen_socks5_read_reply(
|
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 result = 0;
|
||||||
int bytes_read = 0;
|
int bytes_read = 0;
|
||||||
|
@ -313,24 +310,24 @@ static int _xioopen_socks5_read_reply(
|
||||||
while (bytes_to_read >= 0) {
|
while (bytes_to_read >= 0) {
|
||||||
Info("reading SOCKS5 reply");
|
Info("reading SOCKS5 reply");
|
||||||
do {
|
do {
|
||||||
result = Read(xfd->fd,
|
result = Read(sfd->fd,
|
||||||
((unsigned char *)reply) + bytes_read,
|
((unsigned char *)reply) + bytes_read,
|
||||||
bytes_to_read-bytes_read);
|
bytes_to_read-bytes_read);
|
||||||
} while (result < 0 && errno == EINTR);
|
} while (result < 0 && errno == EINTR);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
Msg4(level, "read(%d, %p, %d): %s",
|
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));
|
bytes_to_read-bytes_read, strerror(errno));
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
Msg(level, "read(): EOF during read of SOCKS5 reply");
|
Msg(level, "read(): EOF during read of SOCKS5 reply");
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s",
|
Info2("close(%d): %s",
|
||||||
xfd->fd, strerror(errno));
|
sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
@ -356,9 +353,9 @@ static int _xioopen_socks5_read_reply(
|
||||||
default:
|
default:
|
||||||
Msg1(level, "invalid SOCKS5 reply address type (%d)",
|
Msg1(level, "invalid SOCKS5 reply address type (%d)",
|
||||||
reply->address_type);
|
reply->address_type);
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s",
|
Info2("close(%d): %s",
|
||||||
xfd->fd, strerror(errno));
|
sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
@ -388,7 +385,7 @@ static int _xioopen_socks5_read_reply(
|
||||||
* If command is BIND we receive two replies.
|
* If command is BIND we receive two replies.
|
||||||
*/
|
*/
|
||||||
static int _xioopen_socks5_request(
|
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)
|
uint8_t socks_command, int level)
|
||||||
{
|
{
|
||||||
struct socks5_request *req;
|
struct socks5_request *req;
|
||||||
|
@ -397,8 +394,8 @@ static int _xioopen_socks5_request(
|
||||||
req = _xioopen_socks5_prepare_request(&bytes, target_name, target_port,
|
req = _xioopen_socks5_prepare_request(&bytes, target_name, target_port,
|
||||||
socks_command, level);
|
socks_command, level);
|
||||||
if (req == NULL) {
|
if (req == NULL) {
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare_request could fail due to malloc, but most likely
|
/* Prepare_request could fail due to malloc, but most likely
|
||||||
|
@ -420,11 +417,11 @@ static int _xioopen_socks5_request(
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (writefull(xfd->fd, req, bytes) < 0) {
|
if (writefull(sfd->fd, req, bytes) < 0) {
|
||||||
Msg4(level, "write(%d, %p, %d): %s",
|
Msg4(level, "write(%d, %p, %d): %s",
|
||||||
xfd->fd, req, bytes, strerror(errno));
|
sfd->fd, req, bytes, strerror(errno));
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
free(req);
|
free(req);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
|
@ -434,14 +431,14 @@ static int _xioopen_socks5_request(
|
||||||
|
|
||||||
struct socks5_reply *reply = Malloc(SOCKS5_MAX_REPLY_SIZE);
|
struct socks5_reply *reply = Malloc(SOCKS5_MAX_REPLY_SIZE);
|
||||||
if (reply == NULL) {
|
if (reply == NULL) {
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = _xioopen_socks5_read_reply(xfd, reply, level);
|
result = _xioopen_socks5_read_reply(sfd, reply, level);
|
||||||
if (result != STAT_OK) {
|
if (result != STAT_OK) {
|
||||||
free(reply);
|
free(reply);
|
||||||
return result;
|
return result;
|
||||||
|
@ -454,8 +451,8 @@ static int _xioopen_socks5_request(
|
||||||
if (reply->version != SOCKS5_VERSION) {
|
if (reply->version != SOCKS5_VERSION) {
|
||||||
Msg2(level, "SOCKS5 reply version was %d, not the expected %d, peer might not be a SOCKS5 server",
|
Msg2(level, "SOCKS5 reply version was %d, not the expected %d, peer might not be a SOCKS5 server",
|
||||||
reply->version, SOCKS5_VERSION);
|
reply->version, SOCKS5_VERSION);
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
free(reply);
|
free(reply);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
|
@ -466,7 +463,7 @@ static int _xioopen_socks5_request(
|
||||||
Notice("listening on remote host, waiting for connection");
|
Notice("listening on remote host, waiting for connection");
|
||||||
/* TODO: nicer debug output */
|
/* TODO: nicer debug output */
|
||||||
/* For BIND, we read two replies */
|
/* 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) {
|
if (result != STAT_OK) {
|
||||||
free(reply);
|
free(reply);
|
||||||
return result;
|
return result;
|
||||||
|
@ -484,8 +481,8 @@ static int _xioopen_socks5_request(
|
||||||
Msg2(level, "SOCKS5 server error %d: %s",
|
Msg2(level, "SOCKS5 server error %d: %s",
|
||||||
reply->reply,
|
reply->reply,
|
||||||
_xioopen_socks5_strerror(reply->reply));
|
_xioopen_socks5_strerror(reply->reply));
|
||||||
if (Close(xfd->fd) < 0) {
|
if (Close(sfd->fd) < 0) {
|
||||||
Info2("close(%d): %s", xfd->fd, strerror(errno));
|
Info2("close(%d): %s", sfd->fd, strerror(errno));
|
||||||
}
|
}
|
||||||
free(reply);
|
free(reply);
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
|
@ -497,17 +494,21 @@ static int _xioopen_socks5_request(
|
||||||
|
|
||||||
/* Same function for all socks5-modes, determined by argv[0] */
|
/* Same function for all socks5-modes, determined by argv[0] */
|
||||||
static int xioopen_socks5(
|
static int xioopen_socks5(
|
||||||
int argc, const char *argv[], struct opt *opts, int xioflags,
|
int argc,
|
||||||
xiofile_t *xxfd, groups_t groups, int socks_command, int dummy2,
|
const char *argv[],
|
||||||
int dummy3)
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
{
|
{
|
||||||
|
int socks_command = addrdesc->arg1;
|
||||||
bool dofork = false;
|
bool dofork = false;
|
||||||
int socktype = SOCK_STREAM;
|
int socktype = SOCK_STREAM;
|
||||||
int pf = PF_UNSPEC;
|
int pf = PF_UNSPEC;
|
||||||
int ipproto = IPPROTO_TCP;
|
int ipproto = IPPROTO_TCP;
|
||||||
int level, result;
|
int level, result;
|
||||||
struct opt *opts0 = NULL;
|
struct opt *opts0 = NULL;
|
||||||
struct single *xfd = &xxfd->stream;
|
struct single *sfd = &xxfd->stream;
|
||||||
const char *socks_server, *target_name, *target_port, *socks_port;
|
const char *socks_server, *target_name, *target_port, *socks_port;
|
||||||
union sockaddr_union us_sa, *us = &us_sa;
|
union sockaddr_union us_sa, *us = &us_sa;
|
||||||
socklen_t uslen = sizeof(us_sa);
|
socklen_t uslen = sizeof(us_sa);
|
||||||
|
@ -521,14 +522,7 @@ static int xioopen_socks5(
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
if (argc != 5) {
|
if (argc != 5) {
|
||||||
#if WITH_HELP
|
xio_syntax(argv[0], 4, argc-1, addrdesc->syntax);
|
||||||
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
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,16 +531,16 @@ static int xioopen_socks5(
|
||||||
target_name = argv[3];
|
target_name = argv[3];
|
||||||
target_port = argv[4];
|
target_port = argv[4];
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(xfd, -1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
retropt_bool(opts, OPT_FORK, &dofork);
|
retropt_bool(opts, OPT_FORK, &dofork);
|
||||||
|
|
||||||
result = _xioopen_ipapp_prepare(opts, &opts0, socks_server, socks_port,
|
result = _xioopen_ipapp_prepare(opts, &opts0, socks_server, socks_port,
|
||||||
&pf, ipproto,
|
&pf, ipproto,
|
||||||
xfd->para.socket.ip.ai_flags,
|
sfd->para.socket.ip.ai_flags,
|
||||||
&themlist, us, &uslen,
|
&themlist, us, &uslen,
|
||||||
&needbind, &lowport, socktype);
|
&needbind, &lowport, socktype);
|
||||||
|
|
||||||
|
@ -555,7 +549,7 @@ static int xioopen_socks5(
|
||||||
|
|
||||||
do {
|
do {
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
level = E_INFO;
|
level = E_INFO;
|
||||||
} else {
|
} else {
|
||||||
level = E_ERROR;
|
level = E_ERROR;
|
||||||
|
@ -568,7 +562,7 @@ static int xioopen_socks5(
|
||||||
Notice1("opening connection to %s",
|
Notice1("opening connection to %s",
|
||||||
sockaddr_info(themp->ai_addr, themp->ai_addrlen,
|
sockaddr_info(themp->ai_addr, themp->ai_addrlen,
|
||||||
infobuff, sizeof(infobuff)));
|
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,
|
themp->ai_addr, themp->ai_addrlen,
|
||||||
opts, pf?pf:themp->ai_family, socktype,
|
opts, pf?pf:themp->ai_family, socktype,
|
||||||
IPPROTO_TCP, lowport, level);
|
IPPROTO_TCP, lowport, level);
|
||||||
|
@ -583,8 +577,8 @@ static int xioopen_socks5(
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
case STAT_RETRYNOW:
|
case STAT_RETRYNOW:
|
||||||
if (xfd->forever || xfd->retry-- ) {
|
if (sfd->forever || sfd->retry-- ) {
|
||||||
if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL);
|
if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -594,24 +588,24 @@ static int xioopen_socks5(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xiofreeaddrinfo(themlist);
|
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;
|
return result;
|
||||||
|
|
||||||
if ((result = _xioopen_socks5_handshake(xfd, level)) != STAT_OK) {
|
if ((result = _xioopen_socks5_handshake(sfd, level)) != STAT_OK) {
|
||||||
return result;
|
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) {
|
switch (result) {
|
||||||
case STAT_OK:
|
case STAT_OK:
|
||||||
break;
|
break;
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
case STAT_RETRYNOW:
|
case STAT_RETRYNOW:
|
||||||
if ( xfd->forever || xfd->retry-- ) {
|
if ( sfd->forever || sfd->retry-- ) {
|
||||||
if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL);
|
if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -627,24 +621,24 @@ static int xioopen_socks5(
|
||||||
if (dofork) {
|
if (dofork) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int level = E_ERROR;
|
int level = E_ERROR;
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
level = E_WARN;
|
level = E_WARN;
|
||||||
}
|
}
|
||||||
while ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
|
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
|
||||||
if (xfd->forever || --xfd->retry) {
|
if (sfd->forever || --sfd->retry) {
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
if ( pid == 0 ) {
|
if ( pid == 0 ) {
|
||||||
xfd->forever = false;
|
sfd->forever = false;
|
||||||
xfd->retry = 0;
|
sfd->retry = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
dropopts(opts, PH_ALL);
|
dropopts(opts, PH_ALL);
|
||||||
opts = copyopts(opts0, GROUP_ALL);
|
opts = copyopts(opts0, GROUP_ALL);
|
||||||
continue;
|
continue;
|
||||||
|
|
27
xio-stdio.c
27
xio-stdio.c
|
@ -13,8 +13,8 @@
|
||||||
|
|
||||||
#if WITH_STDIO
|
#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_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, 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);
|
||||||
|
|
||||||
|
|
||||||
/* we specify all option groups that we can imagine for a FD, becasue the
|
/* 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.
|
/* wrap around unidirectional xioopensingle and xioopen_fd to automatically determine stdin or stdout fd depending on rw.
|
||||||
Do not set FD_CLOEXEC flag. */
|
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);
|
int rw = (xioflags&XIO_ACCMODE);
|
||||||
|
|
||||||
if (argc != 1) {
|
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",
|
Notice2("using %s for %s",
|
||||||
&("stdin\0\0\0stdout"[rw<<3]),
|
&("stdin\0\0\0stdout"[rw<<3]),
|
||||||
ddirection[rw]);
|
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.
|
/* wrap around unidirectional xioopensingle and xioopen_fd to automatically determine stdin or stdout fd depending on rw.
|
||||||
Do not set FD_CLOEXEC flag. */
|
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 rw = (xioflags&XIO_ACCMODE);
|
||||||
|
int fd = addrdesc->arg1;
|
||||||
|
|
||||||
if (argc != 1) {
|
if (argc != 1) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 0)", argv[0], 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",
|
Notice2("using %s for %s",
|
||||||
&("stdin\0\0\0stdout\0\0stderr"[fd<<3]),
|
&("stdin\0\0\0stdout\0\0stderr"[fd<<3]),
|
||||||
ddirection[rw]);
|
ddirection[rw]);
|
||||||
return xioopen_fd(opts, rw, &xfd->stream, fd, dummy2, dummy3);
|
return xioopen_fd(opts, rw, &xfd->stream, fd);
|
||||||
}
|
}
|
||||||
#endif /* WITH_STDIO */
|
#endif /* WITH_STDIO */
|
||||||
|
|
25
xio-system.c
25
xio-system.c
|
@ -13,22 +13,19 @@
|
||||||
|
|
||||||
#if WITH_SYSTEM
|
#if WITH_SYSTEM
|
||||||
|
|
||||||
static int xioopen_system(int arg, const char *argv[], struct opt *opts,
|
static int xioopen_system(int arg, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
int xioflags, /* XIO_RDONLY etc. */
|
|
||||||
xiofile_t *fd,
|
|
||||||
groups_t groups,
|
|
||||||
int dummy1, int dummy2, int dummy3
|
|
||||||
);
|
|
||||||
|
|
||||||
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>") };
|
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,
|
static int xioopen_system(
|
||||||
|
int argc,
|
||||||
|
const char *argv[],
|
||||||
|
struct opt *opts,
|
||||||
int xioflags, /* XIO_RDONLY etc. */
|
int xioflags, /* XIO_RDONLY etc. */
|
||||||
xiofile_t *xfd,
|
xiofile_t *xfd,
|
||||||
groups_t groups,
|
const struct addrdesc *addrdesc)
|
||||||
int dummy1, int dummy2, int dummy3
|
{
|
||||||
) {
|
|
||||||
struct single *sfd = &xfd->stream;
|
struct single *sfd = &xfd->stream;
|
||||||
int status;
|
int status;
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
|
@ -36,7 +33,13 @@ static int xioopen_system(int argc, const char *argv[], struct opt *opts,
|
||||||
int result;
|
int result;
|
||||||
const char *string = argv[1];
|
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)
|
if (status < 0)
|
||||||
return status;
|
return status;
|
||||||
if (status == 0) { /* child */
|
if (status == 0) { /* child */
|
||||||
|
|
|
@ -32,42 +32,44 @@ int allow_severity=10, deny_severity=10;
|
||||||
/* returns 0 if option was found and could be applied
|
/* returns 0 if option was found and could be applied
|
||||||
returns 1 if option was not found
|
returns 1 if option was not found
|
||||||
returns -1 if option was found but failed */
|
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;
|
bool dolibwrap = false;
|
||||||
dolibwrap =
|
dolibwrap =
|
||||||
retropt_string(opts, OPT_TCPWRAPPERS,
|
retropt_string(opts, OPT_TCPWRAPPERS,
|
||||||
&xfd->para.socket.ip.libwrapname) >= 0 || dolibwrap;
|
&sfd->para.socket.ip.libwrapname) >= 0 || dolibwrap;
|
||||||
dolibwrap =
|
dolibwrap =
|
||||||
retropt_string(opts, OPT_TCPWRAP_ETC,
|
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)
|
#if defined(HAVE_HOSTS_ALLOW_TABLE)
|
||||||
dolibwrap =
|
dolibwrap =
|
||||||
retropt_string(opts, OPT_TCPWRAP_HOSTS_ALLOW_TABLE,
|
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
|
#endif
|
||||||
#if defined(HAVE_HOSTS_DENY_TABLE)
|
#if defined(HAVE_HOSTS_DENY_TABLE)
|
||||||
dolibwrap =
|
dolibwrap =
|
||||||
retropt_string(opts, OPT_TCPWRAP_HOSTS_DENY_TABLE,
|
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
|
#endif
|
||||||
if (dolibwrap) {
|
if (dolibwrap) {
|
||||||
xfd->para.socket.ip.dolibwrap = true;
|
sfd->para.socket.ip.dolibwrap = true;
|
||||||
if (xfd->para.socket.ip.libwrapname == NULL) {
|
if (sfd->para.socket.ip.libwrapname == NULL) {
|
||||||
xfd->para.socket.ip.libwrapname = (char *)diag_get_string('p');
|
sfd->para.socket.ip.libwrapname = (char *)diag_get_string('p');
|
||||||
}
|
}
|
||||||
#if defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE)
|
#if defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE)
|
||||||
if (xfd->para.socket.ip.tcpwrap_etc) {
|
if (sfd->para.socket.ip.tcpwrap_etc) {
|
||||||
if (xfd->para.socket.ip.hosts_allow_table == NULL) {
|
if (sfd->para.socket.ip.hosts_allow_table == NULL) {
|
||||||
xfd->para.socket.ip.hosts_allow_table =
|
sfd->para.socket.ip.hosts_allow_table =
|
||||||
Malloc(strlen(xfd->para.socket.ip.tcpwrap_etc)+1+11+1);
|
Malloc(strlen(sfd->para.socket.ip.tcpwrap_etc)+1+11+1);
|
||||||
sprintf(xfd->para.socket.ip.hosts_allow_table, "%s/hosts.allow",
|
sprintf(sfd->para.socket.ip.hosts_allow_table, "%s/hosts.allow",
|
||||||
xfd->para.socket.ip.tcpwrap_etc);
|
sfd->para.socket.ip.tcpwrap_etc);
|
||||||
}
|
}
|
||||||
if (xfd->para.socket.ip.hosts_deny_table == NULL) {
|
if (sfd->para.socket.ip.hosts_deny_table == NULL) {
|
||||||
xfd->para.socket.ip.hosts_deny_table =
|
sfd->para.socket.ip.hosts_deny_table =
|
||||||
Malloc(strlen(xfd->para.socket.ip.tcpwrap_etc)+1+10+1);
|
Malloc(strlen(sfd->para.socket.ip.tcpwrap_etc)+1+10+1);
|
||||||
sprintf(xfd->para.socket.ip.hosts_deny_table, "%s/hosts.deny",
|
sprintf(sfd->para.socket.ip.hosts_deny_table, "%s/hosts.deny",
|
||||||
xfd->para.socket.ip.tcpwrap_etc);
|
sfd->para.socket.ip.tcpwrap_etc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE) */
|
#endif /* defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE) */
|
||||||
|
@ -79,7 +81,9 @@ int xio_retropt_tcpwrap(xiosingle_t *xfd, struct opt *opts) {
|
||||||
|
|
||||||
/* returns -1 if forbidden, 0 if no tcpwrap check, or 1 if explicitely allowed
|
/* 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,
|
int xio_tcpwrap_check(
|
||||||
|
struct single *sfd,
|
||||||
|
union sockaddr_union *us,
|
||||||
union sockaddr_union *them) {
|
union sockaddr_union *them) {
|
||||||
char *save_hosts_allow_table, *save_hosts_deny_table;
|
char *save_hosts_allow_table, *save_hosts_deny_table;
|
||||||
struct request_info ri;
|
struct request_info ri;
|
||||||
|
@ -90,25 +94,25 @@ int xio_tcpwrap_check(xiosingle_t *xfd, union sockaddr_union *us,
|
||||||
#endif
|
#endif
|
||||||
int allow;
|
int allow;
|
||||||
|
|
||||||
if (!xfd->para.socket.ip.dolibwrap) {
|
if (!sfd->para.socket.ip.dolibwrap) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (us == NULL || them == NULL) { return -1; }
|
if (us == NULL || them == NULL) { return -1; }
|
||||||
|
|
||||||
#if defined(HAVE_HOSTS_ALLOW_TABLE)
|
#if defined(HAVE_HOSTS_ALLOW_TABLE)
|
||||||
save_hosts_allow_table = 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\"",
|
Debug1("hosts_allow_table = \"%s\"",
|
||||||
xfd->para.socket.ip.hosts_allow_table);
|
sfd->para.socket.ip.hosts_allow_table);
|
||||||
hosts_allow_table = xfd->para.socket.ip.hosts_allow_table;
|
hosts_allow_table = sfd->para.socket.ip.hosts_allow_table;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_HOSTS_ALLOW_TABLE) */
|
#endif /* defined(HAVE_HOSTS_ALLOW_TABLE) */
|
||||||
#if defined(HAVE_HOSTS_DENY_TABLE)
|
#if defined(HAVE_HOSTS_DENY_TABLE)
|
||||||
save_hosts_deny_table = 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\"",
|
Debug1("hosts_deny_table = \"%s\"",
|
||||||
xfd->para.socket.ip.hosts_deny_table);
|
sfd->para.socket.ip.hosts_deny_table);
|
||||||
hosts_deny_table = xfd->para.socket.ip.hosts_deny_table;
|
hosts_deny_table = sfd->para.socket.ip.hosts_deny_table;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_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));
|
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",
|
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),
|
ntohs(((struct sockaddr_in *)them)->sin_port),
|
||||||
serveraddr, ntohs(us->ip4.sin_port),
|
serveraddr, ntohs(us->ip4.sin_port),
|
||||||
xfd->para.socket.ip.libwrapname?xfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'));
|
sfd->para.socket.ip.libwrapname?sfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'));
|
||||||
request_init(&ri, RQ_FILE, xfd->fd,
|
request_init(&ri, RQ_FILE, sfd->fd,
|
||||||
RQ_CLIENT_SIN, them,
|
RQ_CLIENT_SIN, them,
|
||||||
RQ_SERVER_SIN, &us->soa,
|
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() ->");
|
Debug("request_init() ->");
|
||||||
|
|
||||||
Debug1("sock_methods(%p)", &ri);
|
Debug1("sock_methods(%p)", &ri);
|
||||||
|
|
19
xio-tun.c
19
xio-tun.c
|
@ -16,7 +16,7 @@
|
||||||
#include "xio-tun.h"
|
#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 ******/
|
/****** TUN options ******/
|
||||||
const struct optdesc opt_tun_device = { "tun-device", NULL, OPT_TUN_DEVICE, GROUP_TUN, PH_OPEN, TYPE_FILENAME, OFUNC_SPEC };
|
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
|
#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;
|
struct single *sfd = &xfd->stream;
|
||||||
char *tundevice = NULL;
|
char *tundevice = NULL;
|
||||||
char *tunname = NULL, *tuntype = 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;
|
int result;
|
||||||
|
|
||||||
if (argc > 2 || argc < 0) {
|
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)",
|
Error2("%s: wrong number of parameters (%d instead of 0 or 1)",
|
||||||
argv[0], argc-1);
|
argv[0], argc-1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retropt_string(opts, OPT_TUN_DEVICE, &tundevice) != 0) {
|
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;
|
namedargv[1] = tundevice;
|
||||||
/* open the tun cloning device */
|
/* 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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
189
xio-udp.c
189
xio-udp.c
|
@ -19,22 +19,10 @@
|
||||||
#include "xio-udp.h"
|
#include "xio-udp.h"
|
||||||
|
|
||||||
|
|
||||||
static
|
static int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
int xioflags, xiofile_t *xfd, groups_t groups,
|
static int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
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);
|
||||||
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
|
static
|
||||||
int _xioopen_udp_sendto(const char *hostname, const char *servname,
|
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 */
|
/* we expect the form: port */
|
||||||
int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
int xioopen_ipdgram_listen(
|
||||||
int xioflags, xiofile_t *xfd,
|
int argc,
|
||||||
groups_t groups, int pf, int ipproto,
|
const char *argv[],
|
||||||
int protname) {
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
struct single *sfd = &xfd->stream;
|
struct single *sfd = &xfd->stream;
|
||||||
const char *portname = argv[1];
|
const char *portname = argv[1];
|
||||||
|
int pf = addrdesc->arg1;
|
||||||
|
int ipproto = addrdesc->arg2;
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
int socktype = SOCK_DGRAM;
|
int socktype = SOCK_DGRAM;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
|
|
||||||
if (argc != 2) {
|
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);
|
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);
|
opts, pf, socktype, ipproto);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static int xioopen_udp_sendto(
|
||||||
int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts,
|
int argc,
|
||||||
int xioflags, xiofile_t *xfd, groups_t groups,
|
const char *argv[],
|
||||||
int pf, int socktype, int ipproto) {
|
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;
|
int result;
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 2)",
|
xio_syntax(argv[0], 2, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
if ((result = _xioopen_udp_sendto(argv[1], argv[2], opts, xioflags, xfd,
|
if ((result = _xioopen_udp_sendto(argv[1], argv[2], opts, xioflags, xfd,
|
||||||
groups, pf, socktype, ipproto))
|
addrdesc->groups, pf, socktype, ipproto))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -375,75 +376,83 @@ int _xioopen_udp_sendto(const char *hostname, const char *servname,
|
||||||
struct opt *opts,
|
struct opt *opts,
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
int xioflags, xiofile_t *xxfd, groups_t groups,
|
||||||
int pf, int socktype, int ipproto) {
|
int pf, int socktype, int ipproto) {
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
struct single *sfd = &xxfd->stream;
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
int feats = 3; /* option bind supports address and port */
|
int feats = 3; /* option bind supports address and port */
|
||||||
bool needbind = false;
|
bool needbind = false;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
/* ...res_opts[] */
|
||||||
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 =
|
if ((result =
|
||||||
xioresolve(hostname, servname, pf, socktype, ipproto,
|
xioresolve(hostname, servname, pf, socktype, ipproto,
|
||||||
&xfd->peersa, &xfd->salen,
|
&sfd->peersa, &sfd->salen,
|
||||||
xfd->para.socket.ip.ai_flags))
|
sfd->para.socket.ip.ai_flags))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (pf == PF_UNSPEC) {
|
if (pf == PF_UNSPEC) {
|
||||||
pf = xfd->peersa.soa.sa_family;
|
pf = sfd->peersa.soa.sa_family;
|
||||||
}
|
}
|
||||||
uslen = socket_init(pf, &us);
|
uslen = socket_init(pf, &us);
|
||||||
if (retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, feats,
|
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) {
|
!= STAT_NOACTION) {
|
||||||
needbind = true;
|
needbind = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retropt_ushort(opts, OPT_SOURCEPORT,
|
if (retropt_ushort(opts, OPT_SOURCEPORT,
|
||||||
&xfd->para.socket.ip.sourceport) >= 0) {
|
&sfd->para.socket.ip.sourceport) >= 0) {
|
||||||
switch (pf) {
|
switch (pf) {
|
||||||
#if WITH_IP4
|
#if WITH_IP4
|
||||||
case PF_INET:
|
case PF_INET:
|
||||||
us.ip4.sin_port = htons(xfd->para.socket.ip.sourceport);
|
us.ip4.sin_port = htons(sfd->para.socket.ip.sourceport);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if WITH_IP6
|
#if WITH_IP6
|
||||||
case PF_INET6:
|
case PF_INET6:
|
||||||
us.ip6.sin6_port = htons(xfd->para.socket.ip.sourceport);
|
us.ip6.sin6_port = htons(sfd->para.socket.ip.sourceport);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
needbind = true;
|
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,
|
return _xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
||||||
opts, xioflags, xfd, groups,
|
opts, xioflags, sfd, groups,
|
||||||
pf, socktype, ipproto,
|
pf, socktype, ipproto,
|
||||||
xfd->para.socket.ip.lowport);
|
sfd->para.socket.ip.lowport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static int xioopen_udp_datagram(
|
||||||
int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts,
|
int argc,
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
const char *argv[],
|
||||||
int pf, int socktype, int ipproto) {
|
struct opt *opts,
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
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 *rangename;
|
||||||
char *hostname;
|
char *hostname;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 2)",
|
xio_syntax(argv[0], 2, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
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 */
|
/* 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) {
|
>= 0) {
|
||||||
xfd->para.socket.ip.dosourceport = true;
|
sfd->para.socket.ip.dosourceport = true;
|
||||||
xfd->para.socket.ip.sourceport = ntohs(xfd->peersa.ip4.sin_port);
|
sfd->para.socket.ip.sourceport = ntohs(sfd->peersa.ip4.sin_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
result =
|
result =
|
||||||
_xioopen_udp_sendto(hostname, argv[2], opts, xioflags, xxfd, groups,
|
_xioopen_udp_sendto(hostname, argv[2], opts, xioflags, xxfd,
|
||||||
pf, socktype, ipproto);
|
addrdesc->groups, pf, socktype, ipproto);
|
||||||
free(hostname);
|
free(hostname);
|
||||||
if (result != STAT_OK) {
|
if (result != STAT_OK) {
|
||||||
return result;
|
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 */
|
/* which reply packets will be accepted - determine by range option */
|
||||||
if (retropt_string(opts, OPT_RANGE, &rangename)
|
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
||||||
>= 0) {
|
if (xioparserange(rangename, pf, &sfd->para.socket.range,
|
||||||
if (xioparserange(rangename, pf, &xfd->para.socket.range,
|
sfd->para.socket.ip.ai_flags)
|
||||||
xfd->para.socket.ip.ai_flags)
|
|
||||||
< 0) {
|
< 0) {
|
||||||
free(rangename);
|
free(rangename);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
xfd->para.socket.dorange = true;
|
sfd->para.socket.dorange = true;
|
||||||
xfd->dtype |= XIOREAD_RECV_CHECKRANGE;
|
sfd->dtype |= XIOREAD_RECV_CHECKRANGE;
|
||||||
free(rangename);
|
free(rangename);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WITH_LIBWRAP
|
#if WITH_LIBWRAP
|
||||||
xio_retropt_tcpwrap(xfd, opts);
|
xio_retropt_tcpwrap(sfd, opts);
|
||||||
#endif /* WITH_LIBWRAP */
|
#endif /* WITH_LIBWRAP */
|
||||||
|
|
||||||
_xio_openlate(xfd, opts);
|
_xio_openlate(sfd, opts);
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static int xioopen_udp_recvfrom(
|
||||||
int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts,
|
int argc,
|
||||||
int xioflags, xiofile_t *xfd, groups_t groups,
|
const char *argv[],
|
||||||
int pf, int socktype, int ipproto) {
|
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;
|
union sockaddr_union us;
|
||||||
socklen_t uslen = sizeof(us);
|
socklen_t uslen = sizeof(us);
|
||||||
int ai_flags2[2];
|
int ai_flags2[2];
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
xioinit_ip(&pf, xioparms.default_ip);
|
xioinit_ip(&pf, xioparms.default_ip);
|
||||||
xfd->stream.howtoend = END_NONE;
|
sfd->howtoend = END_NONE;
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
if (pf == PF_UNSPEC) {
|
if (pf == PF_UNSPEC) {
|
||||||
#if WITH_IP4 && WITH_IP6
|
#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);
|
socklen_t lalen = sizeof(la);
|
||||||
|
|
||||||
if (retropt_bind(opts, pf, socktype, ipproto, &la.soa, &lalen, 1,
|
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) {
|
!= STAT_NOACTION) {
|
||||||
switch (pf) {
|
switch (pf) {
|
||||||
#if WITH_IP4
|
#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) {
|
if (retropt_ushort(opts, OPT_SOURCEPORT, &sfd->para.socket.ip.sourceport) >= 0) {
|
||||||
xfd->stream.para.socket.ip.dosourceport = true;
|
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;
|
xfd->stream.dtype = XIODATA_RECVFROM_ONE;
|
||||||
if ((result =
|
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))
|
opts, pf, socktype, ipproto, E_ERROR))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return result;
|
return result;
|
||||||
|
@ -578,10 +593,17 @@ int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static int xioopen_udp_recv(
|
||||||
int xioopen_udp_recv(int argc, const char *argv[], struct opt *opts,
|
int argc,
|
||||||
int xioflags, xiofile_t *xfd, groups_t groups,
|
const char *argv[],
|
||||||
int pf, int socktype, int ipproto) {
|
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;
|
union sockaddr_union us;
|
||||||
socklen_t uslen = sizeof(us);
|
socklen_t uslen = sizeof(us);
|
||||||
char *rangename;
|
char *rangename;
|
||||||
|
@ -589,8 +611,7 @@ int xioopen_udp_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,6 @@ extern int _xioopen_ipdgram_listen(struct single *sfd,
|
||||||
int xioflags, union sockaddr_union *us, socklen_t uslen,
|
int xioflags, union sockaddr_union *us, socklen_t uslen,
|
||||||
struct opt *opts, int pf, int socktype, int ipproto);
|
struct opt *opts, int pf, int socktype, int ipproto);
|
||||||
|
|
||||||
extern int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
extern int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||||
int rw, xiofile_t *fd,
|
|
||||||
groups_t groups, int af, int ipproto,
|
|
||||||
int protname);
|
|
||||||
|
|
||||||
#endif /* !defined(__xio_udp_h_included) */
|
#endif /* !defined(__xio_udp_h_included) */
|
||||||
|
|
335
xio-unix.c
335
xio-unix.c
|
@ -24,16 +24,12 @@
|
||||||
# define ABSTRACT 0
|
# define ABSTRACT 0
|
||||||
#endif
|
#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_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, 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);
|
||||||
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_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, 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, const struct addrdesc *addrdesc);
|
||||||
static
|
static int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
|
||||||
int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
|
||||||
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);
|
|
||||||
|
|
||||||
/* the first free parameter is 0 for "normal" unix domain sockets, or 1 for
|
/* 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
|
abstract unix sockets (Linux); the second and third free parameter are
|
||||||
|
@ -115,10 +111,17 @@ xiosetunix(int pf,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WITH_LISTEN
|
#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 */
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
xiosingle_t *sfd = &xxfd->stream;
|
||||||
int pf = PF_UNIX;
|
int pf = PF_UNIX;
|
||||||
int socktype = SOCK_STREAM;
|
int socktype = SOCK_STREAM;
|
||||||
int protocol = 0;
|
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;
|
struct opt *opts0 = NULL;
|
||||||
pid_t pid = Getpid();
|
pid_t pid = Getpid();
|
||||||
bool opt_unlink_early = false;
|
bool opt_unlink_early = false;
|
||||||
bool opt_unlink_close = (abstract != 1);
|
bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1);
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
|
|
||||||
xfd->para.socket.un.tight = true;
|
sfd->para.socket.un.tight = true;
|
||||||
retropt_socket_pf(opts, &pf);
|
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 */
|
/* only for non abstract because abstract do not work in file system */
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
applyopts(xfd, -1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||||
applyopts_offset(xfd, opts);
|
applyopts_offset(sfd, opts);
|
||||||
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 (!(ABSTRACT && abstract)) {
|
if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) {
|
||||||
if (opt_unlink_early) {
|
if (opt_unlink_early) {
|
||||||
xio_unlink(name, E_ERROR);
|
xio_unlink(name, E_ERROR);
|
||||||
} else {
|
} else {
|
||||||
|
@ -166,10 +169,10 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opt_unlink_close) {
|
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);
|
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
|
/* 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() */
|
/* this may fork() */
|
||||||
if ((result =
|
if ((result =
|
||||||
xioopen_listen(xfd, xioflags,
|
xioopen_listen(sfd, xioflags,
|
||||||
(struct sockaddr *)&us, uslen,
|
(struct sockaddr *)&us, uslen,
|
||||||
opts, opts0, pf, socktype, protocol))
|
opts, opts0, pf, socktype, protocol))
|
||||||
!= 0)
|
!= 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (!(ABSTRACT && abstract)) {
|
if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) {
|
||||||
if (opt_unlink_close) {
|
if (opt_unlink_close) {
|
||||||
if (pid != Getpid()) {
|
if (pid != Getpid()) {
|
||||||
/* in a child process - do not unlink-close here! */
|
/* 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 */
|
#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 */
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
struct single *xfd = &xxfd->stream;
|
struct single *sfd = &xxfd->stream;
|
||||||
const struct opt *namedopt;
|
const struct opt *namedopt;
|
||||||
int pf = PF_UNIX;
|
int pf = PF_UNIX;
|
||||||
int socktype = SOCK_STREAM;
|
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;
|
struct sockaddr_un them, us;
|
||||||
socklen_t themlen, uslen = sizeof(us);
|
socklen_t themlen, uslen = sizeof(us);
|
||||||
bool needbind = false;
|
bool needbind = false;
|
||||||
bool opt_unlink_close = (abstract != 1);
|
bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1);
|
||||||
bool dofork = false;
|
bool dofork = false;
|
||||||
struct opt *opts0;
|
struct opt *opts0;
|
||||||
char infobuff[256];
|
char infobuff[256];
|
||||||
|
@ -219,28 +229,29 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
|
|
||||||
xfd->para.socket.un.tight = true;
|
sfd->para.socket.un.tight = true;
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
applyopts(xfd, -1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
applyopts_offset(xfd, opts);
|
applyopts_offset(sfd, opts);
|
||||||
applyopts(xfd, -1, opts, PH_EARLY);
|
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)) {
|
if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) {
|
||||||
/* only for non abstract because abstract do not work in file system */
|
/* Only for non abstract because abstract do not work in file system */
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
}
|
}
|
||||||
if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen,
|
if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &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) {
|
== STAT_OK) {
|
||||||
needbind = true;
|
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 (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);
|
Error1("strdup(\"%s\"): out of memory", name);
|
||||||
}
|
}
|
||||||
xfd->opt_unlink_close = true;
|
sfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
retropt_bool(opts, OPT_FORK, &dofork);
|
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 */
|
do { /* loop over retries and forks */
|
||||||
|
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
level = E_INFO;
|
level = E_INFO;
|
||||||
} else
|
} else
|
||||||
#endif /* WITH_RETRY */
|
#endif /* WITH_RETRY */
|
||||||
level = E_ERROR;
|
level = E_ERROR;
|
||||||
|
|
||||||
result =
|
result =
|
||||||
_xioopen_connect(xfd,
|
_xioopen_connect(sfd,
|
||||||
needbind?(union sockaddr_union *)&us:NULL, uslen,
|
needbind?(union sockaddr_union *)&us:NULL, uslen,
|
||||||
(struct sockaddr *)&them, themlen,
|
(struct sockaddr *)&them, themlen,
|
||||||
opts, pf, socktype, protocol, false, level);
|
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;
|
case STAT_OK: break;
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
case STAT_RETRYLATER:
|
case STAT_RETRYLATER:
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
--xfd->retry;
|
--sfd->retry;
|
||||||
if (result == STAT_RETRYLATER) {
|
if (result == STAT_RETRYLATER) {
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
}
|
}
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
continue;
|
continue;
|
||||||
|
@ -311,16 +322,16 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
if (dofork) {
|
if (dofork) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int level = E_ERROR;
|
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,
|
level = E_WARN; /* most users won't expect a problem here,
|
||||||
so Notice is too weak */
|
so Notice is too weak */
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((pid = xio_fork(false, level, xfd->shutup)) < 0) {
|
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
|
||||||
--xfd->retry;
|
--sfd->retry;
|
||||||
if (xfd->forever || xfd->retry) {
|
if (sfd->forever || sfd->retry) {
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
Nanosleep(&xfd->intervall, NULL); continue;
|
Nanosleep(&sfd->intervall, NULL); continue;
|
||||||
}
|
}
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
@ -330,9 +341,9 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parent process */
|
/* parent process */
|
||||||
Close(xfd->fd);
|
Close(sfd->fd);
|
||||||
/* with and without retry */
|
/* with and without retry */
|
||||||
Nanosleep(&xfd->intervall, NULL);
|
Nanosleep(&sfd->intervall, NULL);
|
||||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||||
continue; /* with next socket() bind() connect() */
|
continue; /* with next socket() bind() connect() */
|
||||||
} else
|
} else
|
||||||
|
@ -342,17 +353,31 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
}
|
}
|
||||||
} while (true);
|
} 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 result;
|
||||||
}
|
}
|
||||||
return STAT_OK;
|
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 */
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
xiosingle_t *sfd = &xxfd->stream;
|
||||||
const struct opt *namedopt;
|
const struct opt *namedopt;
|
||||||
int pf = PF_UNIX;
|
int pf = PF_UNIX;
|
||||||
int socktype = SOCK_DGRAM;
|
int socktype = SOCK_DGRAM;
|
||||||
|
@ -360,32 +385,32 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
socklen_t uslen = sizeof(us);
|
socklen_t uslen = sizeof(us);
|
||||||
bool needbind = false;
|
bool needbind = false;
|
||||||
bool opt_unlink_close = (abstract != 1);
|
bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1);
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
|
|
||||||
xfd->para.socket.un.tight = true;
|
sfd->para.socket.un.tight = true;
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
applyopts_offset(xfd, opts);
|
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 */
|
/* only for non abstract because abstract do not work in file system */
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->dtype = XIODATA_RECVFROM;
|
sfd->dtype = XIODATA_RECVFROM;
|
||||||
|
|
||||||
if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen,
|
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) {
|
== STAT_OK) {
|
||||||
needbind = true;
|
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);
|
Error1("Option \"%s\" only with bind option", namedopt->desc->defname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
|
||||||
applyopts(xfd, -1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
|
|
||||||
result =
|
result =
|
||||||
_xioopen_dgram_sendto(needbind?(union sockaddr_union *)&us:NULL, uslen,
|
_xioopen_dgram_sendto(needbind?(union sockaddr_union *)&us:NULL, uslen,
|
||||||
opts, xioflags, xfd, groups,
|
opts, xioflags, sfd, addrdesc->groups,
|
||||||
pf, socktype, protocol, 0);
|
pf, socktype, protocol, 0);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_unlink_close && needbind) {
|
if (opt_unlink_close && needbind) {
|
||||||
if ((xfd->unlink_close = strdup(us.un.sun_path)) == NULL) {
|
if ((sfd->unlink_close = strndup(us.un.sun_path, sizeof(us.un.sun_path))) == NULL) {
|
||||||
Error1("strdup(\"%s\"): out of memory", name);
|
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;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
int xioopen_unix_recvfrom(
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
int argc,
|
||||||
int abstract, int dummy2, int dummy3) {
|
const char *argv[],
|
||||||
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
/* we expect the form: filename */
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
xiosingle_t *sfd = &xxfd->stream;
|
||||||
int pf = PF_UNIX;
|
int pf = PF_UNIX;
|
||||||
int socktype = SOCK_DGRAM;
|
int socktype = SOCK_DGRAM;
|
||||||
int protocol = 0;
|
int protocol = 0;
|
||||||
|
@ -430,40 +460,41 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
bool needbind = true;
|
bool needbind = true;
|
||||||
bool opt_unlink_early = false;
|
bool opt_unlink_early = false;
|
||||||
bool opt_unlink_close = (abstract != 1);
|
bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1);
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
|
|
||||||
xfd->para.socket.un.tight = true;
|
sfd->para.socket.un.tight = true;
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
xfd->howtoend = END_NONE;
|
sfd->howtoend = END_NONE;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
applyopts(xfd, -1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
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 */
|
/* only for non abstract because abstract do not work in file system */
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
}
|
}
|
||||||
applyopts(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 0
|
||||||
if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen,
|
if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &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) {
|
== STAT_OK) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!(ABSTRACT && abstract)) {
|
if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) {
|
||||||
if (opt_unlink_early) {
|
if (opt_unlink_early) {
|
||||||
xio_unlink(name, E_ERROR);
|
xio_unlink(name, E_ERROR);
|
||||||
} else {
|
} else {
|
||||||
|
@ -474,10 +505,10 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opt_unlink_close) {
|
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);
|
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
|
/* 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! */
|
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 */
|
/* this may fork */
|
||||||
return
|
return
|
||||||
_xioopen_dgram_recvfrom(xfd, xioflags,
|
_xioopen_dgram_recvfrom(sfd, xioflags,
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
needbind?(struct sockaddr *)&us:NULL, uslen,
|
||||||
opts, pf, socktype, protocol, E_ERROR);
|
opts, pf, socktype, protocol, E_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static int xioopen_unix_recv(
|
||||||
int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
int argc,
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
const char *argv[],
|
||||||
int abstract, int dummy2, int dummy3) {
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
/* we expect the form: filename */
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
xiosingle_t *sfd = &xxfd->stream;
|
||||||
int pf = PF_UNIX;
|
int pf = PF_UNIX;
|
||||||
int socktype = SOCK_DGRAM;
|
int socktype = SOCK_DGRAM;
|
||||||
int protocol = 0;
|
int protocol = 0;
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
bool opt_unlink_early = false;
|
bool opt_unlink_early = false;
|
||||||
bool opt_unlink_close = (abstract != 1);
|
bool opt_unlink_close = (addrdesc->arg1/*abstract*/ != 1);
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
|
|
||||||
xfd->para.socket.un.tight = true;
|
sfd->para.socket.un.tight = true;
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
applyopts(xfd, -1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
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 */
|
/* only for non abstract because abstract do not work in file system */
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
}
|
}
|
||||||
applyopts(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 0
|
||||||
if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen,
|
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) {
|
== STAT_OK) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!(ABSTRACT && abstract)) {
|
if (!(ABSTRACT && addrdesc->arg1/*abstract*/)) {
|
||||||
if (opt_unlink_early) {
|
if (opt_unlink_early) {
|
||||||
xio_unlink(name, E_ERROR);
|
xio_unlink(name, E_ERROR);
|
||||||
} else {
|
} else {
|
||||||
|
@ -555,33 +591,41 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opt_unlink_close) {
|
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);
|
Error1("strdup(\"%s\"): out of memory", name);
|
||||||
}
|
}
|
||||||
xfd->opt_unlink_close = true;
|
sfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
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;
|
sfd->dtype = XIODATA_RECV;
|
||||||
result = _xioopen_dgram_recv(xfd, xioflags, &us.soa, uslen,
|
result = _xioopen_dgram_recv(sfd, xioflags, &us.soa, uslen,
|
||||||
opts, pf, socktype, protocol, E_ERROR);
|
opts, pf, socktype, protocol, E_ERROR);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* generic UNIX socket client, tries connect, SEQPACKET, send(to) */
|
/* 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 */
|
/* we expect the form: filename */
|
||||||
if (argc != 2) {
|
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
|
return
|
||||||
_xioopen_unix_client(&xxfd->stream, xioflags, groups, abstract, opts,
|
_xioopen_unix_client(&xxfd->stream, xioflags, addrdesc->groups,
|
||||||
argv[1]);
|
addrdesc->arg1/*abstract*/, opts, argv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* establishes communication with an existing UNIX type socket. supports stream
|
/* 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,
|
OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_CLOEXEC, OPT_USER, OPT_GROUP, ?OPT_FORK,
|
||||||
*/
|
*/
|
||||||
int
|
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) {
|
int abstract, struct opt *opts, const char *name) {
|
||||||
const struct opt *namedopt;
|
const struct opt *namedopt;
|
||||||
int pf = PF_UNIX;
|
int pf = PF_UNIX;
|
||||||
|
@ -608,23 +652,24 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups,
|
||||||
struct opt *opts0;
|
struct opt *opts0;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
xfd->para.socket.un.tight = true;
|
sfd->para.socket.un.tight = true;
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
sfd->howtoend = END_SHUTDOWN;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
if (applyopts_single(sfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
applyopts(xfd, -1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
applyopts_offset(xfd, opts);
|
applyopts_offset(sfd, opts);
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
retropt_int(opts, OPT_SO_PROTOTYPE, &protocol);
|
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)) {
|
if (!(ABSTRACT && abstract)) {
|
||||||
/* only for non abstract because abstract do not work in file system */
|
/* only for non abstract because abstract do not work in file system */
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
}
|
}
|
||||||
if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen,
|
if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen,
|
||||||
(abstract<<1)|xfd->para.socket.un.tight, NULL)
|
(abstract<<1)|sfd->para.socket.un.tight,
|
||||||
|
sfd->para.socket.ip.ai_flags)
|
||||||
!= STAT_NOACTION) {
|
!= STAT_NOACTION) {
|
||||||
needbind = true;
|
needbind = true;
|
||||||
}
|
}
|
||||||
|
@ -635,10 +680,10 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_unlink_close) {
|
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);
|
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 */
|
/* 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 */
|
/* just a breakable block, helps to avoid goto */
|
||||||
do {
|
do {
|
||||||
/* xfd->dtype = DATA_STREAM; // is default */
|
/* sfd->dtype = DATA_STREAM; // is default */
|
||||||
/* this function handles AF_UNIX with EPROTOTYPE specially for us */
|
/* this function handles AF_UNIX with EPROTOTYPE specially for us */
|
||||||
if ((result =
|
if ((result =
|
||||||
_xioopen_connect(xfd,
|
_xioopen_connect(sfd,
|
||||||
needbind?&us:NULL, uslen,
|
needbind?&us:NULL, uslen,
|
||||||
&them.soa, themlen,
|
&them.soa, themlen,
|
||||||
opts, pf, socktype?socktype:SOCK_STREAM, protocol,
|
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;
|
socktype = SOCK_SEQPACKET;
|
||||||
if ((result =
|
if ((result =
|
||||||
_xioopen_connect(xfd,
|
_xioopen_connect(sfd,
|
||||||
needbind?&us:NULL, uslen,
|
needbind?&us:NULL, uslen,
|
||||||
(struct sockaddr *)&them, themlen,
|
(struct sockaddr *)&them, themlen,
|
||||||
opts, pf, SOCK_SEQPACKET, protocol,
|
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);
|
xio_unlink(us.un.sun_path, E_ERROR);
|
||||||
dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0;
|
dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0;
|
||||||
|
|
||||||
xfd->peersa = them;
|
sfd->peersa = them;
|
||||||
xfd->salen = sizeof(struct sockaddr_un);
|
sfd->salen = sizeof(struct sockaddr_un);
|
||||||
if ((result =
|
if ((result =
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
||||||
opts, xioflags, xfd, groups,
|
opts, xioflags, sfd, groups,
|
||||||
pf, SOCK_DGRAM, protocol, 0))
|
pf, SOCK_DGRAM, protocol, 0))
|
||||||
== 0) {
|
== 0) {
|
||||||
xfd->dtype = XIODATA_RECVFROM;
|
sfd->dtype = XIODATA_RECVFROM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
|
@ -694,7 +739,7 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, groups_t groups,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0) {
|
if ((result = _xio_openlate(sfd, opts)) < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
68
xio-vsock.c
68
xio-vsock.c
|
@ -13,12 +13,8 @@
|
||||||
#include "xio-socket.h"
|
#include "xio-socket.h"
|
||||||
#include "xio-vsock.h"
|
#include "xio-vsock.h"
|
||||||
|
|
||||||
static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups, int abstract,
|
static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, const struct addrdesc *addrdesc);
|
||||||
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 void xiolog_vsock_cid(void);
|
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 */
|
/* 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;
|
return STAT_NORETRY;
|
||||||
|
|
||||||
applyopts(xfd, -1, opts, PH_INIT);
|
applyopts(sfd, -1, opts, PH_INIT);
|
||||||
applyopts(xfd, -1, opts, PH_EARLY);
|
applyopts(sfd, -1, opts, PH_EARLY);
|
||||||
|
|
||||||
xfd->dtype = XIODATA_STREAM;
|
sfd->dtype = XIODATA_STREAM;
|
||||||
|
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_vsock_connect(
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
int argc,
|
||||||
int abstract, int dummy2, int dummy3) {
|
const char *argv[],
|
||||||
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
/* we expect the form :cid:port */
|
/* we expect the form :cid:port */
|
||||||
struct single *xfd = &xxfd->stream;
|
struct single *sfd = &xxfd->stream;
|
||||||
struct sockaddr_vm sa, sa_local;
|
struct sockaddr_vm sa, sa_local;
|
||||||
socklen_t sa_len = sizeof(sa);
|
socklen_t sa_len = sizeof(sa);
|
||||||
bool needbind = false;
|
bool needbind = false;
|
||||||
|
@ -74,8 +75,7 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 2)",
|
xio_syntax(argv[0], 2, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = vsock_init(opts, xfd);
|
ret = vsock_init(opts, sfd);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -96,19 +96,20 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
xiolog_vsock_cid();
|
xiolog_vsock_cid();
|
||||||
|
|
||||||
ret = retropt_bind(opts, pf, socktype, protocol,
|
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)
|
if (ret == STAT_NORETRY)
|
||||||
return ret;
|
return ret;
|
||||||
if (ret == STAT_OK)
|
if (ret == STAT_OK)
|
||||||
needbind = true;
|
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),
|
sa_len, (struct sockaddr *)&sa, sizeof(sa),
|
||||||
opts, pf, socktype, protocol, false);
|
opts, pf, socktype, protocol, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = _xio_openlate(xfd, opts);
|
ret = _xio_openlate(sfd, opts);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -117,11 +118,16 @@ static int xioopen_vsock_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
|
|
||||||
|
|
||||||
#if WITH_LISTEN
|
#if WITH_LISTEN
|
||||||
static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts,
|
static int xioopen_vsock_listen(
|
||||||
int xioflags, xiofile_t *xxfd, groups_t groups, int abstract,
|
int argc,
|
||||||
int dummy2, int dummy3) {
|
const char *argv[],
|
||||||
|
struct opt *opts,
|
||||||
|
int xioflags,
|
||||||
|
xiofile_t *xxfd,
|
||||||
|
const struct addrdesc *addrdesc)
|
||||||
|
{
|
||||||
/* we expect the form :port */
|
/* we expect the form :port */
|
||||||
struct single *xfd = &xxfd->stream;
|
struct single *sfd = &xxfd->stream;
|
||||||
struct sockaddr_vm sa, sa_bind;
|
struct sockaddr_vm sa, sa_bind;
|
||||||
socklen_t sa_len = sizeof(sa_bind);
|
socklen_t sa_len = sizeof(sa_bind);
|
||||||
struct opt *opts0;
|
struct opt *opts0;
|
||||||
|
@ -131,8 +137,7 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
xio_syntax(argv[0], 1, argc-1, addrdesc->syntax);
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +150,7 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = vsock_init(opts, xfd);
|
ret = vsock_init(opts, sfd);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return 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);
|
opts0 = copyopts(opts, GROUP_ALL);
|
||||||
|
|
||||||
ret = retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&sa_bind,
|
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)
|
if (ret == STAT_NORETRY)
|
||||||
return ret;
|
return ret;
|
||||||
if (ret == STAT_OK)
|
if (ret == STAT_OK)
|
||||||
|
@ -162,7 +168,7 @@ static int xioopen_vsock_listen(int argc, const char *argv[], struct opt *opts,
|
||||||
xiolog_vsock_cid();
|
xiolog_vsock_cid();
|
||||||
|
|
||||||
/* this may fork() */
|
/* 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);
|
opts, opts0, pf, socktype, protocol);
|
||||||
}
|
}
|
||||||
#endif /* WITH_LISTEN */
|
#endif /* WITH_LISTEN */
|
||||||
|
|
3
xio.h
3
xio.h
|
@ -355,8 +355,7 @@ typedef union bipipe {
|
||||||
struct addrdesc {
|
struct addrdesc {
|
||||||
const char *defname; /* main (canonical) name of address */
|
const char *defname; /* main (canonical) name of address */
|
||||||
int directions; /* 1..read, 2..write, 3..both */
|
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 (*func)(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *fd, const struct addrdesc *addrdesc);
|
||||||
int arg1, int arg2, int arg3);
|
|
||||||
groups_t groups;
|
groups_t groups;
|
||||||
int arg1;
|
int arg1;
|
||||||
int arg2;
|
int arg2;
|
||||||
|
|
12
xiohelp.c
12
xiohelp.c
|
@ -218,4 +218,16 @@ int xioopenhelp(FILE *of,
|
||||||
return 0;
|
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 */
|
#endif /* WITH_HELP */
|
||||||
|
|
|
@ -11,4 +11,6 @@ extern int xioopenhelp(FILE *of,
|
||||||
int level /* 0..only addresses, 1..and options */
|
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) */
|
#endif /* !defined(__xiohelp_h_included) */
|
||||||
|
|
13
xioopen.c
13
xioopen.c
|
@ -8,11 +8,11 @@
|
||||||
|
|
||||||
#include "xioopen.h"
|
#include "xioopen.h"
|
||||||
#include "xiomodes.h"
|
#include "xiomodes.h"
|
||||||
|
#include "xiohelp.h"
|
||||||
#include "nestlex.h"
|
#include "nestlex.h"
|
||||||
|
|
||||||
static xiofile_t *xioallocfd(void);
|
static xiofile_t *xioallocfd(void);
|
||||||
|
|
||||||
xiosingle_t hugo;
|
|
||||||
static xiosingle_t *xioparse_single(const char **addr);
|
static xiosingle_t *xioparse_single(const char **addr);
|
||||||
static xiofile_t *xioparse_dual(const char **addr);
|
static xiofile_t *xioparse_dual(const char **addr);
|
||||||
static int xioopen_dual(xiofile_t *xfd, int xioflags);
|
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);
|
xfd->stream.flags |= (xioflags & XIO_ACCMODE);
|
||||||
result = (*addrdesc->func)(xfd->stream.argc, xfd->stream.argv,
|
result = (*addrdesc->func)(xfd->stream.argc, xfd->stream.argv,
|
||||||
xfd->stream.opts, xioflags, xfd,
|
xfd->stream.opts, xioflags, xfd,
|
||||||
addrdesc->groups, addrdesc->arg1,
|
addrdesc);
|
||||||
addrdesc->arg2, addrdesc->arg3);
|
|
||||||
|
|
||||||
#if HAVE_RESOLV_H
|
#if HAVE_RESOLV_H
|
||||||
if (do_res)
|
if (do_res)
|
||||||
|
@ -690,3 +689,11 @@ int xioopen_single(xiofile_t *xfd, int xioflags) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int xio_syntax(
|
||||||
|
const char *addr,
|
||||||
|
int expectnum,
|
||||||
|
int isnum,
|
||||||
|
const char *syntax)
|
||||||
|
{
|
||||||
|
return xiohelp_syntax(addr, expectnum, isnum, syntax);
|
||||||
|
}
|
||||||
|
|
|
@ -45,6 +45,12 @@ extern const struct optname optionnames[];
|
||||||
|
|
||||||
extern int xioopen_makedual(xiofile_t *file);
|
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)
|
#define retropt_2bytes(o,c,r) retropt_ushort(o,c,r)
|
||||||
|
|
||||||
/* mode_t might be unsigned short or unsigned int or what else? */
|
/* mode_t might be unsigned short or unsigned int or what else? */
|
||||||
|
|
18
xioopts.c
18
xioopts.c
|
@ -151,7 +151,7 @@ bool xioopts_ignoregroups;
|
||||||
#endif
|
#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);
|
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 */
|
/* 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;
|
unsigned char *ptr;
|
||||||
|
|
||||||
ptr = (unsigned char *)xfd + opt->desc->major;
|
ptr = (unsigned char *)sfd + opt->desc->major;
|
||||||
switch (opt->desc->type) {
|
switch (opt->desc->type) {
|
||||||
case TYPE_BOOL:
|
case TYPE_BOOL:
|
||||||
*(bool *)ptr = opt->value.u_bool; break;
|
*(bool *)ptr = opt->value.u_bool; break;
|
||||||
|
@ -4117,7 +4117,7 @@ static int applyopt_offset(struct single *xfd, struct opt *opt) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int applyopts_offset(struct single *xfd, struct opt *opts) {
|
int applyopts_offset(struct single *sfd, struct opt *opts) {
|
||||||
struct opt *opt;
|
struct opt *opt;
|
||||||
|
|
||||||
opt = opts; while (opt->desc != ODESC_END) {
|
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->desc->func != OFUNC_OFFSET) {
|
||||||
++opt; continue; }
|
++opt; continue; }
|
||||||
|
|
||||||
applyopt_offset(xfd, opt);
|
applyopt_offset(sfd, opt);
|
||||||
opt->desc = ODESC_DONE;
|
opt->desc = ODESC_DONE;
|
||||||
++opt;
|
++opt;
|
||||||
}
|
}
|
||||||
return 0;
|
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 */
|
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;
|
struct opt *opt;
|
||||||
int rc = 0;
|
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) &&
|
if ((opt->desc != ODESC_DONE && opt->desc != ODESC_ERROR) &&
|
||||||
(opt->desc->phase == phase && phase != PH_ALL)) {
|
(opt->desc->phase == phase && phase != PH_ALL)) {
|
||||||
if (opt->desc->func < OFUNC_XIO) {
|
if (opt->desc->func < OFUNC_XIO) {
|
||||||
rc = applyopt(NULL, xfd->fd, opt);
|
rc = applyopt(NULL, sfd->fd, opt);
|
||||||
} else {
|
} else {
|
||||||
rc = applyopt(xfd, -1, opt);
|
rc = applyopt(sfd, -1, opt);
|
||||||
}
|
}
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
opt->desc = ODESC_DONE;
|
opt->desc = ODESC_DONE;
|
||||||
|
|
Loading…
Reference in a new issue