slinkServer

Description

slink is "Secure Link" for connecting BNCS networks together over a wide area network.

It is very similar indeed to the FABIAN (but without a bookings engine of FABIAN) but adds support for SSL and 32 bit BNCS devices/indexes.

The server sends commands to BNCS device drivers and receiving responses. This it passes down a TCP to slinkClient.

slinkServer usually works in conjunction with slinkClient but can inter-work with conventional FABIAN.

 | FABIAN | slink
CSI32 | Yes | Yes
DDS CSI | NO | Yes

FABIAN will not work on bncs_csi (DDS CSI) systems as the DDS CSI doesn't pass the custom messages that FabianLink32 uses to control redundancy. slinkClient just uses normal device redundancy and redundancy mastering to control redundancy of a slinkClient pair.

Dependencies

I tried really hard not to put unnecessary dependencies on slink but...

slinkServer requires bncs_csi version 2.0.30 or CSI32 version 1.2.73 or later because CSI32 did not allow direct access to the numeric version of cached revertive data (only a version rendered out of the database names)

slinkServer is Qt5 based application and requires the following DLLs in the path (these are all included in a default BNCS V4.6 install):

  • Qt5Core.dll
  • Qt5Gui.dll
  • Qt5Network.dll
  • Qt5Widgets.dll

and this in the windows\lib\platforms directory (for V4.5), or in a platforms subfolder of the SystemPath specified for V3 in c:\bncs_config.ini:

  • qwindows.dll

If you are using SSL then the following additional DLLs are required (see note below about version-clash issues):

  • libeay32.dll
  • ssleay32.dll

Configuration

There can be more than one slinkServer.exe applications for any one system - so there must be more than one configuration file.

A "profile" can be supplied as a command line parameter. This is used to identify the server and define which config file to use.

The configuration file is very similar to the one used for FABIAN.

Configuration files are held in %CC_ROOT%/%CC_SYSTEM/config/

If no command line parameter is supplied slinkServer uses the configuration file

slinkServer_default.ini

If a profile is supplied as the single command line parameter e.g.:

slinkServer.exe london

then the configuration is taken from

slinkServer_london.ini
[slink]
; Bind address is optional and defines which IP address to listen out for connections on
BindAddress=0.0.0.0
; Domain name is important as this implies the filename to use for SSL certificate (if you use it)
domainname=localhost.bncs.tv
; Server port
; Default port is 46277
Port=46277
; either 0 or 1 - defines whether connections should use SSL or not
SSL=0
SslProtocol=TlsV1_2

; only hosts in this list will be allowed to connect (one IP address per numbered entry)
; Entries can be specific IP addresses or partial address/subnet e.g. 192.168.0.0/24
[whitelist]
Host_1=

; hosts in this list will be blocked (one IP address per numbered entry)
[blacklist]
Host_1=

