9P and VOIP
Plan9’s filesystem protocol is interesting. What would it look like to implement VOIP on top of it? A first draft.
A quick summary
The man-page does a better job of providing a technical description of 9P, but I’ll give a low-tech explanation for completeness.
9P is: - A protocol used by clients and servers to expose and make use of a filesystem hierarchy on a remote machine. - In the simplest case, it allows a client to navigate a filesystem on a remote host. - For example, WSL2 (Linux-on-Windows) has each Linux subsystem start a 9P server to expose the Linux filesystem. - The filesystem hierarchy exposed may be /virtual/. As in a server responding to a read request with generated data. - For example, the server may construct a filesystem-structure representating known-paths of a website. When clients read a ‘file’ in that path, the data returned comes not from a file, but from a process (i.e. python, nodejs, ruby).
Modelling VOIP as a filesystem (draft 1)
I have some interest in how VOIP could be implemented with 9P. SIP isn’t hierarchical, so representing calls in a hierarchy isn’t immediately obvious. The properties of a tree-structure representing a typical commercial VOIP service (with UACs, calls, and perhaps call recordings), would (I think) look a little like this:
voip
|_<account>
|_cdr
| |_2025_01_01
| |_1735689600_1000123456_033443443434.cdr
|_call_recordings
| |_2025_01_01
| |_1735689600_1000123456_0787878787.opus
|_<extension>
|_credential
|_ongoing
| |_1000123456_0787878787
| |_metadata
| |_hep.sock
| |_rtp_src.sock
| |_rtp_dest.sock
|_uacs
|_<registration_a>
|_sip.sock
|_<registration_b>
|_sip.sock
A few notes on this:
This directory structure would be managed by a SIP/RTP-aware 9P-implementing server.
The directories <account> and <extension>, alongside the file credentials would be created by the admin. Clients would be matched to their account and extenion by SIP registration against <account>/<extension>/credentials. Access to paths above extension would be disallowed.
Registrations would persist for the lifetime of the sockets in <account>/<extension>/uacs/<registration>/sip.sock
Calls would be a child of extension, but CDRs and and call recordings would be a child of account. This is based on the presumption businesses do not want their staff accessing account-wide cdrs, recordings, or sockets.
This does pose problems for BLF, as clients can’t fetch a list of on-call extensions on their account. At least insofar as implementing BLF in a filesystem-oriented way.
It also restricts an extensions access to its own recordings.
NAT, as always, is a problem. SIP is fine, as I’m tying registrations to their sockets. RTP is (generally speaking) not. The rtp_src.sock above would be created using SDP from the client, and is certainly wrong. Symmetric RTP helps, as does STUN. But creates more work in the server implentation.