diff --git a/manage.c b/manage.c index c172e34..8ca3c61 100644 --- a/manage.c +++ b/manage.c @@ -36,6 +36,10 @@ extern options_t o; static mgmt_msg_func rtmsg_handler[mgmt_rtmsg_type_max]; +/* + * Number of seconds to try connecting to management interface + */ +static const time_t max_connect_time = 15; /* * Initialize the real-time notification handlers @@ -56,15 +60,9 @@ InitManagement(const mgmt_rtmsg_handler *handler) * asynchronous socket event notification for it */ BOOL -OpenManagement(connection_t *c, u_long addr, u_short port) +OpenManagement(connection_t *c) { WSADATA wsaData; - SOCKADDR_IN skaddr = { - .sin_family = AF_INET, - .sin_addr.s_addr = addr, - .sin_port = htons(port) - }; - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) return FALSE; @@ -76,7 +74,8 @@ OpenManagement(connection_t *c, u_long addr, u_short port) FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE) != 0) return FALSE; - connect(c->manage.sk, (SOCKADDR *)&skaddr, sizeof(skaddr)); + connect(c->manage.sk, (SOCKADDR *)&c->manage.skaddr, sizeof(c->manage.skaddr)); + c->manage.timeout = time(NULL) + max_connect_time; return TRUE; } @@ -200,8 +199,12 @@ OnManagement(SOCKET sk, LPARAM lParam) switch (WSAGETSELECTEVENT(lParam)) { case FD_CONNECT: - if (WSAGETSELECTERROR(lParam)) - SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); + if (WSAGETSELECTERROR(lParam)) { + if (time(NULL) < c->manage.timeout) + connect(c->manage.sk, (SOCKADDR *)&c->manage.skaddr, sizeof(c->manage.skaddr)); + else + SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); + } break; case FD_READ: diff --git a/manage.h b/manage.h index 75a6e51..952512f 100644 --- a/manage.h +++ b/manage.h @@ -63,7 +63,7 @@ typedef struct mgmt_cmd { void InitManagement(const mgmt_rtmsg_handler *handler); -BOOL OpenManagement(connection_t *, u_long, u_short); +BOOL OpenManagement(connection_t *); BOOL ManagementCommand(connection_t *, char *, mgmt_msg_func, mgmt_cmd_type); void OnManagement(SOCKET, LPARAM); diff --git a/openvpn.c b/openvpn.c index 0cd6323..db382a4 100644 --- a/openvpn.c +++ b/openvpn.c @@ -539,7 +539,7 @@ ThreadOpenVPNStatus(void *p) SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_CONNECTING)); SetWindowText(c->hwndStatus, LoadLocalizedString(IDS_NFO_CONNECTION_XXX, conn_name)); - if (!OpenManagement(c, inet_addr("127.0.0.10"), c->manage.port)) + if (!OpenManagement(c)) PostMessage(c->hwndStatus, WM_CLOSE, 0, 0); if (o.silent_connection[0] == '0') @@ -660,11 +660,12 @@ StartOpenVPN(connection_t *c) /* Construct command line */ _sntprintf_0(cmdline, _T("openvpn " "--config \"%s\" %s --service %s 0 --log%s \"%s\" " - "--management 127.0.0.10 %hd stdin --auth-retry interact " + "--management %S %hd stdin --auth-retry interact " "--management-hold --management-query-passwords --tls-exit"), c->config_file, proxy_string, exit_event_name, (o.append_string[0] == '1' ? _T("-append") : _T("")), - c->log_path, c->manage.port); + c->log_path, inet_ntoa(c->manage.skaddr.sin_addr), + ntohs(c->manage.skaddr.sin_port)); /* Try to open the service pipe */ service = CreateFile(_T("\\\\.\\pipe\\openvpn\\service"), diff --git a/openvpn_config.c b/openvpn_config.c index 04ad58c..6e445d1 100644 --- a/openvpn_config.c +++ b/openvpn_config.c @@ -78,23 +78,26 @@ ConfigAlreadyExists(TCHAR *newconfig) static void AddConfigFileToList(int config, TCHAR *filename, TCHAR *config_dir) { - connection_t *conn = &o.conn[config]; + connection_t *c = &o.conn[config]; int i; - _tcsncpy(conn->config_file, filename, _countof(conn->config_file) - 1); - _tcsncpy(conn->config_dir, config_dir, _countof(conn->config_dir) - 1); - _tcsncpy(conn->config_name, conn->config_file, _countof(conn->config_name) - 1); - conn->config_name[_tcslen(conn->config_name) - _tcslen(o.ext_string) - 1] = _T('\0'); - _sntprintf_0(conn->log_path, _T("%s\\%s.log"), o.log_dir, conn->config_name); - conn->manage.sk = INVALID_SOCKET; - conn->manage.port = 25340 + config; + _tcsncpy(c->config_file, filename, _countof(c->config_file) - 1); + _tcsncpy(c->config_dir, config_dir, _countof(c->config_dir) - 1); + _tcsncpy(c->config_name, c->config_file, _countof(c->config_name) - 1); + c->config_name[_tcslen(c->config_name) - _tcslen(o.ext_string) - 1] = _T('\0'); + _sntprintf_0(c->log_path, _T("%s\\%s.log"), o.log_dir, c->config_name); + + c->manage.sk = INVALID_SOCKET; + c->manage.skaddr.sin_family = AF_INET; + c->manage.skaddr.sin_addr.s_addr = inet_addr("127.0.0.10"); + c->manage.skaddr.sin_port = htons(25340 + config); /* Check if connection should be autostarted */ for (i = 0; i < MAX_CONFIGS && o.auto_connect[i]; ++i) { - if (_tcsicmp(conn->config_file, o.auto_connect[i]) == 0) + if (_tcsicmp(c->config_file, o.auto_connect[i]) == 0) { - conn->auto_connect = true; + c->auto_connect = true; break; } } diff --git a/options.h b/options.h index 310d387..27781bd 100644 --- a/options.h +++ b/options.h @@ -66,7 +66,8 @@ struct connection { struct { SOCKET sk; - u_short port; + SOCKADDR_IN skaddr; + time_t timeout; char password[16]; mgmt_cmd_t *cmd_queue; } manage;