Ouroboros Tutorial 03

From Ouroboros
Jump to navigation Jump to search
Ouroboros Tutorial 03

Ouroboros can be configured using a configuration file in TOML format. This requires tomlc17 to be installed when building the prototype.

This tutorial sets up the same 2-node unicast Layer as Tutorial 02, but instead of using the CLI, we use a configuration file. It demonstrates the automatic start of server programs, and uses the system log for logging.[1]

Security configuration

The IPCPs and the oping client allocate flows to the names unicast-layer, uni-1 and oping-server. As explained in Tutorial 02, the clients need a security configuration for these names. If you did not follow Tutorial 02, create them now:

$ for n in unicast-layer uni-1 oping-server; do
>   sudo mkdir -p /etc/ouroboros/security/client/$n
>   printf 'auth=optional\nencryption=none\n' | sudo tee /etc/ouroboros/security/client/$n/sec.conf > /dev/null
> done

The configuration file

Copy/paste the text below and store it as a file. We named it tut03.conf and saved it in /etc/ouroboros/, next to the example configuration files that are installed there.

###  Ouroboros configuration file Tutorial 03
[name.oping-server]
prog=["/usr/bin/oping"]
args=["--listen"]

[unicast.uni-1]
bootstrap="unicast-layer"
autobind=true
reg=["oping-server"]

[unicast.uni-2]
enrol="unicast-layer"
autobind=true
conn=["uni-1"]

It has 3 stanzas:

  1. name.oping-server: This creates a service name, in this case the name is oping-server. Note that if we wanted to name the service oping.server it would need quotes like this: [name."oping.server"]. That name will be served by all instances of the oping binary (located at /usr/bin/oping). We specify the args option to start oping automatically (see below).
  2. unicast.uni-1: The IRMd will start a unicast IPCP called uni-1. It will bootstrap a new Layer called unicast-layer. The autobind option will bind it to both the IPCP name (uni-1) and the Layer name (unicast-layer). We register the oping-server name with this IPCP.
  3. unicast.uni-2: The IRMd will start a unicast IPCP called uni-2. This IPCP will not bootstrap, but enroll in the unicast-layer, bind to its names, and then connect to uni-1, creating both the management and the data transfer flow.

The IRMd processes the stanzas in the order they appear in the file. The example configuration file /etc/ouroboros/irmd.conf.example lists all options.

The configuration file of this tutorial and what the IRMd does with each stanza.

Starting the IRMd

Instead of logging to standard output, we will use the system log, which is Ouroboros' default. Use your preferred way to view the system log. We use journalctl, and follow the log messages of the IRMd and the unicast IPCPs:

$ sudo journalctl --identifier=irmd --identifier=ipcpd-unicast --follow        #short form: sudo journalctl -t irmd -t ipcpd-unicast -f

In a different window, start the IRMd with the configuration file, without the --stdout option. The IRMd only reads a configuration file that is passed with the --config option:

$ sudo irmd --config /etc/ouroboros/tut03.conf

This will load the configuration and set up the same network that we created in the second tutorial. The system log shows the IRMd working through the configuration file (we left out the debug messages of the flow allocations, which are explained in the previous tutorials):

Sep 26 14:02:23 o7s irmd[6556]: Loaded certificates from /etc/ouroboros/security/cacert.
Sep 26 14:02:23 o7s irmd[6556]: Loaded certificates from /etc/ouroboros/security/untrusted.
Sep 26 14:02:23 o7s irmd[6556]: Ouroboros IPC Resource Manager daemon started...
Sep 26 14:02:23 o7s irmd[6556]: Reading configuration from file /etc/ouroboros/tut03.conf
Sep 26 14:02:23 o7s irmd[6556]: Found service name oping-server in configuration file.
Sep 26 14:02:23 o7s irmd[6556]: Created new name: oping-server.
Sep 26 14:02:23 o7s irmd[6556]: Bound program /usr/bin/oping to name oping-server.
Sep 26 14:02:23 o7s irmd[6556]: Found IPCP uni-1 in configuration file.
Sep 26 14:02:23 o7s irmd[6556]: Instantiated /usr/sbin/ipcpd-unicast as process 6561.
Sep 26 14:02:23 o7s irmd[6556]: Process added: 6561 (ipcpd-unicast).
Sep 26 14:02:23 o7s irmd[6556]: Created IPCP 6561.
Sep 26 14:02:23 o7s irmd[6556]: Using DHT directory policy.
Sep 26 14:02:23 o7s irmd[6556]: Using Link State routing policy.
Sep 26 14:02:23 o7s irmd[6556]: Bootstrapped IPCP 6561.
Sep 26 14:02:23 o7s irmd[6556]: Created new name: uni-1.
Sep 26 14:02:23 o7s irmd[6556]: Bound process 6561 to name uni-1.
Sep 26 14:02:23 o7s irmd[6556]: Created new name: unicast-layer.
Sep 26 14:02:23 o7s irmd[6556]: Bound process 6561 to name unicast-layer.
Sep 26 14:02:23 o7s irmd[6556]: Name oping-server already exists.
Sep 26 14:02:23 o7s irmd[6556]: Registered oping-server with IPCP 6561 as f6c93ff2.
Sep 26 14:02:23 o7s irmd[6556]: Found IPCP uni-2 in configuration file.
Sep 26 14:02:23 o7s irmd[6556]: Instantiated /usr/sbin/ipcpd-unicast as process 6618.
Sep 26 14:02:23 o7s irmd[6556]: Process added: 6618 (ipcpd-unicast).
Sep 26 14:02:23 o7s irmd[6556]: Created IPCP 6618.
Sep 26 14:02:23 o7s irmd[6556]: Enrolled IPCP 6618 in layer unicast-layer.
Sep 26 14:02:23 o7s irmd[6556]: Created new name: uni-2.
Sep 26 14:02:23 o7s irmd[6556]: Bound process 6618 to name uni-2.
Sep 26 14:02:23 o7s irmd[6556]: Bound process 6618 to name unicast-layer.
Sep 26 14:02:23 o7s irmd[6556]: Established Management connection between IPCP 6618 and uni-1.
Sep 26 14:02:23 o7s irmd[6556]: Established Data Transfer connection between IPCP 6618 and uni-1.

