Commit 2e60562c authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

Merge branch 'creatorapi'

parents 17a87c6b 2f49e3eb
Socket creator API
This API is between Boss and other modules to allow them requesting of sockets.
For simplicity, we will use the socket creator for all (even non-privileged)
ports for now, but we should have some function where we can abstract it later.
* Be able to request a socket of any combination IPv4/IPv6 UDP/TCP bound to given
port and address (sockets that are not bound to anything can be created
without privileges, therefore are not requested from the socket creator).
* Allow to provide the same socket to multiple modules (eg. multiple running
auth servers).
* Allow releasing the sockets (in case all modules using it give it up,
terminate or crash).
* Allow restricting of the sharing (don't allow shared socket between auth
and recursive, as the packets would often get to the wrong application,
show error instead).
* Get the socket to the application.
Transport of sockets
It seems we are stuck with current msgq for a while and there's a chance the
new replacement will not be able to send sockets inbound. So, we need another
The boss will create a unix-domain socket and listen on it. When something
requests a socket over the command channel and the socket is created, some kind
of token is returned to the application (which will represent the future
socket). The application then connects to the unix-domain socket, sends the
token over the connection (so Boss will know which socket to send there, in case
multiple applications ask for sockets simultaneously) and Boss sends the socket
in return.
In theory, we could send the requests directly over the unix-domain
socket, but it has two disadvantages:
* The msgq handles serializing/deserializing of structured
information (like the parameters to be used), we would have to do it
manually on the socket.
* We could place some kind of security in front of msgq (in case file
permissions are not enough, for example if they are not honored on
socket files, as indicated in the first paragraph of:
The socket would have to be secured separately. With the tokens,
there's some level of security already - someone not having the
token can't request a priviledged socket.
Caching of sockets
To allow sending the same socket to multiple application, the Boss process will
hold a cache. Each socket that is created and sent is kept open in Boss and
preserved there as well. A reference count is kept with each of them.
When another application asks for the same socket, it is simply sent from the
cache instead of creating it again by the creator.
When application gives the socket willingly (by sending a message over the
command channel), the reference count can be decreased without problems. But
when the application terminates or crashes, we need to decrease it as well.
There's a problem, since we don't know which command channel connection (eg.
lname) belongs to which PID. Furthermore, the applications don't need to be
started by boss.
There are two possibilities:
* Let the msgq send messages about disconnected clients (eg. group message to
some name). This one is better if we want to migrate to dbus, since dbus
already has this capability as well as sending the sockets inbound (at least it
seems so on unix) and we could get rid of the unix-domain socket completely.
* Keep the unix-domain connections open forever. Boss can remember which socket
was sent to which connection and when the connection closes (because the
application crashed), it can drop all the references on the sockets. This
seems easier to implement.
The commands
* Command to release a socket. This one would have single parameter, the token
used to get the socket. After this, boss would decrease its reference count
and if it drops to zero, close its own copy of the socket. This should be used
when the module stops using the socket (and after closes it). The
library could remember the file-descriptor to token mapping (for
common applications that don't request the same socket multiple
times in parallel).
* Command to request a socket. It would have parameters to specify which socket
(IP address, address family, port) and how to allow sharing. Sharing would be
one of:
- None
- Same kind of application (however, it is not entirely clear what
this means, in case it won't work out intuitively, we'll need to
define it somehow)
- Any kind of application
And a kind of application would be provided, to decide if the sharing is
possible (eg. if auth allows sharing with the same kind and something else
allows sharing with anything, the sharing is not possible, two auths can).
It would return either error (the socket can't be created or sharing is not
possible) or the token. Then there would be some time for the application to
pick up the requested socket.
We probably would have a library with blocking calls to request the
sockets, so a code could look like:
(socket_fd, token) = request_socket(address, port, 'UDP', SHARE_SAMENAME, 'test-application')
sock = socket.fromfd(socket_fd)
# Some sock.send and sock.recv stuff here
release_socket(socket_fd) # or release_socket(token)
Known limitations
Currently the socket creator doesn't support specifying any socket
options. If it turns out there are any options that need to be set
before bind(), we'll need to extend it (and extend the protocol as
well). If we want to support them, we'll have to solve a possible
conflict (what to do when two applications request the same socket and
want to share it, but want different options).
The current socket creator doesn't know raw sockets, but if they are
needed, it should be easy to add.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment