Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions include/NetAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,14 @@ Socket __cheri_compartment("NetAPI")
* of the connected client. These can be null if the caller is not interested
* in the client's address or port.
*
* This returns a valid sealed capability to a connected socket on success, or
* an untagged value on failure.
* This returns either a valid sealed socket type or an untagged capability that
* encodes the error code, and here are what each of them represent:
* - `-ENOMEM`: allocation of the wrapper timed out or does not have memory for
* now.
* - `-EINVAL`: The timeout pointer is invalid, or FreeRTOS_accept returns
* invalid socket, or fail to claim the socket poiting to mallocCapability, or
* fail to add socket to the socket reset list,
* - `-ETIMEDOUT`: timed out on FreeRTOS_accept.
*/
Socket __cheri_compartment("TCPIP")
network_socket_accept_tcp(Timeout *timeout,
Expand Down
47 changes: 36 additions & 11 deletions lib/tcpip/network_wrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,8 @@ Socket network_socket_accept_tcp(Timeout *timeout,
uint16_t *port)
{
Socket socket = nullptr;
with_sealed_socket(
int retVal = with_sealed_socket(
timeout,
[&](SealedSocket *listeningSocket) {
if (!check_timeout_pointer(timeout))
{
Expand All @@ -621,24 +622,39 @@ Socket network_socket_accept_tcp(Timeout *timeout,
if (socketWrapper == nullptr)
{
Debug::log("Failed to allocate socket wrapper.");
return -EINVAL;
return -ENOMEM;
}

socketWrapper->socketEpoch = currentSocketEpoch.load();

struct freertos_sockaddr addressTmp;
uint32_t addressLength = sizeof(addressTmp);
auto rawSocket = FreeRTOS_accept(
listeningSocket->socket, &addressTmp, &addressLength);
if (rawSocket == nullptr)
FreeRTOS_Socket_t *rawSocket = nullptr;

// acceptResult: 0 = valid socket || -EINVAL = FREERTOS_INVALID_SOCKET
// || -ETIMEDOUT = timed out
int acceptResult = with_freertos_timeout(
timeout,
listeningSocket->socket,
FREERTOS_SO_RCVTIMEO,
[&]() -> int {
rawSocket = FreeRTOS_accept(
listeningSocket->socket, &addressTmp, &addressLength);
if (rawSocket == nullptr)
{
return -ETIMEDOUT;
}
if (rawSocket == FREERTOS_INVALID_SOCKET)
{
return -EINVAL;
}
return 0; // returns a valid socket
});

if (acceptResult != 0)
{
Debug::log("Failed to create socket.");
// This cannot fail unless buggy - we know that we
// successfully allocated the token with this malloc
// capability. Same for other calls to `token_obj_destroy`
// in this function.
token_obj_destroy(mallocCapability, socket_key(), sealedSocket);
return -EINVAL;
return acceptResult;
}
socketWrapper->socket = rawSocket;

Expand Down Expand Up @@ -720,6 +736,15 @@ Socket network_socket_accept_tcp(Timeout *timeout,
return 0;
},
sealedListeningSocket);

if (retVal != 0)
{
__clang_ignored_warning_push("-Wcheri-capability-misuse");
auto errCode = reinterpret_cast<Socket>(retVal);
__clang_ignored_warning_pop();
return errCode;
}

return socket;
}

Expand Down
Loading