This document describes the internal control protocol between the meta server and the actual ACAP server. It's only spoken across a socketpair, thus security wasn't any kind of concern, and extensibility was not a goal.
The protocol is line orientated, and violently simplistic. It's very easy to abuse.
Every message begins with a single octet command name, and a space. The rest of the line depends on what the command name was, and I'll call the the payload:
line = command SP payload LF
command = %x00-FF
text-char = ; Pretty much any printable ASCII character.
num-char = "0"-"9"
Some commands will be sent expecting a nearly instant response - where this is the case, the real ACAP server thread that sent the command will be blocking. In general, this'll be the Master-helper thread, so during the CP call, sockets won't get closed. Worst case - where the metaserver fails to provide a return code - is that the real server doesn't close connections.
In practise, a command is always an upper-case character. Commands currently include:
Log
log-payload = log-pri SP *( text-char )
log-pri = num-char
Logs via whatever logging mechanism we have, at this priority. This really means syslog, or would if I got around to it.
Fatal Error
fatal-payload = *( text-char )
Also logs, but also exits the metaserver when the child process quits. This is used for unrecoverable errors - such as when the ACAP server cannot actually start up properly - where a restart won't work. Think of it as a warning that the child's about to crash.
Socket Request
socket-payload = family SP family-specific
family = 1*(num-char)
; Denote the address family. Note that the type we want is always SOCK_STREAM.
family-specific = ipv6-addrinfo / ipv4-addrinfo / unix-addrinfo
unix-addrinfo = "unix" SP 1*( text-char )
ipv4-addrinfo = "ipv4" SP ipv4-addr SP tcp-port
ipv6-addrinfo = "ipv6" SP ipv6-addr SP tcp-port
ipv4-addr = 1*3( num-char ) "." 1*3( num-char ) "." 1*3( num-char ) "." 1*3( num-char )
; ipv4 dotted-quad notation address, possibly "0.0.0.0" for INADDR_ANY
tcp-port = 1*5( num-char ) "/" tcp
; TCP port address.
ipv6-addr = 1*( num-char / ":" )
; dead::beef notation IPv6 address.
Requests the metaserver to listen to this IP address, and pass the socket back to the caller via an Ancillary Message of type SCM_RIGHTS. Remember that the real ACAP server runs as a non-priveleged user, and thus cannot do this for itself. It also has the benefit that on restart, the metaserver simply hands across existing listening sockets.
Right now, incidentally, only ipv4 works.