TODO.fd-passing: my current design additions/clarifications: fd-passing-final
authorStefan Metzmacher <metze@samba.org>
Tue, 11 Jun 2019 13:45:40 +0000 (15:45 +0200)
committerAnoop C S <anoopcs@samba.org>
Thu, 25 Jun 2020 08:37:42 +0000 (14:07 +0530)
TODO.fd-passing

index 3a0798c8382e0f5a294d0b8cfaeff2f5fe92b9c7..95f5107c0601720d9a6df81159976363adf7b52b 100644 (file)
      index that is not -1, create a socket_fd structure with the
      fi.fd = fds[i] (where fds is the received fd array) and
      fi.si_index = fd_indexes[i]. Bump si.refcount.
+
+From metze:
+
+  - We need to maintain a small file using mmap and protected
+    by pthread robust mutexes. E.g. one file per local ip address.
+  - The path specified in SOCKET_WRAPPER_FD_PASSING_DB will
+    be used as the file name, if this is not specified we'll
+    use malloc'ed and fd-passing is not enabled.
+  - The file contains a header (with magic, unique id, size and free-list pointer)
+    followed by an array of socket_info structures.
+  - The socket_info_fd structures will only maintain the index
+    into the mmap'ed array.
+  - fd-passing is limited to fixed number (~ 127), this should be
+    more than enough for typical caller (Samba would just use 1).
+  - In order to do fd-passing of tcp/udp sockets, we'll create
+    a pipe (or similar) where we write an array of with indexes
+    into the mmap'ed array into the write end of the pipe.
+    We would also pass the device/inode and a unique identifier
+    for the file.
+    The read end of the pipe is then passed as the last fd to
+    the destination process. The destination process can rebuild
+    the socket_info_fd structures by reading the array indexes.
+    out of the read end of the pipe.
+  - A tricky part will be the reference counting in the database
+    entries. The sender needs to write the data into the pipe
+    and increment the refcounts in the db file before calling
+    sendmsg(). The sender may hold a mutex for each socket
+    during sendmsg().
+  - In order to allow multiple threads (or processes) to share a single
+    socket we need to add mutex protection in quite a few places.
+    In the most common cases there won't be any contention on the mutexes,
+    but it will garantee correctness for the corner cases which happens
+    for fd-passing.
+
+An additional idea would be using temporary anonymous files (maybe
+memfd_create() or an similation for it) for shared structures for passed
+sockets. In sendmsg() the sender would move the socket_info[_container]
+structures from malloc'ed memory to an temporary memory file.
+This will replace the pipe fd of the original design.
+If multiple fd's are passed, the memory file contains an array of
+socket_info[_container] structures.
+int *socket_fds_idx would be changed to an array of structures
+or we have an additional array to store possible fd for the temporary
+files and have the destructing code lock at it and select between
+free() and munmap()/close().
+This design would not require a named file, like the one specified
+by SOCKET_WRAPPER_FD_PASSING_DB.
+
+Fixed size integer types!