Specification of communication between programs being concurrently sandboxed by Spawner.
The key words MUST
, MUST NOT
, REQUIRED
, SHALL
, SHALL NOT
, SHOULD
,
SHOULD NOT
, RECOMMENDED
, MAY
, and OPTIONAL
in this document are to be
interpreted as described in RFC 2119.
An implementation is not compliant if it fails to satisfy one or more of the
MUST or REQUIRED level requirements for the protocols it implements. An
implementation that satisfies all the MUST or REQUIRED level and all the SHOULD
level requirements for its protocols is said to be unconditionally compliant
;
one that satisfies all the MUST level requirements but not all the SHOULD level
requirements for its protocols is said to be conditionally compliant.
Spawner is a program for (possibly) concurrent sandboxing of arbitrary applications.
Controller is a spawner-sandboxed program. Controller is aware of each normal existence and able to affect their regulation by spawner. There MUST be only one controller program.
Normal is a spawner-sandboxed program. Normal is only aware of controller. There MAY be many normal programs.
Message is an atomic unit of communication between normal and controller or spawner and controller.
Control mode is a spawner mode being activated when there is program marked as controller.
Both normal and controller are run with spawner. In a single spawner invocation with controller and normal being passed via command line arguments.
- The controller MUST be marked with
--controller
flag. - The controller MUST be the only one.
- The presence of controller MUST trigger spawner into control mode.
- Rest of the requirements MUST only be applied in control mode.
- The number of normals MUST be passed as a first command line argument to controller.
- Each normal's stdin MUST be connected with controller's stdout with
--in=*0.stdout
. - Each normal's stdout MUST be connected with controller's stdin with
--out=*0.stdout
Sample command line:
sp.exe --json -sr=report.json -hr=1 --separator=//
--// --controller --out=std controller.exe 3
--// --out=std --in=*0.stdout --out=*0.stdin normal-1.exe
--// --out=std --in=*0.stdout --out=*0.stdin normal-2.exe
--// --out=std --in=*0.stdout --out=*0.stdin normal-3.exe
-
all normal programs MUST start in suspended mode.
-
spawner MUST resume normal in response to wait request from controller to wait for normal with given index.
-
spawner MUST put awaited normal process into suspended state after it responded with a message.
-
controller MAY send a message to specified normal
-
controller MAY send a message to the spawner, informing it about waiting for specific or any normal to send message to controller
-
normal MAY send a message to the controller
-
controller MAY ask spawner to stop specified normal process
-
controller's deadline MUST be reset after each message sent by controller
-
normal's deadline MUST be set if it's being awaited by controller
-
normal's deadline MUST be reset if normal sends a message
TODO: add examples
In general messages have a form : <header><body>\n
. <body>
MAY contain any character but \n
and \r
. <header>
MUST always end with #
symbol. #
MAY be preceded by a letter which MAY be preceded by integer. e.g. 5S#Hello, world!\n
.
- Controller and __normal__s MUST send messages via
stdout
stdout
MUST be flushed after sending a message. e.g.fflush(stdout);
in C++.- Messages MUST be separated by newline (
\n
). e.g.
This MUST produce two messages First message\n
and Second message\n
(note included \n
s):
printf("First message\nSecond message\n");
fflush(stdout);
while this MUST produce one message (\n
):
printf("\n");
fflush(stdout);
and this one will produces no message since there is no newline present:
printf("foo");
fflush(stdout);
while this will produce undefined behavior since stdout is not being flushed:
printf("foo\n");
Controller MAY post two kinds of a message:
Controller MUST prefix message text with a number followed by #
if intention is to send a message to normal. This number stands for normal index. Normals are indexed from 1 to n where n is total number of __normal__s in order they're passed to spawner via command line arguments.
Considering this command line:
sp.exe --separator=//
--// --controller controller.exe 3
--// --in=*0.stdout --out=*0.stdin normal-1.exe
--// --in=*0.stdout --out=*0.stdin normal-2.exe
--// --in=*0.stdout --out=*0.stdin normal-3.exe
In order to send a message Foo
to application normal-1.exe
controller must:
printf("1#Foo\n");
fflush(stdout);
If controller specifies an invalid index then spawner MUST send the following error message to the controller: <i>I#\n
where <i>
is an index of invalid normal.
Controller MAY specify if it awaits a response from that normal or any normal. Time limit MUST NOT be issued against a normal which response is not awaited for.
To specify waiting for arbitrary normal: <i>W#\n
.
To specify waiting for any normal: W#\n
(not implemented yet)
Controller MAY ask spawner to stop executing specified normal with:
<i>S
spawner MUST shut down the normal with index<i>
Spawner MUST not reply to this message if <i>
is invalid.
e.g.
printf('4S#\n');
fflush(stdout);
Messages sent to 0 index are considered being sent to spawner an OPTIONAL letter may clarify the message. This case is reserved for further versions of protocol.
Spawner MUST prefix each normal message with normal index followed by #
symbol e.g.
// let this normal's index be 3
printf("12 45 56 65\n");
fflush(stdout);
// controller will get "3#12 45 56 65\n"