User:Jacek Antonelli/Plugin System/Networking

Local Sockets
The viewer should be configured to use local, UNIX sockets only. The reasons for this are:


 * 1) UNIX sockets are fast and efficient (especially on Linux and MacOS X) and quite easy to program for.
 * 2) Restricting connections to localhost limits the opportunity for mischief by remote attackers.

Of course, it's not hard to imagine a scenario where one would want to have a plugin connect over the Internet or LAN. But, that can be better achieved via a "bridge" plugin which accepts incoming remote requests and feeds them to the viewer via local sockets. This provides the opportunity for the plugin to encrypt, compress, and/or validate the networked communications in ways that we could not anticipate when programming the viewer.

Built-in support for remote plugins over TCP/IP is a possible future endeavor. But, the system for arranging a connection with a remote plugin is by its nature quite different from that of local plugins. So, the plugin system can be extended at a later time to support remote plugins, if desired.

Coordinating Sockets
Each instance of the viewer will have its own socket file, so that it can run its own plugins separately. When the viewer starts, it would check for an available socket ; if that's already in use, it would try ,   and so on. Once it finds an available socket path, it starts listening for incoming connections.

Then, when the viewer launches a plugin, it passes the path to the socket as an argument to the plugin. The plugin is then responsible for establishing a connection on that socket. That means a requirement of the plugin script is that it check its arguments and use the provided path. Once connected, the plugin and viewer do some handshaking, and then can send messages back and forth.

Counted Message Length
In order to simplify the process of reading off individual messages from the socket, each message that is sent shall be prefixed with a 4-byte unsigned binary integer in network order specifying the number of message bytes following.

The benefit of this scheme is that the program (either viewer or plugin) can read each message using a simple and efficient process:


 * 1) Read 4 bytes to get the length, N.
 * 2) Read N bytes to get the message body.
 * 3) Repeat to get the next message.

This eliminates both the need to scan for delimiters or psuedo-parse JSON to detect the end of the message, as well as the risk of over- or under-reading bytes (as long as the length is accurate).

Example: if the message was, the message length is 33 bytes. Expressed as a 4-byte binary integer in network order, the number 33 is. So, the full text that would be sent over sockets for this message is:

\0\0\0!["request", "GetProps", "entity"]

Note: The maximum message length that can be represented under this scheme is 232-1 bytes, or approximately 4.29 billion bytes (4 Gigabytes). That should be plenty for any conceivable single message needed to be sent between the viewer and plugin.