Parcourir la source

Merge branch 'creatorapi'

Michal 'vorner' Vaner il y a 13 ans
Parent
commit
2e60562cfd
1 fichiers modifiés avec 123 ajouts et 0 suppressions
  1. 123 0
      src/bin/bind10/creatorapi.txt

+ 123 - 0
src/bin/bind10/creatorapi.txt

@@ -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.