; Numbered sections (the number itself is irrelevant so long as it's unique)
[User_001]
UserName=A
UserPass=B
ControlPass=C

; Optional (default is zero) server port for this specific user to connect to
; This is a legacy feature for users of FABIAN
UserServerPort=4444

; Both DevWriteAccess and DevReadAccess are of the same format:
;     <device>:<index>
; or
;     <device>:<start>-<end>
DevReadAccess_01=1:1-65535
DevReadAccess_02=2:1-65535
DevWriteAccess_01=1:1-65535
DevWriteAccess_02=2:1-65535

SSL protocol

SSL connection can use TLS or SSL as configured. Values for SslProtocol in the ini file are:

  • SslV3
  • SslV2
  • TlsV1_0
  • TlsV1_1
  • TlsV1_2
  • AnyProtocol
  • TlsV1SslV3
  • TlsV1_0OrLater
  • TlsV1_1OrLater
  • TlsV1_2OrLater

Other command line options

/noPollManagement

This just incoming poll commands out verbatim rather than interpret, check, aggregate and otherwise manage them.

SSL

Think of the SSL as a means of stopping your server working rather than merely keeping it secure and you'll be approaching this with the correct frame of mind.

slinkServer acts much like a web server in that it presents a certificate to the client which is verified and used to encrypt the data. The server certificate is validated by other certificates "Trusted Root CA" that are already installed on your machine as part of the OS.

If you buy an SSL certificate from a commercial vendor you'll already have a top-level certificate on you machine able to verify the certificate the server presents is valid.

You can generate your own certificates but then must either live with SSL errors or install your own "Trusted Root CA". BNCS has one of these ("Trusted Root CA") which may be installed on your OS for zero-cost SSL certificates.

It's also possible to verify the identity of clients by using client verification. This requires valid SSL certificates for both clients and servers and is all part of the initiation of the TCP session. This is not currently implemented for slink but could easily be.

Note: (one found the hard way). slink uses OpenSSL - well used, well tested, widely distributed. However, might also find their way into your path on a Windows machine so you might not be using the version you think you are. I just had TLS1_2 not work (TLS1_0 was ok) because it was using a V1.0.7 version of ssleay.dll included with an Intel utility rather than the v1.2.0 shipped with my V4.x BNCS system.

Installing BNCS root CA

You do not need to do this to make slink work. If you buy or use corporate SSL certificates then follow the instructions for using those. However, if you want to test slink using SSL this is a good (cheap!) way to do it.

Two ways to install:

Run the installer e.g. BNCS_rootCA_Win8.exe
manually copy the server.crt file to your system and install it by hand. When you open the file Windows will ask you what to do with it - just follow the prompts to install as "Trusted Root CA"
A working BNCS root CA should appear like this (type certlm.msc in Start->Run):

BNCS Root CA

Test Certificate

There is a test certificate that you can use to test/evaluate slink. This validates domain name: slinkserver.bncs.tv. You do not need the DNS configured for this to work.

You can do it locally by adding the translation manually into your c:\windows\system32\drivers\etc\hosts file (open the editor as administrator). For example:

Windows Hosts File

Security certificates are not to be found in the usual file-tree of a V4-based system - otherwise both certificate and private key are likely to be copied and distributed widely. Instead they are to be found in %CC_ROOT%\certs

Place the files slinkserver.bncs.tv.crt and slinkserver.bncs.tv.key into this path, then set the slinkServer domain name to slinkserver.bncs.tv in it's configuration file (see above). Note: if you hit "Save as..." then be sure to remove the HTML headers/footers/formating

Poll Management

If a slink or FABIAN client sends a poll command to slinkServer it could just send it verbatim to the network - indeed that's exactly what early versions of slinkServer did (the same as FABIAN).

With multiple clients which will connect near simultaneously when slinkServer starts they may all try and poll the same material. This is a real example from a live system:

19:21:26-54 - [006] IP 197 1 4096 293
19:21:26-54 - [016] IP 197 1 4096 293
19:21:26-54 - [022] IP 197 1 4096 293

This is three slink/fabian clients connecting at the same time, requesting large ranges of the same device (even sent in the same BNCS network packet). The driver will just send the 3 x 4096 responses it's been asked for and the slinkServer or FabianServer would deliver the resulting 12388 revertives to each of the three clients - so for a request of 4096 values, the server suddenly has 36864 revertives to deliver. Wow.

So, from slinkServer 1.0.27, poll commands are interpretted: split and queued and sent in sequence. This ensures that only a single poll command for the same data is sent, that the amount of data requested in one go is regulated and also that poll commands are retried until they get a response.

For the incoming commands noted above (three of the same range from different clients), the following commands are sent on the device network:

IP 197 1 100
    <wait for reply>
IP 197 101 200
    <wait for reply>
IP 197 201 300
    <wait for reply>
IP 197 4000 4096
    <done>

I called this zig-zag polling because if you draw it out as a command-response timeline you get a zig-zag pattern down the page.

In reality this adds latency - a full poll via a slink connection of a single infodriver device using CSI32 takes about 4 seconds, and with bncs_csi about 1 second (on a loopback TCP connection). This sill compares favourably with the throughput of FABIAN which takes 12 seconds to deliver 4096 slots.

It also adds traffic - instead of a single poll command for the entire 4096 range it sends 41. However, there's only one command outstanding at any time. Theory goes that this mechanism is self-regulating to a degree - next command is only sent when the last block has been received.

Benchmark tests

Delivery of 4096 revertives to PuTTY client

FabianServer32 | slinkServer
12 seconds | <0.5 second

Note: for best performance do not run FabianServer32 and slinkServer on the same machine sharing the same devices. The above test running both Fabian and slink together ran at the same (slow) speed.

Delivery of 4096 database names to PuTTY client

FabianServer32 | slinkServer
<0.5 second | <0.5 second

Version History

Version | Date | Notes
1.0.0.1 | 01.02.2016 | development version
1.0.0.2 | 16.02.2016 | correct params for ADC message
1.0.0.3 | ? |
1.0.0.4 | 20.02.2016 | adds readaccess control, increases registration range from 4096 to 4294967296, starts on tidying debug
1.0.0.5 | 21.02.2016 | adds whitelist/blacklist including live editor for same
1.0.0.6 | 22.02.2016 | database checksum (MD5), start on device profile, context menu to throw users out, access management editor done
1.0.0.7 | 23.02.2016 | adds a bit of user-management, tidies the docs a tiny bit, changes the greeting
1.0.0.8 | 18.03.2016 | adds disk log, some more meaningful logging, startup errors now caught, docs improved
1.0.0.9 | 29.03.2016 | Deleting user now forcibly closes any session open with that name
1.0.0.10 | 03.10.2017 | Step one of any job is now fix the things that were working but now aren't 'cause of a toolkit upgrade. https://bugreports.qt.io/browse/QTBUG-58706. Changes the SSL default to off (so that it at least works out of the box). Changes server edit menu option to open the file (rather than do nothing). Notes on dialogs about dynamic/static nature of changes
1.0.0.11 | 20.10.2017 | Crash fix to clear up registrations on client closing
1.0.0.12 | 26.10.2017 | Router modify handling (anti-howlround)
1.0.0.13 | 06.12.2017 | Closes with CSI
1.0.14.0 | 22/12/2017 | Changes significance of version numbers. Adds version history to docs. Working and entirely functional but clumsy "you missed these..." database syncing functions
1.0.15.0 | 03/01/2018 | Less clumsy database syncing functions
1.0.16.0 | 24/04/2018 | Removes extended range support
1.0.17.0 | 10/05/2018 | Lost in the mists of time (in an early development version) FABIAN compatibility was lost by inconsistent line-endings. This version corrects. Also adds missing read/write access settings for GPI and router types. Adds implementation of GSN command
1.0.18.0 | 11/05/2018 | Supports ADP command (limited to first 10 databases for backwards compatibility as the message parsing/IPC can't handle the possible total 65536 databases)
1.0.19.0 | 11/05/2018 | Optimisation of anti-howlround database messages by including msg id in the correct outgoing msgs
1.0.20.0 | 15/05/2018 | sends ADC for any registration not just within the range of the registration
1.0.21.0 | 17/05/2018 | Adds local turn-around of polls if they exist in CSI's cache so as to not bother ALL the other remotely connected clients with one client's polls
1.0.22.0 | 17/05/2018 | Adds permission checking of poll return values to each client
1.0.23.0 | 18/05/2018 | Cache value now can also return numeric value of cache rather than the database name (allows feature in version 1.0.21 to work)
1.0.24.0 | 18/05/2018 | Removes hard-checking of read access when doing polls. You can poll but the access sets whether you get the response
1.0.25.0 | 21/05/2018 | Tidies up debug messages for incoming commands
1.0.26.0 | 22/05/2018 | Zig-zag polling for client connections: infodrivers 100 slots at a time, GRD and GPI 500. Missing feature is aggregating polls from different clients (because it uses a queue not a set)
1.0.27.0 | 22/05/2018 | Zig-zag polling now rejects duplicate polling commands where multiple clients may all connect at once
1.0.28.0 | 23/05/2018 | Allows for port-per-user-login for legacy users of FABIAN
1.0.29.0 | 29/05/2018 | Adds server port to users config, with dynamic adding/removing of users and server ports
1.0.30.0 | 29/05/2018 | minor tarting following code-review
1.0.31.0 | 30/05/2018 | Updated documentation to clarify ini file location and SSL settings
1.0.32.0 | 31/05/2018 | Socket error code just displayed a placeholder,not the value meant for that position. Now also rather less lazy and shows you the text description of this value.
1.0.33.0 | 05/06/2018 | Implemenets un-register (de-register?) commands AIU ARU and AGU. Also now removes "managed" poll commands for devices that are no longer registered
1.0.34.0 | 05/06/2018 | Bit of an edge case, but still a flaw: corrects delivery of poll responses from cache when that client hadn't registered for that range
1.0.35.0 | 07/06/2018 | Changes main window UI layout to a splitter
1.0.36.0 | 07/06/2018 | Adds SSL protocol configuration
1.0.37.0 | 15/06/2018 | Slightly careless < rather than <= when it came to dealing poll ranges. Gist was you couldn't poll a single slot - only ranges
1.0.38.0 | 15/06/2018 | Allows for no poll management command line override
1.0.39.0 | 18/06/2018 | Makes quote aware so that colons may be embedded in strings without tripping the command parser
1.0.40.0 | 19/06/2018 | Mix-minus local-turnaround of RM commands so that all other clients get the RD without bouncing via the network or returning the RM to the originating network
1.0.41.0 | 12/07/2018 | Adds "V3" search path for finding Qt plugins to path defined in c:\bncs_config.ini (or V2 default of Windows)
1.0.42.0 | 12/07/2018 | "data" path in V3 config dir (resources incorrect for this version)
1.0.43.0 | 19/07/2018 | Sets path to log after getting the profile name (otherwise path can't contain that profile name)
1.0.44.0 | 20/07/2018 | Adds check of serverport when adding a user - just to flag invalid values
1.0.45.0 | 28/07/2018 | adds nodelay option for testing (deliberately undocumented at the moment)
Build: master 3798 615debad Atos © 2018


-----BEGIN CERTIFICATE-----
MIIC/zCCAmigAwIBAgIBGjANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMCR0Ix
DzANBgNVBAgMBkxvbmRvbjEPMA0GA1UEBwwGTG9uZG9uMQ0wCwYDVQQKDARCTkNT
MQ0wCwYDVQQLDARCTkNTMRYwFAYDVQQDDA1jZXJ0cy5ibmNzLnR2MRwwGgYJKoZI
hvcNAQkBFg1jZXJ0c0BibmNzLnR2MB4XDTE2MDMyNDE0MDY1N1oXDTIxMDMyMzE0
MDY1N1owgYkxCzAJBgNVBAYTAkdCMQ8wDQYDVQQIDAZMb25kb24xDzANBgNVBAcM
BkxvbmRvbjENMAsGA1UECgwEQk5DUzENMAsGA1UECwwEQk5DUzEcMBoGA1UEAwwT
c2xpbmtzZXJ2ZXIuYm5jcy50djEcMBoGCSqGSIb3DQEJARYNY2VydHNAYm5jcy50
djCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqf2MmteBOsP0Kaikxq5SCjxp
vqJy1Pt3dKOoVhxa+owc0GSJxNujWt1w5WbwGPBXodt1YSlNXdfwVKqYaFlMpR0Z
dal7llUjJL2VJ1yE5XAt/cbs8XOHN3wAUl7wVBeoFrwWMBeG7tUKiJdPMnKH0Whg
qeaEXQxTedYpzKnevQUCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0E
HxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFKjgJa5I
vLFQhxDBse3haNw62bvpMB8GA1UdIwQYMBaAFK2CYERcip67ylVEC84PWzZwTPBM
MA0GCSqGSIb3DQEBBQUAA4GBAIXexOj18M7ym75rD36MDBPVrbkWJ5iAiRT5xDX+
QuZbBBIssTgS1OqLLDuwPjFG89hbz1a3q+LYJRKM3DuhrUmIN+d0RIo3njxHX1Pt
Esw6YihAwyDmMuo4bgsNaw9akQAmXJgWILv62qBXy1dS9vjcWyHjAscYCZ8A7xBm
1vIO
-----END CERTIFICATE-----


-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQCp/Yya14E6w/QpqKTGrlIKPGm+onLU+3d0o6hWHFr6jBzQZInE
26Na3XDlZvAY8Feh23VhKU1d1/BUqphoWUylHRl1qXuWVSMkvZUnXITlcC39xuzx
c4c3fABSXvBUF6gWvBYwF4bu1QqIl08ycofRaGCp5oRdDFN51inMqd69BQIDAQAB
AoGBAKcKkHBX9JVamUOWhNT314ZXd1HtMAo6UVg8ud5kXsJ1jJr7MKZRbmSL1bSX
Qrg+9N4IWX/wpiXhXDjWqo1fsv+yMVwSGu2XRw2ZlD5N8d2TvkI2QdKUcwVaucVM
aZWJvUW0bZpopomUqQdwY6uHmyKxGgsvOzOOdvHZuYhB377BAkEA4WkyMlxvwA75
lFYGVcuHn84GlvgcuIsiV7Z59izG+MxeSjBm2u7407mw26YDUiVJhr9WBvi1hACr
Bt64Ha++jwJBAMEPCcObjvH7yhnpO/wqV59KUSq5lPnNO3B82rzqFiux30ydB4rS
JfsCPtvc+QUCYvF67S6T+asiyWafN+3IFSsCQQCSJwAqES9QCyWeHWz8IfxtDEvP
hU4yBdydnK5VhND6LqCQX/PAzqO9vC/FK04J7C1RViw0Vvxye3BpAu3EKdhXAkEA
jA1TwQJ9fZByeb+YU4OIEzd/kGYW6+z1vNHmgPu0X7hmzJZyHUP8Z46meSthvz+O
9a1+mLaifYL75iWFFkt7BwJAEJRwsC5jJcV8cRl0hxyWq+czZTwvskpf4X0zy3JH
9azBlXdMRxk9yvHVp9tgDiRu6eiO0yHc/H65MYMAw1O91g==
-----END RSA PRIVATE KEY-----