Add a button for detaching from the management interface

Useful for releasing the management interface if the user wants to
connect to it by other means.

Detached connections are set to state = detached (no disconnected)
and auto_connect disabled, so that they could be handled properly
during a re-attach.

Signed-off-by: Selva Nair <selva.nair@gmail.com>
pull/519/head
Selva Nair 2022-07-07 20:49:00 -04:00
parent 0e76e4b544
commit 7f794eec3d
6 changed files with 45 additions and 11 deletions

6
main.c
View File

@ -358,7 +358,7 @@ StopAllOpenVPN()
*/
for (i = 0; i < o.num_configs; i++)
{
if (o.conn[i].state != disconnected)
if (o.conn[i].state != disconnected && o.conn[i].state != detached)
{
if (o.conn[i].flags & FLAG_DAEMON_PERSISTENT)
{
@ -374,7 +374,7 @@ StopAllOpenVPN()
/* Wait for all connections to terminate (Max 5 sec) */
for (i = 0; i < 20; i++, Sleep(250))
{
if (CountConnState(disconnected) == o.num_configs)
if (CountConnState(disconnected) + CountConnState(detached) == o.num_configs)
break;
}
}
@ -522,7 +522,7 @@ ManagePersistent(HWND hwnd, UINT UNUSED msg, UINT_PTR id, DWORD UNUSED now)
{
if (o.conn[i].flags & FLAG_DAEMON_PERSISTENT
&& o.conn[i].auto_connect
&& o.conn[i].state == disconnected)
&& (o.conn[i].state == disconnected || o.conn[i].state == detached))
{
/* disable auto-connect to avoid repeated re-connect
* after unrecoverable errors. Re-enabled on successful

View File

@ -48,6 +48,7 @@
#define ID_RESTART 164
#define ID_HIDE 165
#define ID_TXT_VERSION 166
#define ID_DETACH 167
#define ID_TXT_BYTECOUNT 168
#define ID_TXT_IP 169

View File

@ -140,7 +140,8 @@ void
OnHold(connection_t *c, UNUSED char *msg)
{
EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), TRUE);
if ((c->flags & FLAG_DAEMON_PERSISTENT) && (c->state == disconnecting))
if ((c->flags & FLAG_DAEMON_PERSISTENT)
&& (c->state == disconnecting || c->state == resuming))
{
/* retain the hold state if we are here while disconnecting */
c->state = onhold;
@ -1343,11 +1344,25 @@ OnStop(connection_t *c, UNUSED char *msg)
c->failed_psw_attempts = 0;
c->failed_auth_attempts = 0;
c->state = disconnected;
if (c->flags & FLAG_DAEMON_PERSISTENT)
{
/* user initiated disconnection -- stay detached and do not auto-reconnect */
c->state = detached;
c->auto_connect = false;
}
CheckAndSetTrayIcon();
SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONNECTED));
SendMessage(c->hwndStatus, WM_CLOSE, 0, 0);
break;
case onhold:
/* stop triggered while on hold -- possibly the daemon exited. Treat same as detaching */
case detaching:
c->state = detached;
CheckAndSetTrayIcon();
SendMessage(c->hwndStatus, WM_CLOSE, 0, 0);
break;
case suspending:
c->state = suspended;
CheckAndSetTrayIcon();
@ -1844,6 +1859,7 @@ RenderStatusWindow(HWND hwndDlg, UINT w, UINT h)
MoveWindow(GetDlgItem(hwndDlg, ID_TXT_VERSION), w-DPI_SCALE(180), h - DPI_SCALE(55), DPI_SCALE(170), DPI_SCALE(15), TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_DISCONNECT), DPI_SCALE(20), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_RESTART), DPI_SCALE(145), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_DETACH), DPI_SCALE(270), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE);
MoveWindow(GetDlgItem(hwndDlg, ID_HIDE), w - DPI_SCALE(130), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE);
}
@ -1908,6 +1924,14 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
rect.top + rand()%100, 0, 0, SWP_NOSIZE);
GetClientRect(hwndDlg, &rect);
RenderStatusWindow(hwndDlg, rect.right, rect.bottom);
if (c->flags & FLAG_DAEMON_PERSISTENT && o.enable_persistent > 0)
{
EnableWindow(GetDlgItem(hwndDlg, ID_DETACH), TRUE);
}
else
{
ShowWindow(GetDlgItem(hwndDlg, ID_DETACH), SW_HIDE);
}
/* Set focus on the LogWindow so it scrolls automatically */
SetFocus(hLogWnd);
return FALSE;
@ -1944,6 +1968,11 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG));
RestartOpenVPN(c);
return TRUE;
case ID_DETACH:
SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG));
DetachOpenVPN(c);
return TRUE;
}
break;
@ -1958,7 +1987,7 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_CLOSE:
c = (connection_t *) GetProp(hwndDlg, cfgProp);
if (c->state != disconnected)
if (c->state != disconnected && c->state != detached)
ShowWindow(hwndDlg, SW_HIDE);
else
DestroyWindow(hwndDlg);
@ -2004,7 +2033,7 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_OVPN_DETACH:
c = (connection_t *) GetProp(hwndDlg, cfgProp);
/* just stop the thread keeping openvpn.exe running */
c->state = disconnecting;
c->state = detaching;
EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE);
EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE);
OnStop(c, NULL);
@ -2071,7 +2100,7 @@ ThreadOpenVPNStatus(void *p)
_tcsncpy(conn_name, c->config_file, _countof(conn_name));
conn_name[_tcslen(conn_name) - _tcslen(o.ext_string) - 1] = _T('\0');
c->state = ((c->state == suspended) ? resuming : connecting);
c->state = (c->state == suspended || c->state == detached) ? resuming : connecting;
/* Create and Show Status Dialog */
c->hwndStatus = CreateLocalizedDialogParam(ID_DLG_STATUS, StatusDialogFunc, (LPARAM) c);
@ -2271,7 +2300,7 @@ StartOpenVPN(connection_t *c)
}
return FALSE;
}
else if (c->state != disconnected)
else if (c->state != disconnected && c->state != detached)
{
return FALSE;
}
@ -2517,6 +2546,7 @@ DetachOpenVPN(connection_t *c)
/* currently supported only for persistent connections */
if (c->flags & FLAG_DAEMON_PERSISTENT)
{
c->auto_connect = false;
PostMessage(c->hwndStatus, WM_OVPN_DETACH, 0, 0);
}
}

