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. Must be called once before using the library.
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.
Deinitialize library. Must be called once after using the library.
Start library main loop. Blocking call.
Stop library event loop.
Returns the same JSON response as /user/locations.
User is responsible for free()
ing the string.
Add a rule to route traffic from a specified IP address via a specified VPN country. Returns 0 on success, -1 on error. Safe to call multiple times to change the country.
ip_addr
- IP address to protect
country
- VPN country to route traffic to
Does not work with wireguard (see Wireguard traffic routing)
Remove rule to route traffic from specified IP address via VPN. Returns 0 on success, -1 on error.
ip_addr
- IP address to unprotect
Does not work with wireguard (see Wireguard traffic routing)
Add a rule to route traffic from a specified MAC address via a specified VPN country. Returns 0 on success, -1 on error. Safe to call multiple times to change the country.
mac_addr
- MAC address to protect
country
- VPN country to route traffic to
Does not work with wireguard (see Wireguard traffic routing)
Remove rule to route traffic from specified MAC address via VPN. Returns 0 on success, -1 on error.
mac_addr
- MAC address to unprotect
Does not work with wireguard (see Wireguard traffic routing)
Add a rule to route traffic from a specified interface via a specified VPN country. Returns 0 on success, -1 on error. Safe to call multiple times to change the country.
iface
- interface to protect
country
- VPN country to route traffic to
Does not work with wireguard (see Wireguard traffic routing)
Remove rule to route traffic from specified interface via VPN. Returns 0 on success, -1 on error.
iface
- interface to unprotect
Does not work with wireguard (see Wireguard traffic routing)
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.
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)
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)
Add access token value to the current configuration
access_token
- platform API access token, received from afwrt_register_device
method
Initiate tunnel connection to specific virtual location.
location
- virtual location name, as provided by afwrt_get_locations()
call.
iface_name
- system interface name.
Terminate tunnel connection to specific virtual location.
location
- virtual location name, same as given to afwrt_setup_tunnel()
call.
Get an SDK version number in MAJOR.MINOR.PATCH format (for example: 1.0.0)
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, country code. 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
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 country.
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