Unified VPN SDK for Routers
Introduction
The Router VPN SDK allows developers to manage Virtual Private Network (VPN) functionalities directly from their applications. It simplifies the process of creating, configuring and monitoring VPN connections on routers. This SDK is ideal for developers building network security, privacy, or enterprise network management solutions.
Quick Start
System requirements
Linux based OS with kernel version greater than 4.14, OpenWRT 19.07 and higher versions. The following packages should be installed: libc
, kmod-tun (TUN/TAP device driver)
, ca-bundle
, and libnetfilter-conntrack
.
SDK Installation
Place libafwrt.so, libwireguard_tools.so
, and afwrt.h
in the required location.
Minimal working configuration
SDK Architecture
Figure 1: Architecture of the Router SDK represents a high-level architecture of a Router SDK system, highlighting the interaction between various components in a test or partner application and the underlying operating system (OS).
Key Components of the image:
Test / Partner Application: This serves as the environment where the SDK operates and interacts with.
Router SDK:
Business Logic: The core logic layer responsible for handling specific business operations within the router.
VPN Protocol: This module manages the VPN functionality, allowing the system to handle secure traffic routing.
Platform-Specific Module: Adapts the SDK to the platform (e.g., router-specific functionality or configuration), ensuring compatibility with various hardware or operating systems.
C API: Exposes a C-language interface for communication between the application and the SDK. The test/partner application interacts with the SDK through this API.
Operating System (OS): The diagram shows that the Router SDK interacts with the OS via:
Linux Kernel: To manage low-level operations related to networking, devices, and other hardware interfaces.
Platform System API: For higher-level interactions, such as controlling system resources or accessing platform-specific features.
VPN features overview
Supported VPN Protocols, platforms, routers
Supported VPN Protocols
Hydra
WireGuard (version 1.0.20210914)
Supported platforms
Linux-based operating systems (e.g., OpenWRT
, Ubuntu
, etc.).
Key features
Multi-locations
refers to the capability of a VPN service to provide multiple server locations across different geographic regions, allowing users to connect to the internet through any of these servers at the same time (see below).Multi-protocols
refers to the ability of a VPN service to support multiple tunneling or encryption protocols for establishing secure connections. These protocols define how data is encrypted, transmitted, and secured between a user’s device and the VPN server.Dynamic configuration without SDK restart
refers to the ability to modify or update a VPN client’s configuration settings without needing to restart the SDK or the underlying VPN client. This feature allows real-time changes to VPN parameters like server selection, security settings, network routing, or other VPN configurations without requiring a full reset of the VPN service.Transparent tunneling
refers to a networking technique where data is transmitted through a VPN tunnel without the end-user or applications being aware of the underlying tunneling process. This method ensures that the tunneling is transparent to the user device and applications, meaning they don't need to be reconfigured or have any knowledge that their data is being encapsulated and transmitted through a tunnel.
Key Components of the image:
Connected Devices. Several devices, such as a TV, Laptop, and Mobile Device, are connected to a router (referred to as the Router Gateway (GW)).
Router SDK. The router is running the Router SDK, which manages how the traffic from each device is routed. The SDK decides whether traffic should be routed through VPN tunnels or directly to the target server (bypassed).
Transparent Tunneling. The SDK handles transparent tunneling for connected devices. Devices do not need to configure VPN settings directly—traffic is routed automatically by the router.
Traffic Routing. The traffic from each device is treated differently. TV traffic is routed through a VPN Tunnel to the VPN Server in GB. Laptop traffic is bypassed, meaning it is sent directly to the target server without using a VPN. Mobile Device traffic is routed through a VPN Tunnel to the VPN Server in the US.
Target Server and Multilocation. All traffic eventually reaches the Target Server, either directly (bypass) or through VPN tunnels. Multiple VPN Tunnels are established for different locations, in this case, GB and US, to enable geographic flexibility in routing. This setup illustrates selective VPN routing based on network requirements, allowing specific devices to use different VPN locations or bypass the VPN entirely.
Example Usage
API Documentation
The library allows developers to manage Virtual Private Network(VPN) functionalities directly from their applications. It simplifies the process of creating, configuring and monitoring VPN connections. All methods are thread safe.
Callback function
afwrt_event_callback_t
afwrt_event_callback_t
Callback function to receive periodic SDK event.
Parameters:
event_str
: Event string in JSON format, see "Callback events" section
Initialization and Termination
afwrt_init
afwrt_init
Initializes the library. Needs to be called once before using the library.
Parameters:
params_json
: Configuration in JSON format. See "All configuration parameters" section. Cannot beNULL
.event_callback
: Callback function to receive SDK events. See "Callback events" section. Can beNULL
.
Returns: 0
on success, -1
on error.
afwrt_deinit
afwrt_deinit
Deinitializes the library. Needs to be called once after using the library.
Returns: 0
on success, -1
on error.
Main Loop
afwrt_start
afwrt_start
Starts the library main loop. This is a blocking call. After calling this, you need to call other methods (setup and teardown tunnel, protect and unprotect IP/MAC/interface) in separate threads.
Returns: 0
on success, -1
on error.
afwrt_stop
afwrt_stop
Stops the library main loop. Should be called once to stop the VPN client.
Returns: Always returns 0
.
IP Address Protection
afwrt_protect_ip_addr
afwrt_protect_ip_addr
Adds a rule to route traffic from the specified IP address via a specified VPN location. Can be called multiple times to change the location. This should be used when the library is initialized, started, and the tunnel for this location is set up. Doesn't work with wireguard, see "Wireguard traffic routing" section
Parameters:
ip_addr
: IP address to protect.location
: VPN location to route traffic.
Returns: 0
on success, -1
on error.
afwrt_unprotect_ip_addr
afwrt_unprotect_ip_addr
Removes the rule to route traffic from the specified IP address via the VPN. Should be used for existing rules. Doesn't work with wireguard, see "Wireguard traffic routing" section
Parameters:
ip_addr
: IP address to unprotect.
Returns: 0
on success, -1
on error.
MAC Address Protection
afwrt_protect_mac_addr
afwrt_protect_mac_addr
Adds a rule to route traffic from the specified MAC address via a specified VPN location. Can be called multiple times to change the location. This should be used when the library is initialized, started, and the tunnel for this location is set up. Doesn't work with wireguard, see "Wireguard traffic routing" section
Parameters:
mac_addr
: MAC address to protect.location
: VPN location to route traffic.
Returns: 0
on success, -1
on error.
afwrt_unprotect_mac_addr
afwrt_unprotect_mac_addr
Removes the rule to route traffic from the specified MAC address via the VPN. Should be used for existing rules. Doesn't work with wireguard, see "Wireguard traffic routing" section
Parameters:
mac_addr
: MAC address to unprotect.
Returns: 0
on success, -1
on error.
Interface Protection
afwrt_protect_iface
afwrt_protect_iface
Adds a rule to route traffic from the specified interface via a specified VPN location. Can be called multiple times to change the location. This should be used when the library is initialized, started, and the tunnel for this location is set up. Doesn't work with wireguard, see "Wireguard traffic routing" section
Parameters:
iface
: Interface to protect.location
: VPN location to route traffic.
Returns: 0
on success, -1
on error.
afwrt_unprotect_iface
afwrt_unprotect_iface
Removes the rule to route traffic from the specified interface via the VPN. Should be used for existing rules. Doesn't work with wireguard, see "Wireguard traffic routing" section
Parameters:
iface
: Interface to unprotect.
Returns: 0
on success, -1
on error.
Access Token Management
afwrt_register_device
afwrt_register_device
(Deprecated) Authenticates a device using any supported by Pango auth provider. Saving the received token value is considered good practice. This function is deprecated, use afwrt_auth_device
instead of afwrt_register_device
.
Parameters:
auth_method
: Supported auth provider oranonymous
. Exact strings are provided by Pango for each project. See "All configuration parameters" sectionauth_token
: Auth token suitable for the specified auth method. See "All configuration parameters" section
Returns: Access token, which can be used in the afwrt_set_access_token()
call.
afwrt_auth_device
afwrt_auth_device
Authenticates a device using any supported by Pango auth provider. Saving a received token value would be considered a good practice.
Parameters:
auth_method
: Supported auth provider oranonymous
. Exact strings are provided by Pango for each project. See "All configuration parameters" sectionauth_token
: Auth token suitable for the specified auth method. See "All configuration parameters" section
Returns: Access token, which can be used in the afwrt_set_access_token()
call.
afwrt_set_access_token
afwrt_set_access_token
Adds an access token value to the current configuration.
Parameters:
access_token
: Platform API access token. The token may consist only of Latin letters, numbers, and.
,_
,-
,~
. "URL encode" needs to apply for other characters.
Returns: 0
on success, -1
when an invalid access token is provided.
Version Management
afwrt_version
afwrt_version
Retrieves the SDK version number in MAJOR.MINOR.PATCH
format (e.g., 1.0.0
). This can be used at any time.
Returns: A statically allocated version string. It does not need to be freed.
Tunnel Management
afwrt_setup_tunnel
afwrt_setup_tunnel
Initiates a tunnel connection to a specific virtual location. Should be used when the library is initialized, started, and list of locations have been retrieved.
Hydra-specific behavior:
If the VPN protocol is
hydra-tcp
,iface_name
is ignored.If the location connection is interrupted, this function should be used to initiate re-connection.
No actual connection is made until the first network packet is sent.
Wireguard-specific behavior:
Connection is initiated immediately.
route_failed
orroute_connected
events are expected soon after calling this function.
Parameters:
location
: Virtual location name, as provided by theafwrt_get_locations()
call.iface_name
: System interface name.
Returns: 0
on success, -1
on error with errno
set to:
EINVAL
: Null location or interface for Wireguard, orafwrt_init()
was not called.ENOENT
: Unknown location ID.EBUSY
: Interface already in use.EEXIST
: Tunnel to the specified location is already set.
afwrt_teardown_tunnel
afwrt_teardown_tunnel
Terminates the tunnel connection to a specific virtual location. Should be used for an existing tunnel.
Parameters:
location
: Virtual location name, as provided toafwrt_setup_tunnel()
.
Returns: 0
on success, -1
on error with errno
set to:
EINVAL
: Null location orafwrt_init()
was not called.ENOENT
: No known connection to the provided location.EBUSY
: At least one active rule for this location exists (Hydra only).
Location Management
afwrt_get_locations
afwrt_get_locations
Retrieves a JSON response containing VPN locations, private groups, DNS servers, features, and profiles. This should be used when the library is initialized and started. The caller is responsible for freeing the returned string. The JSON response looks like:
Returns: JSON string with a list of locations, NULL
on failure.
All configuration parameters
"tun_ifname"
Name of virtual TUN interface will be created by SDK.
Example:
"hydra_tun_fd"
Hydra-specific option. Tells SDK not to create interface but reuse existing one instead. Option value is file descriptor of interface to use.
Example:
"wan_ifname"
Name of WAN interface.
Example:
"vl_default"
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).
Example:
"backend"
Backend server address. Caller should not rely on default value and should specify it explicitly. The specify address will be provided by Pango.
"type"
VPN protocol to use. Possible values: "hydra-tcp", "wireguard". This parameter is deprecated, use "protocol" instead of "type". Default: "hydra-tcp"
"protocol"
VPN protocol to use. Possible values: "hydra-tcp", "wireguard". The "protocol" has higher priority than "type". If "protocol" is empty string than SDK uses "type" as "protocol". If "protocol" is set than "type" will be ignored. Default: ""
"auth_method"
Authentication method, used by client. The value is used to register the device in the Pango infrastructure. The authentication method will be provided by Pango if need.
"auth_token"
Authentication token. The value is used to register the device in the Pango infrastructure.
"data_report_interval"
Event report interval in milliseconds. The time interval between bandwidth events(see "Callback events" section). Default: 30000
(30 seconds).
"default_gateway"
Redirect all traffic including router to SDK TUN interface. Do not create any specific iptables rule for protected IP, MAC, interface, but add a global traffic redirection rule. Default: 0
"ipv6_output_only"
Use only servers which have assigned IPv6 exit pools. Set to 1 to enable. Default: 0
"hydra_default_vl_reconnect_interval"
Hydra reconnect interval when default route fails to connect. Default: 10
"tun_dev_path"
Path to OS tun device. Default: "/dev/net/tun"
"tun_addr"
IPv4 address of SDK TUN interface. Default: "100.73.0.73"
"tun_mtu"
MTU value of SDK TUN interface. If set to 0 - interface MTU value is not updated. Default: 0
"no_iptables"
Do not configure iptables rules from router SDK. 0
- The SDK setups iptables rules. 1
- The SDK client setups iptables rules. Default: 0
"no_socket_setup"
Do not configure tun interface IP addresses. 0
- The SDK setups tun interface. 1
- The SDK client setups interface. Default: 0
"protected_ip_addrs"
Array of protected IP addresses with not empty "ip_addr" and "vl" fields. Default: ""
(empty, no IP addresses to protect).
Example:
"protected_mac_addrs"
An array of protected MAC addresses with no empty "mac_addr" and "vl" fields. Default: ""
(empty, no MAC addresses to protect).
Example:
"protected_ifaces"
An array of interfaces with not empty "iface" and "vl" fields. Default: ""
(empty, no interface to protect).
Example:
Callback events
"ready"
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:
"route_connected"
The event is sent when a link to one of the virtual locations became active.
Example:
"route_disconnected"
The 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:
"route_failed"
The event is sent when a link to one of the virtual locations can not be established.
Example:
The possible values for the reason
field in Hydra are as follows:
201
: Internal Hydra error202
: Recovery timeout expired for connection restoration203
: Route search exhausted204
: No network available205
: Unable to send data; buffer is full206
: Client is blocked
The possible values for the reason
field in Wireguard are as follows:
201
: Internal SDK error202
: Indicates an issue related to the location functionality203
: Indicates an issue related to the node(server) functionality
"bandwidth_info"
The event is sent periodically to the client application.
Example:
"credentials_expire"
The event occurs when internal VPN credentials were expired(usually in 24 hours) and SDK failed to update them automatically. In this case application should stop or restart SDK.
Example:
"auth_success"
The 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:
"invalid_auth"
The event happens when SDK does device registration using provided auth_method and auth_token and receives reject from backend side. Application then should stop or restart SDK with new auth_method and auth_token.
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"
configuration parameter 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.
Example:
Advanced scenario
"default_gateway"
configuration parameter disabled. Selective routing by IP, MAC, or interface name.
First, SDK creates routing table 47 with TUN device default gateway.
Example:
Second, SDK creates a rule to forward all packets with 0x8 mark to table 47.
Example:
Third, SDK creates a custom iptables chain that will contain all specific IP, MAC, and interface rules.
Example:
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:
It doesn't matter in which order rules will appear. All routing priority logic is done by SDK internally (see VPN Core level routing
section).
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.
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
The SDK library does not handle traffic routing for the Wireguard protocol. It is the user's responsibility to set up all required routing rules, routes, and netfilter rules. Below is a typical configuration of the networking stack. These examples assume that the tun_ifname
value is set to "wrt0"
.
Configure Netfilter
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:
Last updated