Browse Source

Save active connections on exit and auto-start in next session

New feature: any connection that is not disconnected on exit
will auto-connect when the GUi is started the next time.

There is no option to toggle auto-connect of any profile. Instead,
just connect normally and leave the connection open while closing the
GUI directly or indirectly (on logout, for example). Such a connection
will auto-connect when the GUI is started the next time.

If auto-connect is not desired for a particular connection, stop it
before exit. Or, the whole feature may be disabled in the setings menu
(implemented in next commit).

Signed-off-by: Selva Nair <selva.nair@gmail.com>
pull/568/head
Selva Nair 2 years ago
parent
commit
fa9e79323b
  1. 125
      main.c
  2. 1
      options.h
  3. 1
      registry.c

125
main.c

@ -66,6 +66,8 @@ static void ShowSettingsDialog();
void CloseApplication(HWND hwnd);
void ImportConfigFileFromDisk();
void ImportConfigFromAS();
static void SaveAutoRestartList();
static void LoadAutoRestartList();
/* Class name and window title */
TCHAR szClassName[ ] = _T("OpenVPN-GUI");
@ -585,6 +587,11 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
ImportConfigFile(o.action_arg, true); /* prompt user */
}
if (o.enable_auto_restart)
{
LoadAutoRestartList();
}
if (!AutoStartConnections()) {
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
@ -675,6 +682,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
return(TRUE);
case WM_ENDSESSION:
SaveAutoRestartList();
StopAllOpenVPN();
OnDestroyTray();
break;
@ -836,6 +844,8 @@ CloseApplication(HWND hwnd)
break; /* show the above message box only once */
}
SaveAutoRestartList(); /* active connection names saved in registry */
DestroyWindow(hwnd);
}
@ -949,3 +959,118 @@ ErrorExit(int exit_code, const wchar_t *msg)
exit(exit_code);
}
}
/**
* Save a list of active connections in registry. If enable_auto_restart
* is false, any previously saved list is deleted and no new list is saved.
* Do not show any messages here as this may be called on receiving
* WM_ENDSESSION (user logout).
*/
static void
SaveAutoRestartList()
{
size_t len = 0;
int nactive = 0;
int max_active = o.num_configs - CountConnState(disconnected);
if (!o.enable_auto_restart || max_active <= 0)
{
/* delete the list -- on load this gets treated as an empty list */
RegDeleteKeyValueW(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, L"auto_restart_list");
return;
}
int *active_conns = malloc((size_t) max_active*sizeof(int));
if (!active_conns)
{
MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Out of memory while persisting state in registry");
return;
}
for (int i = 0; i < o.num_configs; i++)
{
if (o.conn[i].state == disconnected
|| o.conn[i].flags & FLAG_DAEMON_PERSISTENT)
{
continue;
}
/* accumulate space needed for list of active connections */
len += wcslen(o.conn[i].config_name) + 1;
active_conns[nactive++] = i;
}
len++; /* for double nul termination */
if (len == 1) len++; /* two nuls for empty string */
/* Make a double nul terminated list of active connections */
wchar_t *list = calloc(len, sizeof(wchar_t));
if (!list)
{
free(active_conns);
MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Out of memory while persisting state in registry");
return;
}
wchar_t *p = list;
for (int i = 0; i < nactive; i++)
{
connection_t *c = &o.conn[active_conns[i]];
wcscpy(p, c->config_name); /* wcscpy is safe here */
p += wcslen(c->config_name) + 1;
}
/* Save the list in registry for auto-connect on restart */
LSTATUS status = RegSetKeyValueW(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, L"auto_restart_list",
REG_MULTI_SZ, list, (DWORD) len*sizeof(wchar_t));
if (status != ERROR_SUCCESS)
{
MsgToEventLog(EVENTLOG_ERROR_TYPE, L"RegSetKeyValue returned error: status = %lu", status);
}
free(active_conns);
free(list);
}
/*
* Read list of active connections in last session and set them to auto-start
*/
static void
LoadAutoRestartList()
{
wchar_t *list;
DWORD len = 0;
LSTATUS status = RegGetValueW(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, L"auto_restart_list",
RRF_RT_REG_MULTI_SZ, NULL, NULL, &len);
if (status != ERROR_SUCCESS || len == 0)
{
return;
}
list = malloc(len);
if (!list)
{
MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Out of memory while reading state from registry");
return;
}
status = RegGetValueW(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, L"auto_restart_list",
RRF_RT_REG_MULTI_SZ, NULL, list, &len);
if (status != ERROR_SUCCESS)
{
MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Error reading state from registry");
free(list);
return;
}
for (wchar_t *p = list; *p; p += wcslen(p) + 1)
{
connection_t *c = GetConnByName(p);
if (!c || c->flags & FLAG_DAEMON_PERSISTENT)
{
continue;
}
c->auto_connect = true;
}
}

1
options.h

@ -224,6 +224,7 @@ typedef struct {
DWORD ovpn_engine; /* 0 - openvpn2, 1 - openvpn3 */
DWORD enable_persistent; /* 0 - disabled, 1 - enabled, 2 - enabled & auto attach */
DWORD enable_auto_restart; /* 0 - disabled, >0 enabled */
#ifdef DEBUG
FILE *debug_fp;
#endif

1
registry.c

@ -66,6 +66,7 @@ struct regkey_int {
{L"disable_popup_messages", &o.disable_popup_messages, 0},
{L"management_port_offset", &o.mgmt_port_offset, 25340},
{L"enable_peristent_connections", &o.enable_persistent, 2},
{L"enable_auto_restart", &o.enable_auto_restart, 1},
{L"ovpn_engine", &o.ovpn_engine, OPENVPN_ENGINE_OVPN2}
};

Loading…
Cancel
Save