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:
parent
1878ae93fd
commit
1154e69d3e
12 changed files with 31 additions and 15 deletions
4
CHANGES
4
CHANGES
|
@ -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:
|
||||
|
|
2
socat.c
2
socat.c
|
@ -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;
|
||||
|
|
13
sysutils.c
13
sysutils.c
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
6
test.sh
6
test.sh
|
@ -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"
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
1
xio.h
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue