123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- 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.
- Goals
- -----
- * 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
- channel.
- 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:
- http://lkml.indiana.edu/hypermail/linux/kernel/0505.2/0008.html).
- 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.
- Examples
- --------
- 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
- sock.close()
- 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.
|