Automatically starting the server

Now, we will ping an oping server from the client over the unicast Layer. In the previous two tutorials, we first started the server, but O7s can start a server automatically. This is the auto feature of the irm bind program CLI tool. In the configuration file, this feature is enabled by specifying an args line for a service name. In our configuration, we defined that the service name oping-server is bound to program /usr/bin/oping and can be started automatically with the argument --listen (the short form is -l).

Just start a client towards oping-server:

$ oping -n oping-server -c 10
Pinging oping-server with 64 bytes of data (10 packets):

64 bytes from oping-server: seq=0 time=0.440 ms
64 bytes from oping-server: seq=1 time=0.336 ms
64 bytes from oping-server: seq=2 time=0.497 ms
64 bytes from oping-server: seq=3 time=0.542 ms
64 bytes from oping-server: seq=4 time=0.462 ms
64 bytes from oping-server: seq=5 time=0.369 ms
64 bytes from oping-server: seq=6 time=0.728 ms
64 bytes from oping-server: seq=7 time=0.607 ms
64 bytes from oping-server: seq=8 time=0.622 ms
64 bytes from oping-server: seq=9 time=0.538 ms

--- oping-server ping statistics ---
10 packets transmitted, 10 received, 0 out-of-order, 0% packet loss, time: 10001.739 ms
rtt min/avg/max/mdev = 0.336/0.514/0.728/0.120 ms

The window where we started the IRMd shows the output of the server:

Ouroboros ping server started.
New flow 64.
Received 64 bytes on fd 64.
Received 64 bytes on fd 64.
Received 64 bytes on fd 64.
Received 64 bytes on fd 64.
Received 64 bytes on fd 64.
Received 64 bytes on fd 64.
Received 64 bytes on fd 64.
Received 64 bytes on fd 64.
Received 64 bytes on fd 64.
Received 64 bytes on fd 64.
Flow 64 timed out.

The system log shows how the IRMd started the server:

Sep 26 14:02:31 o7s irmd[6556]: Created PUP for uid 967 gid 966.
Sep 26 14:02:31 o7s irmd[6556]: Process added: 6678 (oping).
Sep 26 14:02:31 o7s irmd[6556]: Allocating flow for 6678 to oping-server (uid 967).
Sep 26 14:02:32 o7s irmd[6556]: Instantiated /usr/bin/oping as process 6689.
Sep 26 14:02:32 o7s irmd[6556]: Starting /usr/bin/oping for oping-server.
Sep 26 14:02:32 o7s irmd[6556]: Process added: 6689 (oping).
Sep 26 14:02:32 o7s irmd[6556]: Process 6689 accepting flows for oping-server.
Sep 26 14:02:32 o7s irmd[6556]: UID mismatch, falling back.
Sep 26 14:02:32 o7s ipcpd-unicast[6618]: K<f6c93ff23bd91094> No local values.
Sep 26 14:02:32 o7s ipcpd-unicast[6561]: K<f6c93ff23bd91094> Responding with 1 contacts, 1 values.
Sep 26 14:02:32 o7s ipcpd-unicast[6618]: K<f6c93ff23bd91094> 1 new values received.
Sep 26 14:02:32 o7s ipcpd-unicast[6618]: Allocating flow 6 for 6678 to f6c93ff2.
Sep 26 14:02:32 o7s ipcpd-unicast[6618]: K<f6c93ff23bd91094> No local values.
Sep 26 14:02:32 o7s ipcpd-unicast[6618]: Finished allocating flow 6 to f6c93ff2.
Sep 26 14:02:32 o7s irmd[6556]: Flow req arrived from IPCP 6561 for f6c93ff2.
Sep 26 14:02:32 o7s irmd[6556]: Flow request arrived for oping-server.
Sep 26 14:02:32 o7s irmd[6556]: IPCP 6689 accepting flow 5 for oping-server.
Sep 26 14:02:32 o7s ipcpd-unicast[6561]: Responding 0 to alloc on flow_id 5.
Sep 26 14:02:32 o7s ipcpd-unicast[6561]: Finished responding 0 to allocation request.
Sep 26 14:02:32 o7s ipcpd-unicast[6618]: IPCP received msg response 0 for flow on fd 66.
Sep 26 14:02:32 o7s irmd[6556]: Flow 5 accepted by 6689 for oping-server (uid 0).
Starting the server on demand. The IRMd starts oping when the flow request finds no process for oping-server, and the flow then goes over the Layer as in Tutorial 02.

When the flow allocation request arrives, there is no process that accepts flows for oping-server. The IRMd waits a second, and then starts /usr/bin/oping with the --listen argument. The new process inherits the name oping-server from the program. The server was started by the IRMd, so it runs as the superuser, while our client runs as a regular user. They do not share a packet pool, so the IRMd uses the unicast Layer: uni-2 looks up oping-server in the DHT, gets the address of uni-1 from it, and allocates the flow to uni-1, which hands it to the new server.

The server keeps running after the flow times out, so the next client will not have to wait for it to start.

Notes

  1. ↑ As in the previous tutorials, this tutorial assumes you run the oping client as a regular user, not as root or as a member of the ouroboros group.