VPN Connections
A Virtual Private Network (VPN) connects 2 computers securely and privately over the internet. Using the VPN service, you can allow the users of your application to initialize the VPN device, and manage routing, DNS, and firewall features. A VPN connection consists of multiple components, mainly with the VPN server and client connecting over a tunnel.
This feature is supported in mobile applications only.
The main features of the VPN Service API include:
-
VPN manager
You can create or initialize the tunnel interface for the VPN device with various functions. The application can use those functions to get various tunnel details, such as the tunnel ID and tunnel name, MTU for the tunnel interface, and connection statistics.
You can also set various details, such as the MTU for the tunnel interface, and the session name.
The
vpnsvc_tun_s
structure contains detailed information about the tunnel interface, such as the ID, name, and MTU. The possible errors are defined with the vpnsvc_error_e enumerator.Table: Common macros
Macro Description VPNSVC_IP4_STRING_LEN
IPv4 address string length VPNSVC_VPN_IFACE_NAME_LEN
VPN interface name length VPNSVC_SESSION_STRING_LEN
Session name string length -
VPN profile
You can map the VPN profile and get details about the VPN service by using the vpnsvc_h handle.
The VPN profile provides different functions for routing management, DNS management, and firewall management:
- The
vpnsvc_init()
function is used to a initialize the VPN interface and get the handle. - The
vpnsvc_h
handle is used to configure the tunnel interface before using the VPN application control to ask the user permission to connect to the VPN service. - The
vpnsvc_block_networks()
function is used to block network traffic by creating a route parameter for allowed VPN and original interface routes.
- The
-
VPN statistics
The VPN service allows you to track data transfer information. Use the VPN statistics to gather and reset statistics on network usage, such as the size of the sent or received data, in bytes:
- The
vpnsvc_read()
function is used to read the data from tunnel interface in a specified time period. - The
vpnsvc_write()
function is used to write data to a tunnel file descriptor with a specific size.
- The
The VPN service uses 2 mechanisms for managing access control between the application and service:
-
Privilege:
The application needs the partner level privilege for accessing the VPN service daemon.
-
Application control:
Connecting or disconnecting from a VPN network requires user permission, which is requested by invoking the VPN application control.
VPN Connection Components
A VPN connection includes the following components:
-
VPN server
A computer that accepts VPN connections from VPN clients.
-
VPN client
A computer that initiates a VPN connection to a VPN server. A VPN client can be an individual computer or a router.
-
Tunnel
The portion of the connection in which your data is encapsulated.
-
VPN connection
The portion of the connection in which your data is encrypted. For typical secure VPN connections, the data is encrypted and encapsulated along the same portion of the connection.
-
Tunneling protocols
Protocols that are used to manage tunnels and encapsulate private data. Data that is tunneled must also be encrypted to be a VPN connection.
-
Tunneled data
Data that is usually sent across a private point-to-point link.
-
Transit inter-network
The shared or public network crossed by the encapsulated data. The transit inter-network can be the Internet or a private IP-based intranet.
Prerequisites
To enable your application to use the VPN service functionality:
-
To use the VPN Service API, the application has to request permission by adding the following privilege to the
tizen-manifest.xml
file:<privileges> <privilege>http://developer.samsung.com/tizen/vpnservice</privilege> </privileges>
-
To use the functions and data types of the VPN Service API, include the
<vpn_service.h>
header file in your application:#include <vpn_service.h>
-
To be able to use all VPN functions, you must create a handle that contains information about the VPN. At the beginning, create a vpnsvc_h type variable, which is a
void*
that stores the VPN handle.vpnsvc_h handle = NULL;
-
Create the VPN handle using the
vpnsvc_init()
function that allows you to obtain the VPN state and data transfer information:char *name = TEST_VPN_IF_NAME; int ret = VPNSVC_ERROR_NONE; ret = vpnsvc_init(name, &handle); if (ret != VPNSVC_ERROR_NONE) printf("vpnsvc_init failed: %d\n", ret);
-
When the VPN handle is no longer needed, destroy it using the
vpnsvc_deinit()
function:if (handle) vpnsvc_deinit(handle); handle = NULL;
Getting Interface Parameters
To get the interface parameters after successfully initializing the VPN service:
-
Get the interface file descriptor using the
vpnsvc_get_iface_fd()
function:int int_value; if (vpnsvc_get_iface_fd(handle, &int_value) == VPNSVC_ERROR_NONE) printf("iface_fd: %d\n", int_value);
-
Get the interface index using the
vpnsvc_get_iface_index()
function:int int_value; if (vpnsvc_get_iface_index(handle, &int_value) == VPNSVC_ERROR_NONE) printf("iface_index: %d\n", int_value);
-
Get the interface name using the
vpnsvc_get_iface_name()
function:char *result_name = NULL; int ret = VPNSVC_ERROR_NONE; ret = vpnsvc_get_iface_name(handle, &result_name); if (ret == VPNSVC_ERROR_NONE) printf("iface_name: %s\n", result_name);
-
Get the session for the interface using the
vpnsvc_get_session()
function:int ret = VPNSVC_ERROR_NONE; char *get_session = NULL; ret = vpnsvc_get_session(handle, &get_session); printf("Session Name = %s\n", get_session); printf("vpnsvc_set_session succeeded!\n");
Setting Interface Parameters
To set the interface parameters:
-
Set the MTU configuration for the tunnel interface using the
vpnsvc_set_mtu()
function, and update the value using thevpnsvc_update_settings()
function:int ret; ret = vpnsvc_set_mtu(handle, 9000); if (ret != VPNSVC_ERROR_NONE) printf("vpnsvc_set_mtu failed!\n"); else printf("vpnsvc_set_mtu succeeded!\n"); ret = vpnsvc_update_settings(handle); if (ret != VPNSVC_ERROR_NONE) printf("vpnsvc_update_settings failed!\n"); else printf("vpnsvc_update_settings succeeded!\n");
-
Set the session name for the tunnel interface using the
vpnsvc_set_session()
function:char *set_session = "vpnsvc_test VPN Session"; int ret; ret = vpnsvc_set_session(handle, set_session); if (ret != VPNSVC_ERROR_NONE) printf("vpnsvc_set_session failed!\n");
Configuring the Interface and Connecting to the Service
To configure the interface and connect to the VPN service through an application control:
-
Define a function to launch the VPN application control and a callback to handle the results:
#include <app_control.h> void launch_vpn_service_appcontrol(void) { app_control_h service; app_control_create(&service); app_control_set_operation(service, APP_CONTROL_OPERATION_SETTING_VPN); app_control_add_extra_data(service, APP_CONTROL_DATA_TYPE, "up"); app_control_add_extra_data(service, APP_CONTROL_DATA_NAME, "tizen"); app_control_set_launch_mode(service, APP_CONTROL_LAUNCH_MODE_GROUP); app_control_send_launch_request(service, vpn_appcontrol_result_cb, NULL); app_control_destroy(service); } static void vpn_appcontrol_result_cb(app_control_h request, app_control_h reply, app_control_result_e result, void *user_data) { char *result_txt; switch (result) { case APP_CONTROL_RESULT_APP_STARTED: case APP_CONTROL_RESULT_SUCCEEDED: dlog_print(DLOG_INFO, LOG_TAG, "Success!"); break; case APP_CONTROL_RESULT_FAILED: dlog_print(DLOG_INFO, LOG_TAG, "Failed!"); break; case APP_CONTROL_RESULT_CANCELED: dlog_print(DLOG_INFO, LOG_TAG, "Canceled!"); break; } app_control_get_extra_data(reply, APP_CONTROL_DATA_TEXT, &result_txt); dlog_print(DLOG_INFO, LOG_TAG, "Result: %s", result_txt); }
-
Protect the underlying VPN traffic to be routed to the VPN itself by binding the socket to the underlying network interface, such as
wlan0
:int sock; int ret; ret = vpnsvc_protect(handle, sock, "wlan0"); if (ret != VPNSVC_ERROR_NONE) printf("vpnsvc_protect failed!\n"); else printf("vpnsvc_protect succeeded!\n");
-
Set up the connection information, which includes the local IP address and the remote IP address:
int ret; char local[VPNSVC_IP4_STRING_LEN] = {'\0',}; char remote[VPNSVC_IP4_STRING_LEN] = {'\0',}; if (!handle) { printf("invalid handle\n"); return -1; } strncpy(local, "192.168.0.82", VPNSVC_IP4_STRING_LEN); strncpy(remote, "192.168.0.1", VPNSVC_IP4_STRING_LEN); /* Local IP address */ ret = vpnsvc_set_local_ip_address(handle, local); if (ret != VPNSVC_ERROR_NONE) printf("vpnsvc_set_local_ip_address failed!\n"); else printf("vpnsvc_set_local_ip_address succeeded!\n"); /* Remote IP address */ ret = vpnsvc_set_remote_ip_address(handle, remote); if (ret != VPNSVC_ERROR_NONE) printf("vpnsvc_set_remote_ip_address failed!\n"); else printf("vpnsvc_set_remote_ip_address succeeded!\n");
-
Update the vpnsvc_h handle with the connection information by calling the
vpnsvc_update_settings()
function:ret = vpnsvc_update_settings(handle); if (ret != VPNSVC_ERROR_NONE) printf("vpnsvc_update_settings failed!\n"); else printf("vpnsvc_update_settings succeeded!\n");
-
Launch the application control to allow the user to connect to the VPN service:
launch_vpn_service_appcontrol();
Blocking and Unblocking Networks
To block or unblock the network:
-
Block all traffic, except specified allowed networks, and send the specified UP addresses to a specified interface:
char *block_nets[2]; int block_prefix[2]; int block_nr_nets = 2; char *allow_nets[2]; int allow_prefix[2]; int allow_nr_nets = 2; int ret; if (!handle) { printf("invalid handle\n"); return -1; } block_nets[0] = malloc(sizeof(char) * VPNSVC_IP4_STRING_LEN); block_nets[1] = malloc(sizeof(char) * VPNSVC_IP4_STRING_LEN); memset(block_nets[0], 0, sizeof(char) * VPNSVC_IP4_STRING_LEN); memset(block_nets[1], 0, sizeof(char) * VPNSVC_IP4_STRING_LEN); strncpy(block_nets[0], "125.209.222.141", VPNSVC_IP4_STRING_LEN); block_prefix[0] = 32; strncpy(block_nets[1], "180.70.134.19", VPNSVC_IP4_STRING_LEN); block_prefix[1] = 32; allow_nets[0] = malloc(sizeof(char) * VPNSVC_IP4_STRING_LEN); allow_nets[1] = malloc(sizeof(char) * VPNSVC_IP4_STRING_LEN); memset(allow_nets[0], 0, sizeof(char) * VPNSVC_IP4_STRING_LEN); memset(allow_nets[1], 0, sizeof(char) * VPNSVC_IP4_STRING_LEN); strncpy(allow_nets[0], "216.58.221.142", VPNSVC_IP4_STRING_LEN); allow_prefix[0] = 32; strncpy(allow_nets[1], "206.190.36.45", VPNSVC_IP4_STRING_LEN); allow_prefix[1] = 32; ret = vpnsvc_block_networks(handle, block_nets, block_prefix, block_nr_nets, allow_nets, allow_prefix, allow_nr_nets); if (ret != VPNSVC_ERROR_NONE) printf("vpnsvc_block_networks failed!\n"); else printf("vpnsvc_block_networks succeeded!\n");
-
Remove any restrictions from the VPN network:
int ret; if (!handle) { printf("invalid handle\n"); return -1; } ret = vpnsvc_unblock_networks(handle); if (ret != VPNSVC_ERROR_NONE) printf("vpnsvc_unblock_networks failed!\n"); else printf("vpnsvc_unblock_networks succeeded!\n");
Reading and Writing Data
To read or write data:
-
Check whether there is data to read within a specified time period:
int ret; int timeout_ms = 20; ret = vpnsvc_read(handle, timeout_ms); if (ret == VPNSVC_ERROR_NONE) printf("vpnsvc_read: Data available to read!\n");
-
Write data directly to the underlying socket using a system call for performance. The number of bytes written is returned on success (the same as the system write call).
int ret; char *message = "test message"; ret = vpnsvc_write(handle, message, strlen(message)); if (ret < 0) printf("vpnsvc_write: failed!\n"); else if (ret == 0) printf("vpnsvc_write: Nothing written!\n"); else printf("vpnsvc_read: %d bytes written!\n", ret);
Related Information
- Dependencies
- Tizen 3.0 and Higher for Mobile