blob: 38fd9de62751ea54c152b2ef1b679cc4299a72e9 [file] [view] [edit]
# Replacing use of host OSes' bind() and connect()
These are notes on how to address [issue 344]
(http://code.google.com/p/nativeclient/issues/detail?id=344).
## What I thought the current protocol was
In the server process: * imc\_makeboundsock() does the following: * `token =
ChooseRandomToken()` * `fd = socket(AF_UNIX, SOCK_STREAM)` * `bind(fd, token)`
// An error here means two processes chose the same token, which is not supposed
to happen. * `listen(fd, backlog)` // Currently backlog=5 on Mac OS X. This is
bad because it exposes an arbitrary limit to NaCl processes. * `return
(SocketAddress(token), BoundSocket(fd))` * imc\_accept(BoundSocket(fd)) does: *
`sock_fd1 = accept(fd)` * `return ConnectedSocket(sock_fd1)`
In a client process: * imc\_connect(SocketAddress(token)) does: * `sock_fd2 =
socket(AF_UNIX, SOCK_STREAM)` * `connect(sock_fd2, token)` * `return
ConnectedSocket(sock_fd2)`
## Current protocol on Linux
In the server process: * imc\_makeboundsock() does the following: * `token =
ChooseRandomToken()` * `fd = socket(AF_UNIX, SOCK_DGRAM)` * `bind(fd, token)` //
An error here means two processes chose the same token, which is not supposed to
happen. * `return (SocketAddress(token), BoundSocket(fd))` *
imc\_accept(BoundSocket(fd)) does: * `sock_fd1 = recvmsg(fd)` * `return
ConnectedSocket(sock_fd1)`
In a client process: * imc\_connect(SocketAddress(token)) does: * `sock_fd1,
sock_fd2 = socketpair(AF_UNIX, SOCK_SEQPACKET)` * `sendmsg(global_fd, "",
[sock_fd1], address=token)` // global\_fd is only available if sel\_ldr is run
with "-X -1" * `close(sock_fd2)` * // The problem with this is that it succeeds
immediately. We don't know if our connection request was received. * `return
ConnectedSocket(sock_fd2)`
## Replacement protocol
In the server process: * imc\_makeboundsock() does the following: * `client_fd,
server_fd = socketpair(AF_UNIX, SOCK_STREAM)` * `return
(SocketAddress(client_fd), BoundSocket(server_fd))` *
imc\_accept(BoundSocket(server\_fd)) does: * `msg, sock_fd1 = recvmsg(server_fd,
single_byte_buffer)` * `assert msg == "c"` * `return ConnectedSocket(sock_fd1)`
// We assume that the FD that is sent to us behaves sanely.
In a client process: * imc\_connect(SocketAddress(client\_fd)) does: *
`sock_fd1, sock_fd2 = socketpair()` * `sendmsg(client_fd, "c", [sock_fd1])` *
`close(sock_fd1)` * // The problem with this is that it succeeds immediately. We
don't know if our connection request was received. * `return
ConnectedSocket(sock_fd2)`