net: fix O_NONBLOCK races

Runtime modification of _shared_ socket flags like O_NONBLOCK
is a bad idea. If I remember correctly, long ago there was no
other way. Current kernels allow different flags on the stack per
kernel_*() call, but I am not sure whether this could break
compatibility with some very ancient kernels. Unfortunately, I
cannot test MARS with these dinosaur kernels anymore, but hopefully
nobody uses them anyway.
This commit is contained in:
Thomas Schoebel-Theuer 2018-10-22 07:35:24 +02:00
parent 18542103d6
commit 0d579d48ba
1 changed files with 8 additions and 15 deletions

View File

@ -178,10 +178,6 @@ void _set_socketopts(struct socket *sock)
_setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, default_tcp_params.tcp_keepidle);
_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, t);
_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, t);
if (sock->file) { // switch back to blocking mode
sock->file->f_flags &= ~O_NONBLOCK;
}
}
int mars_create_socket(struct mars_socket *msock, struct sockaddr_storage *addr, bool is_server)
@ -229,7 +225,7 @@ int mars_create_socket(struct mars_socket *msock, struct sockaddr_storage *addr,
MARS_WRN("#%d listen failed, status = %d\n", msock->s_debug_nr, status);
}
} else {
status = kernel_connect(sock, sockaddr, sizeof(*sockaddr), 0);
status = kernel_connect(sock, sockaddr, sizeof(*sockaddr), O_NONBLOCK);
/* Treat non-blocking connects as successful.
* Any potential errors will show up later during traffic.
*/
@ -585,16 +581,6 @@ int mars_recv_raw(struct mars_socket *msock, void *buf, int minlen, int maxlen)
if (!mars_get_socket(msock))
goto final;
if (minlen < maxlen) {
struct socket *sock = msock->s_socket;
if (sock && sock->file) {
/* Use nonblocking reads to consume as much data
* as possible
*/
sock->file->f_flags |= O_NONBLOCK;
}
}
MARS_IO("#%d receiving len=%d/%d bytes\n", msock->s_debug_nr, minlen, maxlen);
msock->s_recv_cnt = 0;
@ -624,6 +610,13 @@ int mars_recv_raw(struct mars_socket *msock, void *buf, int minlen, int maxlen)
goto err;
}
if (minlen < maxlen) {
/* Use nonblocking reads to consume as much data
* as possible
*/
msg.msg_flags |= O_NONBLOCK;
}
MARS_LOW("#%d done %d, fetching %d bytes\n", msock->s_debug_nr, done, maxlen-done);
status = kernel_recvmsg(sock, &msg, &iov, 1, maxlen-done, msg.msg_flags);