SDK. Shared library.
Router SDK provides a shared library (with a C header file) that can be integrated with Applications using C calls.
SDK C API
Initialize library
Initialize library. Must be called once before using the library.
Arguments
params_json
- configuration in JSON format. See the "Configuration" section below. Can't be NULL;event_callback
- callback function to receive periodic SDK events. See the "Callback events" section below. Can be NULL.
Return value
0
on success;-1
on failure.
Free library resources
Deinitialize library. Must be called once after using the library.
Return value
0
on success;-1
on failure.
Start VPN
Return value
0
on success;-1
on failure.
Stop VPN
Start library main loop. Blocking call.
Return value
Always returns
0
.
Verify user credentials
Verify that the user's credentials are valid.
Arguments
backend
- URL to backend to interact with;username
- user's account login name;password
- user's password.
Return value
-1
- user credentials are not valid;0
- user credentials are valid;1
- failed to verify user credentials.
Get available locations list
Stop library event loop.
Returns the same JSON response as /user/locations.
Return value
On success JSON string with locations list as provided by backend side;
NULL
on failure.
The caller is responsible for freeing the returned string.
Protect specific IP address and bind to specific location
Add a rule to route traffic from a specified IP address via a specified VPN location. Safe to call multiple times to change the location.
Arguments
ip_addr
- IP address to protect;location
- VPN location to route traffic to.
Return value
0
on success;-1
on failure.
Does not work with wireguard (see Wireguard traffic routing)
Remove protecting rule for specific IP address
Remove rule to route traffic from specified IP address via VPN.
Arguments
ip_addr
- IP address to unprotect.
Return value
0
on success;-1
on failure.
Does not work with wireguard (see Wireguard traffic routing)
Protect specific MAC address and bind to specific location
Add a rule to route traffic from a specified MAC address via a specified VPN location. Safe to call multiple times to change the location.
Arguments
mac_addr
- MAC address to protect;location
- VPN location to route traffic to.
Return value
0
on success;-1
on failure.
Does not work with wireguard (see Wireguard traffic routing)
Remove protecting rule for specific MAC address
Remove rule to route traffic from specified MAC address via VPN.
Arguments
mac_addr
- MAC address to unprotect.
Return value
0
on success;-1
on failure.
Does not work with wireguard (see Wireguard traffic routing)
Protect specific interface and bind it to specific location
Add a rule to route traffic from a specified interface via a specified VPN location. Safe to call multiple times to change the location.
Arguments
iface
- interface to protect;location
- VPN location to route traffic to.
Return value
0
on success;-1
on failure.
Does not work with wireguard (see Wireguard traffic routing)
Remove protecting role for specific interface
Remove rule to route traffic from specified interface via VPN.
Arguments
iface
- interface to unprotect.
Return value
0
on success;-1
on failure.
Does not work with wireguard (see Wireguard traffic routing)
Register device
Register a new device and returns an access token, that will also be included in the configuration. Saving a received token value would be considered a good practice.
Arguments
auth_method
- any supported OAuth provider (i.e. Firebase) or anonymous;auth_token
- OAuth token (if a relevant OAuth provider is set for the auth method).
Return value
Access token. Can be used for later
afwrt_set_access_token()
call.
Use specific access token
Add access token value to the current configuration
Arguments
access_token
- platform API access token, received fromafwrt_register_device
method.
Auth token value may only consist of Latin letters, numbers, and dot, underscore, minus, tilde symbols.
"url encode" must be applied for any other characters (especially for /, ?, &, =, % symbols)
Return value
0
on success;-1
when invalid access token provided.
Bring up connection for specific location
Initiate tunnel connection to specific virtual location.
Arguments
location
- virtual location name, as provided byafwrt_get_locations()
call;iface_name
- system interface name.
Return value
0
on success;-1
on failure.
Failure error codes
When -1
is returned, errno is set to one of values:
EINVAL
- NULL location, NULL interface for wireguard orafwrt_init()
was not called;ENOENT
- unknown location ID;EBUSY
- providediface_name
already in use.EEXIST
- tunnel to specifiedlocation
is already set.
Hydra-specific behavior
If the VPN protocol is
hydra-tcp
,iface_name
is ignored.If location connection was interrupted with calling appropriate event, this function should be used to initiate reconnection.
When this function ls called, no actual connection is done, it will be started with first network packet.
Wireguard-specific behavior
Initiates connection immediately.
It's expected to receive
route_failed
orroute_connected
event soon after the function is called.
Teardown connection to specific location
Terminate tunnel connection to specific virtual location.
Arguments
location
- virtual location name, same as given toafwrt_setup_tunnel()
call.
Return value
0
on success;-1
on failure.
Failure error codes
When -1
is returned, errno is set to one of values:
EINVAL
- NULL location orafwrt_init()
was not called;ENOENT
- there is no known connection, established to providedlocation
;EBUSY
- at least one active rule for this location exists (hydra only).
Get library version
Get an SDK version number in MAJOR.MINOR.PATCH format (for example: 1.0.0)
Return value
Always returns statically allocated version string, do not free it.
Typical workflow
You should implement your own OAuth token (auth_token
) obtaining mechanism and use it before afwrt_start()
or afwrt_register_device()
call.
Callback events
Wireguard-specific event. Emitted when SDK is fully initialized and ready to receive control commands. This event added since wireguard can be started without default location and no "route_connected"
event is emitted in this case.
Example: {"event":"ready"}
This event is sent when a link to one of the virtual locations became active.
Example: { "event": "route_connected", "route_name": "us" }
This event is sent when an active link to one of the virtual locations became inactive due to SDK stop, network condition, or for another external reason.
Example: { "event": "route_disconnected", "route_name": "us" }
This event is sent when a link to one of the virtual locations can not be established.
Example: { "event": "route_failed", "route_name": "fr", "reason_details": "connection failed" }
An event is sent periodically to the client application.
Example: { "event": "bandwidth_info", "bandwidth_info": [ { "data_interval_ms": 100, "n_points": 100, "points_downstream": 0, "points_upstream": 0, "route_name": "us" }, { "data_interval_ms": 100, "n_points": 100, "points_downstream": 0, "points_upstream": 0, "route_name": "de" } ] }
This event occurs when internal SDK credentials were expired (usually in 24 hours) and SDK failed to update them automatically. In this case application must stop or restart SDK.
Example: {"event": "credentials_expire"}
This event happens when SDK successfully receives access_token
while registering device using provided auth_method
and auth_token
. Event also returns access_token
, it should be stored in persistent storage and used during next SDK start.
Example: {"event":"auth_success", "access_token":"keeMeroohohfiefai8AhXaesh9eetheeX8neilu5ichaichuzu"}
This event happens when SDK does device registration using provided auth_method
and auth_token
and receives reject from backend side. Application then must stop or restart SDK with new auth_method
and auth_token
.
Configuration
Minimal working configuration
All configuration parameters
Name of virtual TUN interface created by SDK.
Example: "wrt0"
Hydra-specific option. Tells SDK not to create interface but reuse existing one instead. Option value is file descriptor of interface to use.
Example: 42
Name of virtual TUN interface created by SDK.
Example: "eth1"
"tun_ifname" still should be specified for successful interface management.
Default virtual location. By default, all traffic routed to the SDK TUN interface goes through this location. If not specified or empty, SDK will try to get an optimal location that can be configured on the backend side.
Default: ""
(empty, see above)
Example: "us"
Backend server address. Caller should not rely on default value and should specify it explicitly.
VPN protocol to use. Possible values:
"hydra-tcp"
"wireguard"
Default: "hydra-tcp"
Authentication method, used by client. Value is updated with each afwrt_register_device()
call.
Authentication token. Value is updated with each afwrt_register_device()
call.
Event report interval in milliseconds. The time interval between bandwidth events (see "Callback events" section above).
Default: 30000
(30 seconds)
Redirect all traffic including router to SDK TUN interface. Do not create any specific iptables rule for protected IP, MAC, or interface(see "Routing" section below), but add a global traffic redirection rule.
Default: 0
Sets ipv4/ipv6 protocol usage policy for connecting to VPN nodes. Possible values:
"legacy"
- used for backward compatibility. Shouldn't be set manually, it will be removed in future releases."ipv4_only"
- use only ipv4 protocol."ipv6_only"
- use only ipv6 protocol."both"
- use both ipv4 and ipv6 protocols.
Default: "legacy"
Use only servers which have assigned ipv6 exit pools. Set to 1
to enable.
Default: 0
Hydra reconnect interval when default route fails to connect.
Default: 10
Location of VPN core temporary files. SDK creates or updates a set of temporary files on each start. A directory should be already created for them.
Default: "/etc/afwrt"
Path to OS tun device.
Default: "/dev/net/tun"
IPv4 address of SDK TUN interface.
Default: "100.73.0.73"
MTU value of SDK TUN interface. If set to 0
- interface MTU value is not updated.
Default: 0
Do not configure iptables rules.
Default: 0
Do not configure interface IP addresses.
Default: 0
Array of protected IP addresses with not empty "ip_addr"
and "vl"
fields.
Default: ""
(empty, no IP addresses to protect).
Example: "protected_ip_addrs": [ { "ip_addr": "192.168.50.159", "vl": "us-new-york" }, { "ip_addr": "192.168.50.139", "vl": "de-berlin" } ]
An array of protected MAC addresses with no empty "mac_addr"
and "vl"
fields.
Default: ""
(empty, no MAC addresses to protect).
Example: "protected_mac_addrs": [ { "mac_addr": "08:00:27:AA:D7:17", "vl": "us-new-york" }, { "mac_addr": "09:01:28:AB:D8:18", "vl": "de-berlin" } ]
An array of interfaces with not empty "iface"
and "vl"
fields.
Default: ""
(empty, no interface to protect).
Example: "protected_ifaces": [ { "iface": "eth1", "vl": "us-new-york" }, { "iface": "br0", "vl": "de-berlin" } ]
OS level routing
To protect traffic, SDK creates a TUN device and routes all packets or packets with specific source IP, MAC, or interface to it. To achieve this, SDK creates a set of routing and/or firewall (iptables) rules.
Simple scenario. "default_gateway"
option enabled.
"default_gateway"
option enabled.Redirect just all traffic including router to TUN device.
To be smarter, SDK not changing the default route of the router "main" table, but adding two big subnets with high metrics. 0.0.0.0/1
and 128.0.0.0/1
for IPv4, for example.
Advanced scenario. "default_gateway"
option disabled.
"default_gateway"
option disabled.Selective routing by IP, MAC, or interface name.
First, SDK creates routing table 47 with TUN device default gateway.
Second, SDK creates a rule to forward all packets with 0x8 mark to table 47.
Third, SDK creates a custom iptables chain that will contain all specific IP, MAC, and interface rules.
Such rules can be loaded from config on the initialization phase or changed dynamically using the protection methods above. Each rule marks specified IP, MAC, or interface with 0x8 mark.
Example of the interface, MAC, and IP rules:
It doesn't matter in which order rules will appear. All routing priority logic is done by SDK internally (see below).
VPN Core level routing
Regardless of the OS-level routing mechanism, the core is always ready to do selective routing based on IP, MAC, and interface rules if any. If no rules are specified, traffic will go to "vl_default"
route as described above.
Routing rules priority
MAC address rule has higher priority than IP address rule. IP address rule has higher priority than Interface rule.
For example, there are the following rules:
route traffic from a device with a MAC address
"08:00:27:AA:D7:17"
via"us"
route traffic from a device with an IP address
"192.168.50.139"
via"de"
If both addresses (MAC and IP) belongs to the same device, traffic will be routed via "us"
VPN location.
MAC and Interface to IP resolution
To be able to distinguish device traffic on the L3 network layer SDK needs its IP address.
SDK maintains a mapping from MAC or Interface to IP addresses internally.
It subscribes to changes in neighbors table using a netlink, asking for ones with the following states: NUD_REACHABLE
, NUD_DELAY
, NUD_PROBE
, NUD_PERMANENT
, NUD_STALE
.
Wireguard traffic routing
SDK library does not handle any traffic routing for wireguard protocol. It's user's responsibility to setup all required routing rules, routes and netfilter rules.
Typical configuration of networking stack is described below.
Configure netfliter.
Examples below assume that "tun_ifname" value is set to "wrt0"
.
For ipv4 protocol
For ipv6 protocol
Create routing tables with default routes
For ipv4 protocol
For ipv6 protocol
Add source-based rules to forward specific devices
For ipv4 protocol
For ipv6 protocol
OpenWRT
Firewall
Depends on your firmware version, you may need to insert additional iptables rules manually or via OpenWRT CI. Such rules may look like this:
Dependencies
libc
kmod-tun
ca-bundle
libnetfilter-conntrack
Last updated