|
@@ -0,0 +1,123 @@
|
|
|
+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.
|