1
0
Fork 0
mirror of https://repo.or.cz/socat.git synced 2025-05-21 20:52:40 +00:00

writefull() respects total inactivity timeout

This commit is contained in:
Gerhard Rieger 2025-01-10 19:41:34 +01:00
parent 1878ae93fd
commit 1154e69d3e
12 changed files with 31 additions and 15 deletions

View file

@ -22,6 +22,9 @@ Corrections:
On partial write to not poll with sleep() but use select()/poll().
Partial write situations respect total inactivity timeout when
nonblocking.
Building:
Disabling certain features during configure could break build process.
@ -39,6 +42,7 @@ Testing:
SOCKS5 addresses are no longer experimental.
Tests: SOCKS5CONNECT_TCP4 SOCKS5LISTEN_TCP4
####################### V 1.8.0.2:
Security:

View file

@ -282,6 +282,8 @@ int main(int argc, const char *argv[]) {
socat_opts.total_timeout.tv_usec =
(rto-socat_opts.total_timeout.tv_sec) * 1000000;
}
xioparms.total_timeout.tv_sec = socat_opts.total_timeout.tv_sec;
xioparms.total_timeout.tv_usec = socat_opts.total_timeout.tv_usec;
break;
case 'u': if (arg1[0][2]) { socat_opt_hint(stderr, arg1[0][1], arg1[0][2]); Exit(1); }
socat_opts.lefttoright = true; break;

View file

@ -32,10 +32,15 @@ const int one = 1;
Then we can test partial write with something like:
socat -d4 -lu -b 262144 -u /dev/zero,readbytes=262144 -,o-nonblock |{ sleep 3; wc -c; }
*/
ssize_t writefull(int fd, const void *buff, size_t bytes) {
ssize_t writefull(
int fd,
const void *buff,
size_t bytes,
const struct timeval *tmo0) {
size_t writt = 0;
ssize_t chk;
struct pollfd pfd;
struct timeval tmo = { 0 };
int rc;
while (1) {
@ -51,7 +56,11 @@ ssize_t writefull(int fd, const void *buff, size_t bytes) {
pfd.fd = fd;
pfd.events = POLLOUT;
pfd.revents = 0;
rc = xiopoll(&pfd, 1, NULL);
if (tmo0 != NULL) {
tmo.tv_sec = tmo0->tv_sec;
tmo.tv_usec = tmo0->tv_usec;
}
rc = xiopoll(&pfd, 1, (tmo.tv_sec!=0 || tmo.tv_usec!=0) ? &tmo : NULL);
if (rc == 0) {
Notice("inactivity timeout triggered");
errno = ETIMEDOUT;

View file

@ -47,7 +47,7 @@ struct xiorange {
extern const int one;
#endif
extern ssize_t writefull(int fd, const void *buff, size_t bytes);
extern ssize_t writefull(int fd, const void *buff, size_t bytes, const struct timeval *tmo0);
#if _WITH_SOCKET
extern socklen_t socket_init(int af, union sockaddr_union *sa);

View file

@ -19053,7 +19053,7 @@ else
da="test$N $(date) $RANDOM"
case X$IPPORT in
XPORT) newport $(tolower $PROTO); _PORT=$PORT ;;
XPROTO) echo "IPPROTO=\"$IPPROTO\""
XPROTO) #echo "IPPROTO=\"$IPPROTO\""
_PORT=$IPPROTO ;;
esac
CMD0="$TRACE $SOCAT $opts ${ADDR}:$_PORT,$option,$ACCEPT_TIMEOUT PIPE"
@ -19146,7 +19146,7 @@ else
da="test$N $(date) $RANDOM"
case X$IPPORT in
XPORT) newport $(tolower $PROTO); _PORT=$PORT ;;
XPROTO) echo "IPPROTO=\"$IPPROTO\""
XPROTO) #echo "IPPROTO=\"$IPPROTO\""
_PORT=$IPPROTO ;;
esac
CMD0="$TRACE $SOCAT $opts -u /dev/null $ADDR:localhost-6-4.dest-unreach.net:$_PORT,bind=127.0.0.1"
@ -19211,7 +19211,7 @@ else
da="test$N $(date) $RANDOM"
case X$IPPORT in
XPORT) newport $(tolower $PROTO); _PORT=$PORT ;;
XPROTO) echo "IPPROTO=\"$IPPROTO\""
XPROTO) #echo "IPPROTO=\"$IPPROTO\""
_PORT=$IPPROTO ;;
esac
CMD0="$TRACE $SOCAT $opts ${ADDR%%-*}-LISTEN:$_PORT,pf=ip4 PIPE"

