Session API
***********


Connection management algorithm basics
======================================

The Session core uses the normal auto-connect algorithm for selecting
which services will be connected or disconnected. That means only
Services with AutoConnect set to true will be used. The Session
core will assign a connected Service to a Session if the Service
is matching the AllowedBearer filter.

By using the normal auto-connect algorithm, it is possible to
use the Session API and the Service API at the same time.


Session States and Transitions
==============================

There is only one state which is called Free Ride.

The Free Ride state means that a session will go online if a matching
service goes online without calling Service.Connect() itself. The idea
behind this is that a session doesn't request a connection for itself
instead waits until another session actively requires to go online.
This is comparable to piggy-backing.

Connect()
 +------+
 |      v
+------------+
|  Free Ride |
+------------+
  |     ^
  +-----+
 Disconnect()


If an application wants to stay offline it can set an empty
AllowedBearers list.


Session application identification
==================================

Application using session can be identified through different means.

  - SELinux
  - UID
  - GID

ConnMan will try to identify the application in the given order above.
If SELinux is not supported by the system or not configured, ConnMan
will ignore it and fallback asking the D-Bus daemon about the UID of
the application.

The identification is only useful in combination with the policy plugin.


Policy Plugin
=============

The policy plugin allows the administrator to provision/configure
sessions. Each policy needs an application identification in order to
match the policy to a session.

See session-policy-format.txt for more details.


Per application routing
=======================

For each session a policy routing table is maintained. Each policy
routing table contains a default route to the selected service.

Per session iptables rules:

iptables -t mangle -A OUTPUT -m owner [--uid-owner|--gid-owner] $OWNER \
	  -j MARK --set-mark $MARK

Global rules for all sessions:

iptables -t mangle -A INPUT -j CONNMARK --restore-mark
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark

Per application routing is only available when policy files are
used. Without the policy plugin or a valid configuration, the default
session configuration is applied.

The default session configuration does not enable the per application
routing. Sessions are still useful in this setup, because the
notification of sessions is still available, e.g. the online/offline
notification.


Multiple per-session routing tables
===================================

Sessions can be used in an environment with multiple network interfaces,
where an application needs to direct outside traffic through a selected
interface(s). ConnMan can maintain multiple sessions in a connected
stated, and the application can dynamically, on a per-socket basis,
select which session is used to route traffic.

Example use cases are:
- monitoring liveness of multiple connected interfaces, by sending
  end-to-end heartbeat traffic on all of them in parallel.
- prioritising traffic - e.g. sensitive data can be transferred over a slow,
  but secure connection, while big, public downloads use a second session

By default, ConnMan maintains only one online service. So it is impossible
to send external traffic (routed through a gateway) on multiple interfaces.
In order to enable this functionality, an application needs to issue the
following API calls:
- create multiple sessions, one for each interface to be used
- set each session's AllowedInterface config field to the required interface
  name (eth0, eth1, wlan0, ppp0, etc.)
- set each session's SourceIPRule config field to true
- connect each session (or the service it is using)

That will instruct ConnMan to create multiple routing tables, with default
routes in them. After that, the application can issue a bind() call on each
socket, using required interface's source IP address. The bind() call must
be made before a connect() call on a socket.
