summaryrefslogtreecommitdiffstats
path: root/src/bin/sockcreator/README
blob: 84a0f6db01a25846d0b3ac3ae17eb3309cb66970 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
The socket creator
==================

The only thing we need higher rights than standard user is binding sockets to
ports lower than 1024. So we will have a separate process that keeps the
rights, while the rests drop them for security reasons.

This process is the socket creator. Its goal is to be as simple as possible
and to contain as little code as possible to minimise the amount of code
running with higher privileges (to minimize the number of bugs and make
checking/auditing it easier). It uses low-level OS API instead of some
fancy library for that reason. It has only fixed-length reads so there's no
place for buffer overruns.

Protocol
--------

It talks with whoever started it by its stdin/stdout. It reads simple
binary protocol from stdin and does what the commands ask. Command is a single
byte (usually from the printable range, so it is easier to debug and guess
what it does), followed by parameters.

Note that as send_fd and recv_fd works only with unix domain socket, it's stdio
must be a socket, not pipe.

* 'T': It has no parameters. It asks the socket creator to terminate.

* 'S' 'U|T' '4|6' port address: Asks it to create a port. First parameter
  tels the socket type (either UDP or TCP). The second one is address family
  (either IPv4 or IPv6). Then there's 2 bytes of the port number, in the
  network byte order. The last one is either 4 or 16 bytes of address, as
  they would be passed to bind (note that both parameters are already prepared,
  like hton called on them).

  The answer to this is either 'S' and then the socket is passed using sendmsg
  if it is successful (it uses our send_fd, you can use recv_fd to read it).
  If it fails, 'E' is returned, followed by either 'S' or 'B' (either socket()
  or bind() call failed). Then there is one int (architecture-dependent length
  and endianess), which is the errno value after the failure.

The creator may also send these messages at any time (but not in the middle
of another message):

* 'F': A fatal error has been detected. It is followed by one byte of error
  condition code and then the creator terminates with non-zero status.

  The conditions are:
  * 'I': Invalid input (eg. someone sent a wrong letter and it does not
    understand it).