View file

@ -376,7 +376,7 @@ int _xioopen_proxy_connect(struct single *sfd,
* xiosanitize(request, strlen(request), textbuff) = '\0';
Info1("sending \"%s\"", textbuff);
/* write errors are assumed to always be hard errors, no retry */
if (writefull(sfd->fd, request, strlen(request)) < 0) {
if (writefull(sfd->fd, request, strlen(request), NULL) < 0) {
Msg4(level, "write(%d, %p, "F_Zu"): %s",
sfd->fd, request, strlen(request), strerror(errno));
if (Close(sfd->fd) < 0) {
@ -406,7 +406,7 @@ int _xioopen_proxy_connect(struct single *sfd,
*next = '\0';
Info1("sending \"%s\\r\\n\"", header);
*next++ = '\r'; *next++ = '\n'; *next++ = '\0';
if (writefull(sfd->fd, header, strlen(header)) < 0) {
if (writefull(sfd->fd, header, strlen(header), NULL) < 0) {
Msg4(level, "write(%d, %p, "F_Zu"): %s",
sfd->fd, header, strlen(header), strerror(errno));
if (Close(sfd->fd) < 0) {
@ -419,7 +419,7 @@ int _xioopen_proxy_connect(struct single *sfd,
}
Info("sending \"\\r\\n\"");
if (writefull(sfd->fd, "\r\n", 2) < 0) {
if (writefull(sfd->fd, "\r\n", 2, NULL) < 0) {
Msg2(level, "write(%d, \"\\r\\n\", 2): %s",
sfd->fd, strerror(errno));
if (Close(sfd->fd) < 0) {

View file

@ -184,7 +184,7 @@ ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) {
/* we must carriage return, because readline will first print the
prompt */
ssize_t writt;
writt = writefull(pipe->fd, "\r", 1);
writt = writefull(pipe->fd, "\r", 1, NULL);
if (writt < 0) {
Warn2("write(%d, \"\\r\", 1): %s",
pipe->fd, strerror(errno));

View file

@ -370,7 +370,7 @@ int _xioopen_socks4_connect(struct single *sfd,
}
}
#endif /* WITH_MSGLEVEL <= E_DEBUG */
if (writefull(sfd->fd, sockhead, headlen) < 0) {
if (writefull(sfd->fd, sockhead, headlen, NULL) < 0) {
Msg4(level, "write(%d, %p, "F_Zu"): %s",
sfd->fd, sockhead, headlen, strerror(errno));
if (Close(sfd->fd) < 0) {

View file

@ -136,7 +136,7 @@ static int _xioopen_socks5_handshake(struct single *sfd, int level)
}
#endif
if (writefull(sfd->fd, client_hello, client_hello_size) < 0) {
if (writefull(sfd->fd, client_hello, client_hello_size, NULL) < 0) {
Msg4(level, "write(%d, %p, %d): %s",
sfd->fd, client_hello, client_hello_size,
strerror(errno));
@ -426,7 +426,7 @@ static int _xioopen_socks5_request(
}
#endif
if (writefull(sfd->fd, req, bytes) < 0) {
if (writefull(sfd->fd, req, bytes, NULL) < 0) {
Msg4(level, "write(%d, %p, %d): %s",
sfd->fd, req, bytes, strerror(errno));
if (Close(sfd->fd) < 0) {

1
xio.h
View file

@ -120,6 +120,7 @@ typedef struct xioparms {
const char *sniffleft_name; /* file name with -r */
const char *sniffright_name; /* file name with -R */
size_t bufsiz;
struct timeval total_timeout;/* when nothing happens, die after seconds */
} xioparms_t;
/* pack the description of a lock file */

View file

@ -52,7 +52,7 @@ int xiogetlock(const char *lockfile) {
pid = Getpid();
bytes = sprintf(pidbuf, F_pid"\n", pid);
if (writefull(fd, pidbuf, bytes) < 0) {
if (writefull(fd, pidbuf, bytes, NULL) < 0) {
Error4("write(%d, %p, "F_Zu"): %s", fd, pidbuf, bytes, strerror(errno));
return -1;
}

View file

@ -50,7 +50,7 @@ ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) {
switch (pipe->dtype & XIODATA_WRITEMASK) {
case XIOWRITE_STREAM:
writt = writefull(pipe->fd, buff, bytes);
writt = writefull(pipe->fd, buff, bytes, NULL);
if (writt < 0) {
_errno = errno;
switch (_errno) {