ThingWorx Edge C SDK > Running the C SDK > Initializing the Tunnel Manager (Optional)
Initializing the Tunnel Manager (Optional)
If using the tunneling capability of the C SDK you must create #define ENABLE_TUNNELING. A tunnel manager singleton is automatically created for you when you initialize the API. If you wish to disable tunneling for any reason you may call twTunnelManager_Delete(). The tunnel manager may be started up again by calling twTunnelManager_Create(). Once the tunnel manager is running you may register any callback functions. Passing a NULL for the id parameter when registering a callback will result in callbacks for all tunnel events.
/* Register the tunnel callback function */
twTunnelManager_RegisterTunnelCallback(tunnelCallbackFunc, NULL, NULL);
When new tunnels are requested by the server, the tunnel manager creates a new tunnel. These tunnels establish an independent websocket back to the server. By default these websockets connect back to the same host/port that the API’s websocket uses as well as the same TLS certificate validation criteria. You can override these defaults by using the built-in tunnel manager functions as found in the file, twTunnelManager.h:
int twTunnelManager_UpdateTunnelServerInfo(char * host,
uint16_t port, appKeyCallback);
void twTunnelManager_SetProxyInfo(char * proxyHost, uint16_t proxyPort,
char * proxyUser, twPasswdCallbackFunction proxyPassCallback);
void twTunnelManager_SetSelfSignedOk(char state);
void twTunnelManager_EnableFipsMode(char state);
void twTunnelManager_DisableCertValidation(char state);
void twTunnelManager_DisableEncryption(char state);
void twTunnelManager_SetX509Fields(char * subject_cn, char * subject_o,
char * subject_ou, char * issuer_cn,
char * issuer_o, char * issuer_ou);
void twTunnelManager_LoadCACert(const char *file, int type);
void twTunnelManager_LoadClientCert(char *file);
void twTunnelManager_SetClientKey(const char *file, char * passphrase, int type);
Notice that output of two callback functions is used by the TunnelManager for security:
The twTunnelManager_UpdateTunnelServerInfo() function uses the output of the appKeyCallback() function, which is represented as appKeyCallback.
The twTunnelManager_setProxyInfo() function uses the output of the twPasswdCallbackFunction, which is represented here by proxyPassCallback.
This change is present in v.2.2.0 and later versions of the C SDK. For details about the appKeyCallback function, see the explanation below the first example code listing in "Initializing the API Singleton". The password callback is explained in the section, Passwords (C SDK 2.2.0 and later).
Is the Built-in Tasker Function Used?
If you are using the built-in tasker, continue to the next section. However, if you are not using the built-in tasker, you must call the function twTunnelManager_TaskerFunction on a very frequent basis (the examples default to 5 ms). The setting to use here is highly dependent on use case and environment. Before using this function, read the section, . twTunnelManager_TaskerFunction and Tick Resolution.
Connection Information for the Tunnel Manager
By default the twTunnelManager uses the same twConnectionInfo structure as twApi so that all twConnectionInfo settings should be shared by twApi and twTunnelManager. However, if twTunnelManager_EnableFipsMode is called, a new twConnectionInfo structure is allocated for the twTunnelManager, assigned the current values of the twConnectionInfo structure of twApi, and then updated by this function. Therefore, after this function is called, any ::twConnectionInfo settings applied to the ::twApi are not reflected in the ::twTunnelManager's connection structure.
twTunnelManager_TaskerFunction and Tick Resolution
Tunnel performance can be greatly affected by the thread’s tick_resolution of the twTunnelManager_TaskerFunction. When the tunnel manager thread is being created, the tick resolution determines how fast a tunnel manager checks the status of its managed tunnels. The smaller this value, the faster the tunnel responds. Tick resolution is especially important when running multiple tunnels concurrently, but be aware that a smaller tick resolution consumes more CPU resources. For an example, see the example application called “SteamSensorWithThreads.” See also Running the C SDK on Windows-based Operating Systems
Tunneling and Proxy Servers
When using a proxy server, you must set both the initial proxy with twApi_SetProxyInfo AND the proxy for tunneling with twTunnelManager_SetProxyInfo. Otherwise, the tunneling will fail. To set up the initial proxy, see Proxy Server Authentication.
Use the following function to set up communication through a proxy server for tunneling:
twTunnelManager_SetProxyInfo(char * proxyHost, uint16_t proxyPort,
char * proxyUser, twPasswdCallbackFunction proxyPassCallback);
The following table lists and describes the parameters you can specify:
The IP address or host name of the proxy server to use for tunneling. .
The number of the port on the proxy server to use.
If the proxy server requires Basic or Digest authentication, you need to use the callback function, twPassword
For a password, you must provide a password callback function so the ThingWorx SDK can obtain a copy of the tunnel password from your application.
See the next section for more information about passwords.
Passwords (C SDK 2.2.0 and later)
As of v.2.2.0 of the C SDK, password protection is your responsibility. For the C SDK to use a password, you need to develop a way for the password to be provided to the following callback function:
typedef void (*twPasswdCallbackFunction)(char * passwdBuffer, unsigned int maxPasswdSize);
As a result, the twTunnelManager_SetProxyInfo function no longer takes password variable. Instead, starting with v.2.2.0 of the C SDK, it uses the output of twPasswdCallbackFunction. This callback function is called whenever the C SDK requires the current password for a proxy server user or a digest to authenticate with the ThingWorx platform.
In production, this callback should obtain a password or digest from a secure source.
Tunnel Manager and OpenSSL
When the tunnel manager is initialized, it points its {{tm->info}} struct at {{tw_api->connectionInfo}}, so that any API settings are realized in the tunnel manager. However, if you call any functions that set tunnel manager settings (such as {{twTunnelManager_DisableCertValidation()}} or {{twTunnelManager_EnableFipsMode()}}), then the C SDK will actually create a new struct to set the tunnel manager specific settings and any subsequent calls to set API connection information (like loading a cert) will no longer be realized in the tunnel manager. See also the API documentation for the C SDK.