1
0
Fork 0
mirror of https://repo.or.cz/socat.git synced 2025-07-13 23:13:24 +00:00

Reworked IPAPP clients

This commit is contained in:
Gerhard 2025-02-10 12:48:04 +01:00
parent 63f67101f4
commit 7b26406d96
16 changed files with 1660 additions and 649 deletions

View file

@ -805,7 +805,7 @@ int xiogetpacketinfo(struct single *sfd, int fd)
with IP sockets: lowport (selects randomly a free port from 640 to 1023)
with UNIX and abstract sockets: uses tmpname() to find a free file system
entry.
returns 0 on success.
Returns STAT_OK on success, or STAT_RETRYLATER (+errno) on failure.
*/
int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
struct sockaddr *them, size_t themlen,
@ -835,7 +835,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
applyopts_cloexec(sfd->fd, opts);
if (xiobind(sfd, us, uslen, opts, pf, alt, level) < 0) {
return -1;
return STAT_RETRYLATER;
}
applyopts(sfd, -1, opts, PH_CONNECT);
@ -875,6 +875,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
Msg4(level, "xiopoll({%d,POLLOUT|POLLERR},,{"F_tv_sec"."F_tv_usec"): %s",
sfd->fd, timeout.tv_sec, timeout.tv_usec, strerror(errno));
Close(sfd->fd);
errno = _errno;
return STAT_RETRYLATER;
}
if (result == 0) {
@ -882,6 +883,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
strerror(ETIMEDOUT));
Close(sfd->fd);
errno = _errno;
return STAT_RETRYLATER;
}
if (writefd.revents & POLLERR) {
@ -897,15 +899,19 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
themlen, strerror(errno));
#endif
_errno = errno;
Close(sfd->fd);
errno = _errno;
return STAT_RETRYLATER;
}
/* otherwise OK or network error */
result = Getsockopt(sfd->fd, SOL_SOCKET, SO_ERROR, &err, &errlen);
if (result != 0) {
_errno = errno;
Msg2(level, "getsockopt(%d, SOL_SOCKET, SO_ERROR, ...): %s",
sfd->fd, strerror(err));
Close(sfd->fd);
errno = _errno;
return STAT_RETRYLATER;
}
Debug2("getsockopt(%d, SOL_SOCKET, SO_ERROR, { %d }) -> 0",
@ -915,6 +921,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
themlen, strerror(err));
Close(sfd->fd);
errno = err;
return STAT_RETRYLATER;
}
Fcntl_l(sfd->fd, F_SETFL, fcntl_flags);
@ -945,6 +952,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen,
sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
themlen, strerror(errno));
Close(sfd->fd);
errno = _errno;
return STAT_RETRYLATER;
}
} else { /* result >= 0 */
@ -1679,9 +1687,7 @@ int xiocheckrange(union sockaddr_union *sa, struct xiorange *range) {
int xiocheckpeer(xiosingle_t *sfd,
union sockaddr_union *pa, union sockaddr_union *la) {
char infobuff[256];
#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
int result;
#endif
#if WITH_IP4 || WITH_IP6
if (sfd->para.socket.dorange) {
@ -2091,9 +2097,8 @@ int xiosetsockaddrenv(const char *lr,
/* retrieves options so-type and so-prototype from opts, calls socket, and
ev. generates an appropriate error message.
returns 0 on success or -1 if an error occurred. */
int
xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) {
returns 0 on success or -1 (and errno) if an error occurred. */
int xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) {
int result;
retropt_int(opts, OPT_SO_TYPE, &socktype);
@ -2118,6 +2123,7 @@ xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) {
with IP sockets: lowport (selects randomly a free port from 640 to 1023)
with UNIX and abstract sockets: uses a method similar to tmpname() to
find a free file system entry.
On success returns STAT_OK, otherwise errno is set.
*/
int xiobind(
struct single *sfd,
@ -2154,18 +2160,20 @@ int xiobind(
usrname = strndup(us->un.sun_path, sizeof(us->un.sun_path));
if (usrname == NULL) {
int _errno = errno;
Error2("strndup(\"%s\", "F_Zu"): out of memory",
Msg2(level, "strndup(\"%s\", "F_Zu"): out of memory",
us->un.sun_path, sizeof(us->un.sun_path));
errno = _errno;
return -1;
return STAT_RETRYLATER;
}
}
do { /* loop over tempnam bind() attempts */
sockname = xio_tempnam(usrname, abstract);
if (sockname == NULL) {
int _errno = errno;
Error2("tempnam(\"%s\"): %s", usrname, strerror(errno));
free(usrname);
errno = _errno;
return -1;
}
strncpy(us->un.sun_path+(abstract?1:0), sockname, sizeof(us->un.sun_path));
@ -2179,8 +2187,10 @@ int xiobind(
infobuff, sizeof(infobuff)),
uslen, strerror(errno));
if (errno != EADDRINUSE) {
int _errno = errno;
free(usrname);
Close(sfd->fd);
errno = _errno;
return STAT_RETRYLATER;
}
} else {
@ -2193,10 +2203,12 @@ int xiobind(
if (us != NULL) {
if (Bind(sfd->fd, &us->soa, uslen) < 0) {
int _errno = errno;
Msg4(level, "bind(%d, {%s}, "F_Zd"): %s",
sfd->fd, sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)),
uslen, strerror(errno));
Close(sfd->fd);
errno = _errno;
return STAT_RETRYLATER;
}
applyopts_named(us->un.sun_path, opts, PH_PREOPEN);
@ -2268,12 +2280,14 @@ int xiobind(
do { /* loop over lowport bind() attempts */
*port = htons(i);
if (Bind(sfd->fd, &sinp->soa, sizeof(*sinp)) < 0) {
int _errno = errno;
Msg4(errno==EADDRINUSE?E_INFO:level,
"bind(%d, {%s}, "F_Zd"): %s", sfd->fd,
sockaddr_info(&sinp->soa, sizeof(*sinp), infobuff, sizeof(infobuff)),
sizeof(*sinp), strerror(errno));
if (errno != EADDRINUSE) {
if (_errno != EADDRINUSE) {
Close(sfd->fd);
errno = _errno;
return STAT_RETRYLATER;
}
} else {
@ -2282,8 +2296,8 @@ int xiobind(
--i; if (i < XIO_IPPORT_LOWER) i = IPPORT_RESERVED-1;
if (i == N) {
Msg(level, "no low port available");
/*errno = EADDRINUSE; still assigned */
Close(sfd->fd);
errno = EADDRINUSE;
return STAT_RETRYLATER;
}
} while (i != N);
@ -2294,17 +2308,19 @@ int xiobind(
if (us) {
applyopts(sfd, sfd->fd, opts, PH_BIND);
if (Bind(sfd->fd, &us->soa, uslen) < 0) {
int _errno = errno;
Msg4(level, "bind(%d, {%s}, "F_Zd"): %s",
sfd->fd, sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)),
uslen, strerror(errno));
Close(sfd->fd);
errno = _errno;
return STAT_RETRYLATER;
}
}
}
applyopts(sfd, -1, opts, PH_PASTBIND);
return 0;
return STAT_OK;
}
/* Handles the SO_REUSEADDR socket option for TCP LISTEN addresses depending on