View File

@ -73,6 +73,8 @@ typedef enum {
suspending,
suspended,
resuming,
detaching,
detached,
} conn_state_t;
/* Interactive Service IO parameters */

View File

@ -102,6 +102,7 @@ BEGIN
LTEXT "", ID_TXT_IP, 20, 160, 300, 10
PUSHBUTTON "&Disconnect", ID_DISCONNECT, 50, 190, 50, 14
PUSHBUTTON "&Reconnect", ID_RESTART, 150, 190, 50, 14
PUSHBUTTON "De&tach", ID_DETACH, 180, 190, 50, 14, WS_DISABLED
PUSHBUTTON "&Hide", ID_HIDE, 100, 190, 50, 14
END

6
tray.c
View File

@ -511,11 +511,11 @@ SetMenuStatusById(int i, conn_state_t state)
int checked = 0;
if (state == connected || state == disconnecting) checked = 1;
else if (state != disconnected) checked = 2;
else if (state != disconnected && state != detached && state != onhold) checked = 2;
if (o.num_configs == 1)
{
if (state == disconnected)
if (state == disconnected || state == detached)
{
EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_ENABLED);
EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_GRAYED);
@ -581,7 +581,7 @@ SetMenuStatusById(int i, conn_state_t state)
}
}
if (state == disconnected)
if (state == disconnected || state == detached)
{
EnableMenuItem(hMenuConn[i], IDM_CONNECTMENU, MF_ENABLED);
EnableMenuItem(hMenuConn[i], IDM_DISCONNECTMENU, MF_GRAYED);