Speedify SDK for Desktop/Embedded 17.0.4
Loading...
Searching...
No Matches
Getting Started: Daemon, Login & Connect

Basic Usage shows the smallest possible call. This page covers the full runtime model you need for a real application: running the daemon, connecting to it, logging in, connecting the VPN, and how state, callbacks, and statistics actually flow.

Running the Speedify daemon

The SDK library (libbondingsdk) is a thin client. All VPN work happens in the speedify daemon — a separate process that you run yourself (or launch from your app). The library just talks to it over a local websocket (default 127.0.0.1:9330).

The daemon must run with elevated privileges: it creates the VPN tunnel device and configures system routing/firewall rules.

  • Linux / macOS: run it as root (e.g. via sudo).
  • Windows: run speedify.exe as an administrator process or install it as a service.

Without privileges the daemon may still answer state/login calls, but SpeedifySDK_ConnectAuto and the other connect calls will fail.

Launch it with at least a port, a resources path, and a data path (Linux also takes a keys path). The -r resources path must point at the resources/ folder shipped with the SDK — it contains cacert.pem, which the daemon needs to reach Speedify's servers. See Daemon Arguments for the full list.

# Linux example
sudo ./speedify -p 9330 -r ./resources -d ~/.speedify -k ~/.speedify/keys &

Connecting the SDK to the daemon

Create the client with the same port the daemon is listening on:

SpeedifySDK_CreateSettings settings;
SpeedifySDK_InitializeCreateSettings(&settings);
snprintf(settings.name, SPEEDIFYSDK_MAX_APP_NAME_LENGTH, "%s", "MyApp");
settings.port = 9330;
CSpeedifySDK sdk = SpeedifySDK_CreateWithSettings(settings);

SpeedifySDK_CreateWithSettings does not launch the daemon and does not block — it only configures the client. The first call that performs I/O (such as SpeedifySDK_GetState or SpeedifySDK_GetVersion) is what actually reaches the daemon.

If the daemon isn't reachable, calls return STATE_UNKNOWN / an error result. Use that as a readiness check — poll until the daemon answers:

for (int i = 0; i < 50; i++) { // up to ~10s
SpeedifySDK_VersionResult v = SpeedifySDK_GetVersion(sdk, NULL, NULL);
if (!v.isError) break; // daemon is up
// sleep 200 ms
}

If your app launched the daemon, shut it down cleanly with SpeedifySDK_DaemonExit before SpeedifySDK_Destroy.

Logging in

You must be logged in before you can connect. A fresh daemon starts at STATE_LOGGED_OUT; after authentication it moves to STATE_LOGGED_IN, from which you can connect. Choose a login method:

Login is asynchronous; watch the state to observe the transition, and check the result's errorMessage on failure. Note that if you call SpeedifySDK_SetDoNotStoreCredentials with true, you must log in again on every new daemon run.

The activation-code flow is a two-step login. Call SpeedifySDK_GetActivationCode; the resulting SpeedifySDK_ActivationCodeResult carries an activationCode and an activationUrl (it also supports subscription via a callback). Present those to the user — for example, render the URL as a QR code — and they open the URL in a browser, sign in, and enter the code to authorize this device. On success the daemon transitions to STATE_LOGGED_IN like any other login.

Connecting & disconnecting

SpeedifySDK_ConnectAuto with ACM_CLOSEST connects to the closest server; other ACM_* methods select closest-public / closest-private / P2P / last. Connect by location with SpeedifySDK_ConnectCountry, SpeedifySDK_ConnectCity, or SpeedifySDK_ConnectServer. Disconnect with SpeedifySDK_Disconnect.

The state progression is STATE_LOGGED_INSTATE_CONNECTINGSTATE_CONNECTED (or STATE_AUTO_CONNECTING for automatic connects). STATE_OVERLIMIT means you are connected but all adapters are over their data limit.

State, callbacks & threading

Every getter has two forms. Called with a NULL callback it returns the current value synchronously. Called with a callback it also subscribes you to future updates:

SpeedifySDK_GetState(sdk, onStateChanged, userData); // subscribe to state changes

Subscription callbacks are invoked from an SDK-owned background thread, not your calling thread. Return true from a callback to stay subscribed or false to cancel, or unsubscribe later with SpeedifySDK_UnregisterCallback using the eventId from the result. Because callbacks run on another thread, guard any shared state with a lock, and never call a UI toolkit that requires its own thread directly from a callback — marshal the update to your UI thread instead.

Two models work well; pick whichever fits your app:

  • Subscribe — register callbacks once and let updates be pushed to you. Keep your process alive to keep receiving them.
  • Poll — from your own worker thread, periodically call the synchronous (NULL-callback) getters. Simple and predictable, and a natural fit when you already have a render/update loop.

Reading connection statistics

Enable stat updates once after the daemon is up:

SpeedifySDK_EnableStatUpdates(sdk, true, 0, NULL);

Connection stats are then produced about once per second. (The periods argument is not the update interval — it configures the session-stat timeframes, in hours; pass 0 / NULL to leave them unchanged.)

SpeedifySDK_GetConnectionStats returns a group with one SpeedifySDK_ConnectionStats per underlying connection. The aggregate tunnel throughput is reported on the synthetic entry whose adapterID is "speedify"; the other entries are the individual links. Read receiveBps / sendBps from the "speedify" entry for total download / upload:

SpeedifySDK_ConnectionStatsResult r = SpeedifySDK_GetConnectionStats(sdk, NULL, NULL);
for (uint16_t i = 0; i < r.connectionStats.count; i++) {
if (strcmp(r.connectionStats.connections[i].adapterID, "speedify") == 0) {
int64_t downBps = r.connectionStats.connections[i].receiveBps;
int64_t upBps = r.connectionStats.connections[i].sendBps;
}
}

Some per-link fields (loss, jitter, localIp, …) are not populated on the "speedify" aggregate.

A note on large results

A few result structs are large because they embed fixed-size arrays: SpeedifySDK_DirectoryResult holds up to SPEEDIFYSDK_MAX_SERVERS servers, and SpeedifySDK_AdaptersResult / SpeedifySDK_ConnectionStatsResult up to SPEEDIFYSDK_MAX_ADAPTERS entries — together several megabytes. They are returned by value, so avoid keeping many of them as stack locals (especially on threads with small stacks); allocate them on the heap if you need to hold onto them.