|
|
|
@ -19,7 +19,7 @@
|
|
|
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#include <Winsock2.h> |
|
|
|
|
#include <winsock2.h> |
|
|
|
|
|
|
|
|
|
#include "options.h" |
|
|
|
|
#include "main.h" |
|
|
|
@ -75,19 +75,48 @@ OpenManagement(connection_t *c, u_long addr, u_short port)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Try to send a queued management command to OpenVPN |
|
|
|
|
*/ |
|
|
|
|
static void |
|
|
|
|
SendCommand(connection_t *c) |
|
|
|
|
{ |
|
|
|
|
int res; |
|
|
|
|
mgmt_cmd_t *cmd = c->manage.cmd_queue; |
|
|
|
|
if (cmd == NULL || cmd->size == 0) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
res = send(c->manage.sk, cmd->command, cmd->size, 0); |
|
|
|
|
if (res < 1) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (res != cmd->size) |
|
|
|
|
memmove(cmd->command, cmd->command + res, cmd->size - res); |
|
|
|
|
|
|
|
|
|
cmd->size -= res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Send a command to the OpenVPN management interface |
|
|
|
|
*/ |
|
|
|
|
BOOL |
|
|
|
|
ManagementCommand(connection_t *c, char *command, mgmt_msg_func handler, mgmt_cmd_type type) |
|
|
|
|
{ |
|
|
|
|
int res = 0; |
|
|
|
|
int size = strlen(command) + 1; |
|
|
|
|
|
|
|
|
|
mgmt_cmd_t *cmd = calloc(1, sizeof(*cmd)); |
|
|
|
|
if (cmd == NULL) |
|
|
|
|
return FALSE; |
|
|
|
|
|
|
|
|
|
cmd->size = strlen(command) + 1; |
|
|
|
|
cmd->command = malloc(cmd->size); |
|
|
|
|
if (cmd->command == NULL) |
|
|
|
|
{ |
|
|
|
|
free(cmd); |
|
|
|
|
return FALSE; |
|
|
|
|
} |
|
|
|
|
memcpy(cmd->command, command, cmd->size); |
|
|
|
|
*(cmd->command + cmd->size - 1) = '\n'; |
|
|
|
|
|
|
|
|
|
cmd->handler = handler; |
|
|
|
|
cmd->type = type; |
|
|
|
|
|
|
|
|
@ -104,54 +133,12 @@ ManagementCommand(connection_t *c, char *command, mgmt_msg_func handler, mgmt_cm
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (c->manage.cmd_queue == cmd) |
|
|
|
|
{ |
|
|
|
|
*(command + size - 1) = '\n'; |
|
|
|
|
res = send(c->manage.sk, command, size, 0); |
|
|
|
|
*(command + size - 1) = '\0'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (res != size) |
|
|
|
|
{ |
|
|
|
|
if (res == SOCKET_ERROR) |
|
|
|
|
res = 0; |
|
|
|
|
|
|
|
|
|
size -= res; |
|
|
|
|
cmd->command = malloc(size); |
|
|
|
|
if (cmd->command == NULL) |
|
|
|
|
{ |
|
|
|
|
free(cmd); |
|
|
|
|
return FALSE; |
|
|
|
|
} |
|
|
|
|
memcpy(cmd->command, command + res, size); |
|
|
|
|
*(cmd->command + size - 1) = '\n'; |
|
|
|
|
cmd->size = size; |
|
|
|
|
} |
|
|
|
|
SendCommand(c); |
|
|
|
|
|
|
|
|
|
return TRUE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Try to send a queued management command to OpenVPN |
|
|
|
|
*/ |
|
|
|
|
static void |
|
|
|
|
SendCommand(connection_t *c) |
|
|
|
|
{ |
|
|
|
|
int res; |
|
|
|
|
mgmt_cmd_t *cmd = c->manage.cmd_queue; |
|
|
|
|
if (cmd == NULL || cmd->size == 0) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
res = send(c->manage.sk, cmd->command, cmd->size, 0); |
|
|
|
|
if (res < 1) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (res != cmd->size) |
|
|
|
|
memmove(cmd->command, cmd->command + res, cmd->size - res); |
|
|
|
|
|
|
|
|
|
cmd->size -= res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Remove a command from a connection's command queue |
|
|
|
|
*/ |
|
|
|
@ -186,6 +173,7 @@ UnqueueCommand(connection_t *c)
|
|
|
|
|
return TRUE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Handle management socket events asynchronously |
|
|
|
|
*/ |
|
|
|
|