creatorapi.txt 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. Socket creator API
  2. ==================
  3. This API is between Boss and other modules to allow them requesting of sockets.
  4. For simplicity, we will use the socket creator for all (even non-privileged)
  5. ports for now, but we should have some function where we can abstract it later.
  6. Goals
  7. -----
  8. * Be able to request a socket of any combination IPv4/IPv6 UDP/TCP bound to given
  9. port and address (sockets that are not bound to anything can be created
  10. without privileges, therefore are not requested from the socket creator).
  11. * Allow to provide the same socket to multiple modules (eg. multiple running
  12. auth servers).
  13. * Allow releasing the sockets (in case all modules using it give it up,
  14. terminate or crash).
  15. * Allow restricting of the sharing (don't allow shared socket between auth
  16. and recursive, as the packets would often get to the wrong application,
  17. show error instead).
  18. * Get the socket to the application.
  19. Transport of sockets
  20. --------------------
  21. It seems we are stuck with current msgq for a while and there's a chance the
  22. new replacement will not be able to send sockets inbound. So, we need another
  23. channel.
  24. The boss will create a unix-domain socket and listen on it. When something
  25. requests a socket over the command channel and the socket is created, some kind
  26. of token is returned to the application (which will represent the future
  27. socket). The application then connects to the unix-domain socket, sends the
  28. token over the connection (so Boss will know which socket to send there, in case
  29. multiple applications ask for sockets simultaneously) and Boss sends the socket
  30. in return.
  31. In theory, we could send the requests directly over the unix-domain
  32. socket, but it has two disadvantages:
  33. * The msgq handles serializing/deserializing of structured
  34. information (like the parameters to be used), we would have to do it
  35. manually on the socket.
  36. * We could place some kind of security in front of msgq (in case file
  37. permissions are not enough, for example if they are not honored on
  38. socket files, as indicated in the first paragraph of:
  39. http://lkml.indiana.edu/hypermail/linux/kernel/0505.2/0008.html).
  40. The socket would have to be secured separately. With the tokens,
  41. there's some level of security already - someone not having the
  42. token can't request a priviledged socket.
  43. Caching of sockets
  44. ------------------
  45. To allow sending the same socket to multiple application, the Boss process will
  46. hold a cache. Each socket that is created and sent is kept open in Boss and
  47. preserved there as well. A reference count is kept with each of them.
  48. When another application asks for the same socket, it is simply sent from the
  49. cache instead of creating it again by the creator.
  50. When application gives the socket willingly (by sending a message over the
  51. command channel), the reference count can be decreased without problems. But
  52. when the application terminates or crashes, we need to decrease it as well.
  53. There's a problem, since we don't know which command channel connection (eg.
  54. lname) belongs to which PID. Furthermore, the applications don't need to be
  55. started by boss.
  56. There are two possibilities:
  57. * Let the msgq send messages about disconnected clients (eg. group message to
  58. some name). This one is better if we want to migrate to dbus, since dbus
  59. already has this capability as well as sending the sockets inbound (at least it
  60. seems so on unix) and we could get rid of the unix-domain socket completely.
  61. * Keep the unix-domain connections open forever. Boss can remember which socket
  62. was sent to which connection and when the connection closes (because the
  63. application crashed), it can drop all the references on the sockets. This
  64. seems easier to implement.
  65. The commands
  66. ------------
  67. * Command to release a socket. This one would have single parameter, the token
  68. used to get the socket. After this, boss would decrease its reference count
  69. and if it drops to zero, close its own copy of the socket. This should be used
  70. when the module stops using the socket (and after closes it). The
  71. library could remember the file-descriptor to token mapping (for
  72. common applications that don't request the same socket multiple
  73. times in parallel).
  74. * Command to request a socket. It would have parameters to specify which socket
  75. (IP address, address family, port) and how to allow sharing. Sharing would be
  76. one of:
  77. - None
  78. - Same kind of application (however, it is not entirely clear what
  79. this means, in case it won't work out intuitively, we'll need to
  80. define it somehow)
  81. - Any kind of application
  82. And a kind of application would be provided, to decide if the sharing is
  83. possible (eg. if auth allows sharing with the same kind and something else
  84. allows sharing with anything, the sharing is not possible, two auths can).
  85. It would return either error (the socket can't be created or sharing is not
  86. possible) or the token. Then there would be some time for the application to
  87. pick up the requested socket.
  88. Examples
  89. --------
  90. We probably would have a library with blocking calls to request the
  91. sockets, so a code could look like:
  92. (socket_fd, token) = request_socket(address, port, 'UDP', SHARE_SAMENAME, 'test-application')
  93. sock = socket.fromfd(socket_fd)
  94. # Some sock.send and sock.recv stuff here
  95. sock.close()
  96. release_socket(socket_fd) # or release_socket(token)
  97. Known limitations
  98. -----------------
  99. Currently the socket creator doesn't support specifying any socket
  100. options. If it turns out there are any options that need to be set
  101. before bind(), we'll need to extend it (and extend the protocol as
  102. well). If we want to support them, we'll have to solve a possible
  103. conflict (what to do when two applications request the same socket and
  104. want to share it, but want different options).
  105. The current socket creator doesn't know raw sockets, but if they are
  106. needed, it should be easy to add.