Skip to content

Commit

Permalink
tcp: Add SIGPIPE on sendmsg for a broken connection
Browse files Browse the repository at this point in the history
Correct UNIX behavior requires a SIGPIPE when the connection is broken
(i.e we can't send or they won't listen). Add a nice common helper while
we're at it.

Signed-off-by: Pedro Falcato <[email protected]>
  • Loading branch information
heatd committed Jan 31, 2025
1 parent 4098752 commit 6838c3a
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 6 deletions.
2 changes: 2 additions & 0 deletions kernel/include/onyx/net/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,8 @@ static inline void sock_discharge_rmem_pbf(struct socket *sock, struct packetbuf
sock_discharge_rmem_bytes(sock, pbf->total_len);
}

int sock_stream_error(struct socket *sock, int err, int flags);

__END_CDECLS

#endif
8 changes: 8 additions & 0 deletions kernel/kernel/net/socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <onyx/net/netkernel.h>
#include <onyx/net/socket.h>
#include <onyx/poll.h>
#include <onyx/process.h>
#include <onyx/scoped_lock.h>
#include <onyx/utils.h>

Expand Down Expand Up @@ -1500,3 +1501,10 @@ int socket::setsockopt(int level, int optname, const void *optval, socklen_t opt
return -ENOPROTOOPT;
return setsockopt_socket_level(optname, optval, optlen);
}

int sock_stream_error(struct socket *sock, int err, int flags)
{
if (err == -EPIPE && !(flags & MSG_NOSIGNAL))
kernel_raise_signal(SIGPIPE, get_current_process(), 0, NULL);
return err;
}
16 changes: 10 additions & 6 deletions kernel/kernel/net/tcp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -951,16 +951,20 @@ ssize_t tcp_sendmsg(struct socket *sock_, const msghdr *msg, int flags)
scoped_hybrid_lock g{sock->socket_lock, sock};

if (sock->has_sock_err())
return sock->consume_sock_err();
return sock_stream_error(sock, sock->consume_sock_err(), flags);

if (!tcp_state_is_fl(sock, TCPF_STATE_CLOSE_WAIT | TCPF_STATE_ESTABLISHED))
if (sock->shutdown_state & SHUTDOWN_WR ||
!tcp_state_is_fl(sock, TCPF_STATE_CLOSE_WAIT | TCPF_STATE_ESTABLISHED))
{
err = -ENOTCONN;
err = -EPIPE;
if (sock->state == TCP_STATE_SYN_SENT)
{
err = tcp_wait_conn(sock);
if (!err && sock->state != TCP_STATE_ESTABLISHED)
err = -ENOTCONN;
return err;
if (!err && sock->state != TCP_STATE_ESTABLISHED)
err = -ENOTCONN;
}

return sock_stream_error(sock, err, flags);
}

auto len = iovec_count_length(msg->msg_iov, msg->msg_iovlen);
Expand Down

0 comments on commit 6838c3a

Please sign in to comment.