Skip to content

Support accept() for tcp wrapper#2768

Merged
stevenengler merged 2 commits intoshadow:mainfrom
stevenengler:wrap-tcp-rust
Feb 28, 2023
Merged

Support accept() for tcp wrapper#2768
stevenengler merged 2 commits intoshadow:mainfrom
stevenengler:wrap-tcp-rust

Conversation

@stevenengler
Copy link
Copy Markdown
Contributor

@stevenengler stevenengler commented Feb 28, 2023

The logic generally follows the logic from src/main/host/syscall/socket.c.

static SysCallReturn _syscallhandler_acceptHelper(SysCallHandler* sys,
int sockfd, PluginPtr addrPtr,
PluginPtr addrlenPtr,
int flags) {
trace("trying to accept on socket %i", sockfd);
/* Check that non-valid flags are not given. */
if (flags & ~(SOCK_NONBLOCK | SOCK_CLOEXEC)) {
debug("invalid flags \"%i\", only SOCK_NONBLOCK and SOCK_CLOEXEC are "
"allowed",
flags);
return syscallreturn_makeDoneErrno(EINVAL);
}
/* Get and validate the TCP socket. */
TCP* tcp_desc = NULL;
int errcode =
_syscallhandler_validateTCPSocketHelper(sys, sockfd, &tcp_desc);
if (errcode < 0) {
return syscallreturn_makeDoneErrno(-errcode);
}
utility_debugAssert(tcp_desc);
/* We must be listening in order to accept. */
if (!tcp_isValidListener(tcp_desc)) {
debug("socket %i is not listening", sockfd);
return syscallreturn_makeDoneErrno(EINVAL);
}
/* OK, now we can check if we have anything to accept. */
struct sockaddr_in inet_addr = {.sin_family = AF_INET};
int accepted_fd = 0;
errcode = tcp_acceptServerPeer(tcp_desc, _syscallhandler_getHost(sys),
&inet_addr.sin_addr.s_addr, &inet_addr.sin_port, &accepted_fd);
LegacyFile* legacyDesc = (LegacyFile*)tcp_desc;
if (errcode == -EWOULDBLOCK && !(legacyfile_getFlags(legacyDesc) & O_NONBLOCK)) {
/* This is a blocking accept, and we don't have a connection yet.
* The socket becomes readable when we have a connection to accept.
* This blocks indefinitely without a timeout. */
trace("Listening socket %i waiting for acceptable connection.", sockfd);
Trigger trigger = (Trigger){
.type = TRIGGER_DESCRIPTOR, .object = legacyDesc, .status = STATUS_FILE_READABLE};
return syscallreturn_makeBlocked(
syscallcondition_new(trigger), legacyfile_supportsSaRestart(legacyDesc));
} else if (errcode < 0) {
trace("TCP error when accepting connection on socket %i", sockfd);
return syscallreturn_makeDoneErrno(-errcode);
}
/* We accepted something! */
utility_debugAssert(accepted_fd > 0);
TCP* accepted_tcp_desc = NULL;
errcode = _syscallhandler_validateTCPSocketHelper(
sys, accepted_fd, &accepted_tcp_desc);
utility_debugAssert(errcode == 0);
trace("listening socket %i accepted fd %i", sockfd, accepted_fd);
/* Get the descriptor for this new socket and set flags if necessary. */
Descriptor* desc =
process_getRegisteredDescriptorMut(_syscallhandler_getProcess(sys), accepted_fd);
if (flags & SOCK_CLOEXEC) {
descriptor_setFlags(desc, O_CLOEXEC);
}
desc = NULL;
/* Set the flags on the accepted socket if requested. */
if (flags & SOCK_NONBLOCK) {
legacyfile_addFlags((LegacyFile*)accepted_tcp_desc, O_NONBLOCK);
}
/* check if they wanted to know where we got the data from */
if (addrPtr.val) {
errcode = _syscallhandler_getnameHelper(
sys, (struct sockaddr*)&inet_addr, sizeof(inet_addr), addrPtr, addrlenPtr);
if (errcode != 0) {
return syscallreturn_makeDoneErrno(-errcode);
}
}
return syscallreturn_makeDoneI64(accepted_fd);
}

Since the TCP code has already (incorrectly) added the socket to the descriptor table, we need to remove it from the table so that we can re-add it later in the accept() syscall handler.

@stevenengler stevenengler self-assigned this Feb 28, 2023
@github-actions github-actions bot added the Component: Main Composing the core Shadow executable label Feb 28, 2023
For legacy reasons, TCP sockets will already be stored in an `OpenFile` before
they're `accept()`ed, so we need to return this `OpenFile` back to the syscall
handler rather than just returning the socket object.
@stevenengler stevenengler merged commit 0cdd3bc into shadow:main Feb 28, 2023
@stevenengler stevenengler deleted the wrap-tcp-rust branch February 28, 2023 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component: Main Composing the core Shadow executable

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants