Network Setup

devel. one** is delivered with a network plug-in. The plug-in connects D1 instances (NODES) to a peer-to-peer network. The individual NODES are connected by TCP. Messages move through the links from NODE to NODE. If there are enough links between the NODES, a redundant Mesh network is created.

The data for creating the links is read from the configuration.

Links can of course also be started and stopped via services. Usually, however, all links are created at the startup and remain open all the time.

Start TCP Server Socket Automatically

Links are created by a combination of TCP server and client. The automatic start of a server can be achieved by an entry in the Configuration. Just specify the port to be opened for the server:

<record path="plugin/D1Tcp/autostart/Node002">
    <recordentry key="Port" value="20002" />
</record>

The path used for the server entry in the configuration must always start with “plugin/D1Tcp/autostart/”. The sub-path (here “Node002”) can be freely selected (e. g.”Server1”,”Server22000” or similar). All settings for this server must be in this path.

Start TCP Client Socket Automatically

The automatic start of a client can be achieved by an entry in the Configuration. All you need to do is to make entries in the configuration:

<record path="plugin/D1Tcp/autoconnect/Node004">
    <recordentry key="Port" value="20004" />
    <recordentry key="TcpAddress" value="localhost" />
</record>

Clients must have at least two entries (TCP address and port). There is no default port.

The path used for the client entry in the configuration must always begin with “plugin/D1Tcp/autoconnect/”. The sub-path (here “Node004”) can be freely selected (e. g.”Client1”,”ClientToNode004” or similar). All settings for this client must be in this path.

Using SSL/TLS

For both ends of the link (client and server) the use of SSL/TLS can be enabled in the configuration.

For the server:

<record path="plugin/D1Tcp/autostart/Node002">
    <recordentry key="Port" value="20002" />
    <recordentry key="UseSsl" value="false" />
</record>

For the client:

<record path="plugin/D1Tcp/autoconnect/Node004">
    <recordentry key="Port" value="20004" />
    <recordentry key="TcpAddress" value="localhost" />
    <recordentry key="UseSsl" value="false" />
</record>

But this is not enough, because you need a TrustStore with the keys. This is passed by system property, as well as the password for the truststore:

-Djavax.net.ssl.trustStore=m:\run2\common\testkeystore.ks
-Djavax.net.ssl.trustStorePassword=test01

The above variant can be specified in Eclipse in the run/debug configuration:

../_images/EclipseRunConfiguration1.PNG

When starting a NODES via command line, it is also used as follows:

java -cp ../lib/* -Dlogback.configurationFile=logback.xml -Djavax.net.ssl.trustStore=..\common\testkeystore.ks -Djavax.net.ssl.trustStorePassword=test01 de.softdevel.d1.kernel.impl.CKernel kernel/ConfigDir=./ kernel/PluginDir=../plugins/

Automatic Reconnect of the Client

In order for a client to periodically attempt to connect to a server, it is sufficient to make an entry in the configuration:

<record path="plugin/D1Tcp/autoconnect/Node004">
    <recordentry key="Port" value="20004" />
    <recordentry key="TcpAddress" value="localhost" />
    <recordentry key="UseSsl" value="false" />
    <recordentry key="Retry" value="5000" />
</record>

The value for the time interval is specified in milliseconds. In the example, the client will try to connect to the server every 5 seconds.

When using reconnect timers, the order of starting servers and clients in the network is not important. The NODES will connect themselves. Individual NODES can also be shut down and restarted.

../_images/Sequenz-Monitor1.PNG

Messages on the way to the other NODE

To get to another NODE via a link, the message must be packed. This is done automatically by the framework. To do this, the message is first of all transferred via a stream into a byte array. However, this is only the beginning. For certain messages, it is worthwhile to use compression that further reduces the size of the byte array. Additional encryption may also be required if certain NODES are not trustworthy on the way.

We have implemented the concept of Package Builder Sequence. Each method of transforming the package is marked with a letter.

At the moment there are

  • M = stream a Message (mandatory)
  • Z = Compressing a packet with the ZIP algorithm
  • A = encrypt with AES

The header of the package contains the applied sequence, e. g.”MZA” for all three builder types. When unpacking, the Builder is called up in reverse order.

../_images/PackageBuilderSequence500x139.png

The sequence does not apply to a link, but to a NODE-to-NODE connection, so even if the NODES are far away from each other. And: The sequence belongs to only one direction, e. g. for the route NODE001 –> NODE008. A different sequence can apply to the opposite direction.

You can set the Package Builder Sequence in various ways:

  • You can set a sequence in the envelope of a message. This sequence has the highest priority.

  • If the sequence is missing in the envelope, the preferred NODE-to-NODE sequence is used. In the configuration the sequence is under:

    plugin/network/hosts/{NODEID}/MyPacketBuilderSequence
    

    wherein NODEID is the remote NODE ID.

  • If the NODE-to-NODE sequence is missing, the sequence of the entire host is used. It is entered in the configuration as follows:

    <entry path="plugin/network" key="PacketBuilderSequence" force="True">
        <description>
            The PacketBuilderSequence is the sequence of packing messages, before they will be sent to another host.
            'M' means 'Message' and is mandatory.
            'Z' means 'Zip': ZIP compression is used if the compressed packet is smaller then the uncompressed packet.
            'A' means 'AES': AES encryption is used after compression.
            The default PacketBuilderSequence is 'MZA'.
        </description>
        <value>MZA</value>
    </entry>
    
  • If this entry is missing,”M” is assumed and neither compression nor encryption is used.

../_images/HopHopHop400x294.png

The symmetrical host-to-host encryption is not to be confused with the use of SSL/TLS for a link between two local hosts. It applies to the internal encryption of a message between sender and receiver NODE, e. g. between “A” and “D” in the diagram above.

How does the sender NODE find out how the receiver NODE would like to have it? And how is it encrypted if the TLS layer is not used?

Now, before the first message is sent from e. g. A to D, A must ask the host D for its preferences. This happens (of course!) by a message (CRecordGetNodeRecord). If this has not yet been done for the first message to be sent, the current message is reset for a moment and the message CRecordGetNodeRecord is sent. A public key of an RSA key of A is given, with which D then encrypts a symmetrical session key. In addition, various other data is also included, such as name, vendor, package builder sequence (!), license key etc. Thus, A now learns everything he needs to communicate with D. Reverse (D–>A) it works the same way. This means that two different session keys (in there and back) are agreed between each NODE pair. This happens only at the beginning of a session (and again after a certain time has elapsed), and is so fast that you won’t notice it.

There’s a catch: If one of the hosts involved is shut down and rebooted, the session keys become invalid. Since the host host doesn’t necessarily notice that one host was briefly down, Host D receives a message from Host A that is still encrypted with the old session key. This message is lost. After all, the circumstance is used and NODE A is prompted to request a new NodeRecord.

Prioritizing Messages

The priority that can be entered in the envelope of a message is only valid on the routes between the NODES. If a message is to be forwarded from a NODE to a neighboring NODE, it first enters a queue with the same priority. The network plugin always takes the next message to be transported from the highest queue (if it does not contain anything, the next-highest queue is emptied, and so on). This way, slow messages (e. g. LOG messages) cannot slow down the important ones. The goal is a dynamic system.

Incidentally, answers are always given the highest priority.