diff mbox series

[03/11] vpn: Add association state before connect state

Message ID 20250124185845.1546384-4-jussi.laakkonen@jolla.com (mailing list archive)
State New
Headers show
Series Add association state for VPNs | expand

Commit Message

Jussi Laakkonen Jan. 24, 2025, 6:58 p.m. UTC
This changes the state machine by adding the VPN_STATE_ASSOCIATION to be
entered right after connect() callback is called. This is needed in
order to properly react with the user input dialog waiting on VPNs.
connect state is now set when the dialog is closed to indicate that user
input is given and now the VPN really connects.

When VPN notify() allback is called the connect state is enforced if the
return value indicates so and the internal state is different. This is
to accommodate the changes required and to operate as a fallback that
the states of provider and driver are kept in sync.

Warn about invalid transition to ASSOCIATION state in case vpn_notify()
gets it as a reply back from plugin notify.
---
 vpn/plugins/vpn.c | 22 +++++++++++++++++++++-
 vpn/plugins/vpn.h | 11 ++++++-----
 2 files changed, 27 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c
index cb0d304b..5cc4c757 100644
--- a/vpn/plugins/vpn.c
+++ b/vpn/plugins/vpn.c
@@ -219,6 +219,9 @@  static int vpn_set_state(struct vpn_provider *provider,
 	case VPN_PROVIDER_STATE_IDLE:
 		data->state = VPN_STATE_IDLE;
 		break;
+	case VPN_PROVIDER_STATE_ASSOCIATION:
+		data->state = VPN_STATE_ASSOCIATION;
+		break;
 	case VPN_PROVIDER_STATE_CONNECT:
 	case VPN_PROVIDER_STATE_READY:
 		data->state = VPN_STATE_CONNECT;
@@ -281,6 +284,12 @@  static DBusMessage *vpn_notify(struct connman_task *task,
 
 	switch (state) {
 	case VPN_STATE_CONNECT:
+		if (data->state == VPN_STATE_ASSOCIATION) {
+			data->state = VPN_STATE_CONNECT;
+			vpn_provider_set_state(provider,
+						VPN_PROVIDER_STATE_CONNECT);
+		}
+		/* fall through */
 	case VPN_STATE_READY:
 		if (data->state == VPN_STATE_READY) {
 			/*
@@ -333,6 +342,16 @@  static DBusMessage *vpn_notify(struct connman_task *task,
 		break;
 
 	case VPN_STATE_UNKNOWN:
+		break;
+
+	/* State transition to ASSOCIATION via notify is not allowed */
+	case VPN_STATE_ASSOCIATION:
+		connman_warn("Invalid %s vpn_notify() state transition "
+					"from %d to %d (ASSOCIATION)."
+					"VPN provider %p is disconnected",
+					vpn_driver_data->name, data->state,
+					state, provider);
+		/* fall through */
 	case VPN_STATE_IDLE:
 	case VPN_STATE_DISCONNECT:
 	case VPN_STATE_FAILURE:
@@ -565,6 +584,7 @@  static int vpn_connect(struct vpn_provider *provider,
 		data->state = VPN_STATE_IDLE;
 		break;
 
+	case VPN_STATE_ASSOCIATION:
 	case VPN_STATE_CONNECT:
 		return -EINPROGRESS;
 
@@ -645,7 +665,7 @@  static int vpn_connect(struct vpn_provider *provider,
 	DBG("%s started with dev %s",
 		vpn_driver_data->provider_driver.name, data->if_name);
 
-	data->state = VPN_STATE_CONNECT;
+	data->state = VPN_STATE_ASSOCIATION;
 
 	return -EINPROGRESS;
 
diff --git a/vpn/plugins/vpn.h b/vpn/plugins/vpn.h
index fd10addf..a8d24fc3 100644
--- a/vpn/plugins/vpn.h
+++ b/vpn/plugins/vpn.h
@@ -34,11 +34,12 @@  extern "C" {
 enum vpn_state {
 	VPN_STATE_UNKNOWN       = 0,
 	VPN_STATE_IDLE          = 1,
-	VPN_STATE_CONNECT       = 2,
-	VPN_STATE_READY         = 3,
-	VPN_STATE_DISCONNECT    = 4,
-	VPN_STATE_FAILURE       = 5,
-	VPN_STATE_AUTH_FAILURE  = 6,
+	VPN_STATE_ASSOCIATION   = 2,
+	VPN_STATE_CONNECT       = 3,
+	VPN_STATE_READY         = 4,
+	VPN_STATE_DISCONNECT    = 5,
+	VPN_STATE_FAILURE       = 6,
+	VPN_STATE_AUTH_FAILURE  = 7,
 };
 
 struct vpn_driver {