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:
parent
63f67101f4
commit
7b26406d96
16 changed files with 1660 additions and 649 deletions
40
xio-socket.c
40
xio-socket.c
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue