From eba0774bf3bd2b89ca64f6851d465cb74559005c Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:23:09 -0400 Subject: [PATCH 1/3] Prevent `SIGPIPE` on Darwin when writing to a closed `core:net` socket Mimics behavior found on Linux implementation. --- core/net/socket_darwin.odin | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/net/socket_darwin.odin b/core/net/socket_darwin.odin index 10069963a33..83280cad9ae 100644 --- a/core/net/socket_darwin.odin +++ b/core/net/socket_darwin.odin @@ -35,6 +35,10 @@ Socket_Option :: enum c.int { Send_Timeout = c.int(os.SO_SNDTIMEO), } +// https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/socket.h#L1025-L1027 +// Prevent the raising of SIGPIPE on writing to a closed network socket. +@private MSG_NOSIGNAL :: 0x80000 + @(private) _create_socket :: proc(family: Address_Family, protocol: Socket_Protocol) -> (socket: Any_Socket, err: Network_Error) { c_type, c_protocol, c_family: int @@ -194,7 +198,7 @@ _send_tcp :: proc(skt: TCP_Socket, buf: []byte) -> (bytes_written: int, err: Net for bytes_written < len(buf) { limit := min(int(max(i32)), len(buf) - bytes_written) remaining := buf[bytes_written:][:limit] - res, res_err := os.send(os.Socket(skt), remaining, 0) + res, res_err := os.send(os.Socket(skt), remaining, MSG_NOSIGNAL) if res_err != nil { err = TCP_Send_Error(os.is_platform_error(res_err) or_else -1) return @@ -210,7 +214,7 @@ _send_udp :: proc(skt: UDP_Socket, buf: []byte, to: Endpoint) -> (bytes_written: for bytes_written < len(buf) { limit := min(1<<31, len(buf) - bytes_written) remaining := buf[bytes_written:][:limit] - res, res_err := os.sendto(os.Socket(skt), remaining, 0, cast(^os.SOCKADDR)&toaddr, i32(toaddr.len)) + res, res_err := os.sendto(os.Socket(skt), remaining, MSG_NOSIGNAL, cast(^os.SOCKADDR)&toaddr, i32(toaddr.len)) if res_err != nil { err = UDP_Send_Error(os.is_platform_error(res_err) or_else -1) return From 3512d7c672883da61a6a4e128242f5f3b56a830f Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:48:45 -0400 Subject: [PATCH 2/3] Move Darwin `MSG_NOSIGNAL` to `core:os` --- core/net/socket_darwin.odin | 8 ++------ core/os/os_darwin.odin | 4 ++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/net/socket_darwin.odin b/core/net/socket_darwin.odin index 83280cad9ae..83c62742399 100644 --- a/core/net/socket_darwin.odin +++ b/core/net/socket_darwin.odin @@ -35,10 +35,6 @@ Socket_Option :: enum c.int { Send_Timeout = c.int(os.SO_SNDTIMEO), } -// https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/socket.h#L1025-L1027 -// Prevent the raising of SIGPIPE on writing to a closed network socket. -@private MSG_NOSIGNAL :: 0x80000 - @(private) _create_socket :: proc(family: Address_Family, protocol: Socket_Protocol) -> (socket: Any_Socket, err: Network_Error) { c_type, c_protocol, c_family: int @@ -198,7 +194,7 @@ _send_tcp :: proc(skt: TCP_Socket, buf: []byte) -> (bytes_written: int, err: Net for bytes_written < len(buf) { limit := min(int(max(i32)), len(buf) - bytes_written) remaining := buf[bytes_written:][:limit] - res, res_err := os.send(os.Socket(skt), remaining, MSG_NOSIGNAL) + res, res_err := os.send(os.Socket(skt), remaining, os.MSG_NOSIGNAL) if res_err != nil { err = TCP_Send_Error(os.is_platform_error(res_err) or_else -1) return @@ -214,7 +210,7 @@ _send_udp :: proc(skt: UDP_Socket, buf: []byte, to: Endpoint) -> (bytes_written: for bytes_written < len(buf) { limit := min(1<<31, len(buf) - bytes_written) remaining := buf[bytes_written:][:limit] - res, res_err := os.sendto(os.Socket(skt), remaining, MSG_NOSIGNAL, cast(^os.SOCKADDR)&toaddr, i32(toaddr.len)) + res, res_err := os.sendto(os.Socket(skt), remaining, os.MSG_NOSIGNAL, cast(^os.SOCKADDR)&toaddr, i32(toaddr.len)) if res_err != nil { err = UDP_Send_Error(os.is_platform_error(res_err) or_else -1) return diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 09cdd84d062..f21dbb676ec 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -492,6 +492,10 @@ in6_addr :: struct #packed { s6_addr: [16]u8, } +// https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/socket.h#L1025-L1027 +// Prevent the raising of SIGPIPE on writing to a closed network socket. +MSG_NOSIGNAL :: 0x80000 + SIOCGIFFLAG :: enum c.int { UP = 0, /* Interface is up. */ BROADCAST = 1, /* Broadcast address valid. */ From 4c0ab09c9a88ae644b4b6ecd0a5b541428b0be24 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:51:56 -0400 Subject: [PATCH 3/3] Handle `EPIPE` in Darwin `core:net` --- core/net/socket_darwin.odin | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/net/socket_darwin.odin b/core/net/socket_darwin.odin index 83c62742399..ba369810b5f 100644 --- a/core/net/socket_darwin.odin +++ b/core/net/socket_darwin.odin @@ -195,7 +195,11 @@ _send_tcp :: proc(skt: TCP_Socket, buf: []byte) -> (bytes_written: int, err: Net limit := min(int(max(i32)), len(buf) - bytes_written) remaining := buf[bytes_written:][:limit] res, res_err := os.send(os.Socket(skt), remaining, os.MSG_NOSIGNAL) - if res_err != nil { + if res_err == os.EPIPE { + // EPIPE arises if the socket has been closed remotely. + err = TCP_Send_Error.Connection_Closed + return + } else if res_err != nil { err = TCP_Send_Error(os.is_platform_error(res_err) or_else -1) return } @@ -211,7 +215,11 @@ _send_udp :: proc(skt: UDP_Socket, buf: []byte, to: Endpoint) -> (bytes_written: limit := min(1<<31, len(buf) - bytes_written) remaining := buf[bytes_written:][:limit] res, res_err := os.sendto(os.Socket(skt), remaining, os.MSG_NOSIGNAL, cast(^os.SOCKADDR)&toaddr, i32(toaddr.len)) - if res_err != nil { + if res_err == os.EPIPE { + // EPIPE arises if the socket has been closed remotely. + err = UDP_Send_Error.Not_Socket + return + } else if res_err != nil { err = UDP_Send_Error(os.is_platform_error(res_err) or_else -1) return }