summaryrefslogtreecommitdiff
path: root/src/openvpn/ps.c
diff options
context:
space:
mode:
authorAlberto Gonzalez Iniesta <agi@inittab.org>2016-12-27 18:25:47 +0100
committerAlberto Gonzalez Iniesta <agi@inittab.org>2016-12-27 18:25:47 +0100
commit3a2bbdb05ca6a6996e424c9fb225cb0d53804125 (patch)
treef29063da5bec4caf3853d49a22a09c8619eebd21 /src/openvpn/ps.c
parentd53dba59e78da865c4fe820386ff2f4f76925f3b (diff)
New upstream version 2.4.0upstream/2.4.0
Diffstat (limited to 'src/openvpn/ps.c')
-rw-r--r--src/openvpn/ps.c1330
1 files changed, 689 insertions, 641 deletions
diff --git a/src/openvpn/ps.c b/src/openvpn/ps.c
index 2cb68f1..21b12ca 100644
--- a/src/openvpn/ps.c
+++ b/src/openvpn/ps.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -68,32 +68,34 @@ struct port_share *port_share = NULL; /* GLOBAL */
* usually HTTPS
*/
struct proxy_connection {
- bool defined;
- struct proxy_connection *next;
- struct proxy_connection *counterpart;
- struct buffer buf;
- bool buffer_initial;
- int rwflags;
- int sd;
- char *jfn;
+ bool defined;
+ struct proxy_connection *next;
+ struct proxy_connection *counterpart;
+ struct buffer buf;
+ bool buffer_initial;
+ int rwflags;
+ int sd;
+ char *jfn;
};
#if 0
static const char *
-headc (const struct buffer *buf)
+headc(const struct buffer *buf)
{
- static char foo[16];
- strncpy (foo, BSTR(buf), 15);
- foo[15] = 0;
- return foo;
+ static char foo[16];
+ strncpy(foo, BSTR(buf), 15);
+ foo[15] = 0;
+ return foo;
}
#endif
static inline void
-close_socket_if_defined (const socket_descriptor_t sd)
+close_socket_if_defined(const socket_descriptor_t sd)
{
- if (socket_defined (sd))
- openvpn_close_socket (sd);
+ if (socket_defined(sd))
+ {
+ openvpn_close_socket(sd);
+ }
}
/*
@@ -107,14 +109,16 @@ close_socket_if_defined (const socket_descriptor_t sd)
* fds from crossing a fork().
*/
static void
-close_fds_except (int keep)
+close_fds_except(int keep)
{
- socket_descriptor_t i;
- closelog ();
- for (i = 3; i <= 100; ++i)
+ socket_descriptor_t i;
+ closelog();
+ for (i = 3; i <= 100; ++i)
{
- if (i != keep)
- openvpn_close_socket (i);
+ if (i != keep)
+ {
+ openvpn_close_socket(i);
+ }
}
}
@@ -123,15 +127,15 @@ close_fds_except (int keep)
* deal with them.
*/
static void
-set_signals (void)
+set_signals(void)
{
- signal (SIGTERM, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
- signal (SIGINT, SIG_IGN);
- signal (SIGHUP, SIG_IGN);
- signal (SIGUSR1, SIG_IGN);
- signal (SIGUSR2, SIG_IGN);
- signal (SIGPIPE, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGUSR1, SIG_IGN);
+ signal(SIGUSR2, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
}
/*
@@ -139,33 +143,39 @@ set_signals (void)
*/
static int
-recv_control (const socket_descriptor_t fd)
+recv_control(const socket_descriptor_t fd)
{
- unsigned char c;
- const ssize_t size = read (fd, &c, sizeof (c));
- if (size == sizeof (c))
- return c;
- else
+ unsigned char c;
+ const ssize_t size = read(fd, &c, sizeof(c));
+ if (size == sizeof(c))
+ {
+ return c;
+ }
+ else
{
- return -1;
+ return -1;
}
}
static int
-send_control (const socket_descriptor_t fd, int code)
+send_control(const socket_descriptor_t fd, int code)
{
- unsigned char c = (unsigned char) code;
- const ssize_t size = write (fd, &c, sizeof (c));
- if (size == sizeof (c))
- return (int) size;
- else
- return -1;
+ unsigned char c = (unsigned char) code;
+ const ssize_t size = write(fd, &c, sizeof(c));
+ if (size == sizeof(c))
+ {
+ return (int) size;
+ }
+ else
+ {
+ return -1;
+ }
}
static int
-cmsg_size ()
+cmsg_size()
{
- return CMSG_SPACE(sizeof(socket_descriptor_t));
+ return CMSG_SPACE(sizeof(socket_descriptor_t));
}
/*
@@ -176,83 +186,87 @@ cmsg_size ()
* send commands, data, and file descriptors to the background process.
*/
static void
-port_share_sendmsg (const socket_descriptor_t sd,
- const char command,
- const struct buffer *head,
- const socket_descriptor_t sd_send)
+port_share_sendmsg(const socket_descriptor_t sd,
+ const char command,
+ const struct buffer *head,
+ const socket_descriptor_t sd_send)
{
- if (socket_defined (sd))
- {
- struct msghdr mesg;
- struct cmsghdr* h;
- struct iovec iov[2];
- socket_descriptor_t sd_null[2] = { SOCKET_UNDEFINED, SOCKET_UNDEFINED };
- char cmd;
- ssize_t status;
-
- dmsg (D_PS_PROXY_DEBUG, "PORT SHARE: sendmsg sd=%d len=%d",
- (int)sd_send,
- head ? BLEN(head) : -1);
-
- CLEAR (mesg);
-
- cmd = command;
-
- iov[0].iov_base = &cmd;
- iov[0].iov_len = sizeof (cmd);
- mesg.msg_iovlen = 1;
-
- if (head)
- {
- iov[1].iov_base = BPTR (head);
- iov[1].iov_len = BLEN (head);
- mesg.msg_iovlen = 2;
- }
-
- mesg.msg_iov = iov;
-
- mesg.msg_controllen = cmsg_size ();
- mesg.msg_control = (char *) malloc (mesg.msg_controllen);
- check_malloc_return (mesg.msg_control);
- mesg.msg_flags = 0;
-
- h = CMSG_FIRSTHDR(&mesg);
- h->cmsg_level = SOL_SOCKET;
- h->cmsg_type = SCM_RIGHTS;
- h->cmsg_len = CMSG_LEN(sizeof(socket_descriptor_t));
-
- if (socket_defined (sd_send))
- {
- memcpy (CMSG_DATA(h), &sd_send, sizeof (sd_send));
- }
- else
- {
- socketpair (PF_UNIX, SOCK_DGRAM, 0, sd_null);
- memcpy (CMSG_DATA(h), &sd_null[0], sizeof (sd_null[0]));
- }
-
- status = sendmsg (sd, &mesg, MSG_NOSIGNAL);
- if (status == -1)
- msg (M_WARN|M_ERRNO, "PORT SHARE: sendmsg failed -- unable to communicate with background process (%d,%d,%d,%d)",
- sd, sd_send, sd_null[0], sd_null[1]
- );
-
- close_socket_if_defined (sd_null[0]);
- close_socket_if_defined (sd_null[1]);
- free (mesg.msg_control);
+ if (socket_defined(sd))
+ {
+ struct msghdr mesg;
+ struct cmsghdr *h;
+ struct iovec iov[2];
+ socket_descriptor_t sd_null[2] = { SOCKET_UNDEFINED, SOCKET_UNDEFINED };
+ char cmd;
+ ssize_t status;
+
+ dmsg(D_PS_PROXY_DEBUG, "PORT SHARE: sendmsg sd=%d len=%d",
+ (int)sd_send,
+ head ? BLEN(head) : -1);
+
+ CLEAR(mesg);
+
+ cmd = command;
+
+ iov[0].iov_base = &cmd;
+ iov[0].iov_len = sizeof(cmd);
+ mesg.msg_iovlen = 1;
+
+ if (head)
+ {
+ iov[1].iov_base = BPTR(head);
+ iov[1].iov_len = BLEN(head);
+ mesg.msg_iovlen = 2;
+ }
+
+ mesg.msg_iov = iov;
+
+ mesg.msg_controllen = cmsg_size();
+ mesg.msg_control = (char *) malloc(mesg.msg_controllen);
+ check_malloc_return(mesg.msg_control);
+ mesg.msg_flags = 0;
+
+ h = CMSG_FIRSTHDR(&mesg);
+ h->cmsg_level = SOL_SOCKET;
+ h->cmsg_type = SCM_RIGHTS;
+ h->cmsg_len = CMSG_LEN(sizeof(socket_descriptor_t));
+
+ if (socket_defined(sd_send))
+ {
+ memcpy(CMSG_DATA(h), &sd_send, sizeof(sd_send));
+ }
+ else
+ {
+ socketpair(PF_UNIX, SOCK_DGRAM, 0, sd_null);
+ memcpy(CMSG_DATA(h), &sd_null[0], sizeof(sd_null[0]));
+ }
+
+ status = sendmsg(sd, &mesg, MSG_NOSIGNAL);
+ if (status == -1)
+ {
+ msg(M_WARN|M_ERRNO, "PORT SHARE: sendmsg failed -- unable to communicate with background process (%d,%d,%d,%d)",
+ sd, sd_send, sd_null[0], sd_null[1]
+ );
+ }
+
+ close_socket_if_defined(sd_null[0]);
+ close_socket_if_defined(sd_null[1]);
+ free(mesg.msg_control);
}
}
static void
-proxy_entry_close_sd (struct proxy_connection *pc, struct event_set *es)
+proxy_entry_close_sd(struct proxy_connection *pc, struct event_set *es)
{
- if (pc->defined && socket_defined (pc->sd))
+ if (pc->defined && socket_defined(pc->sd))
{
- dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: delete sd=%d", (int)pc->sd);
- if (es)
- event_del (es, pc->sd);
- openvpn_close_socket (pc->sd);
- pc->sd = SOCKET_UNDEFINED;
+ dmsg(D_PS_PROXY_DEBUG, "PORT SHARE PROXY: delete sd=%d", (int)pc->sd);
+ if (es)
+ {
+ event_del(es, pc->sd);
+ }
+ openvpn_close_socket(pc->sd);
+ pc->sd = SOCKET_UNDEFINED;
}
}
@@ -260,24 +274,26 @@ proxy_entry_close_sd (struct proxy_connection *pc, struct event_set *es)
* Mark a proxy entry and its counterpart for close.
*/
static void
-proxy_entry_mark_for_close (struct proxy_connection *pc, struct event_set *es)
+proxy_entry_mark_for_close(struct proxy_connection *pc, struct event_set *es)
{
- if (pc->defined)
- {
- struct proxy_connection *cp = pc->counterpart;
- proxy_entry_close_sd (pc, es);
- free_buf (&pc->buf);
- pc->buffer_initial = false;
- pc->rwflags = 0;
- pc->defined = false;
- if (pc->jfn)
- {
- unlink (pc->jfn);
- free (pc->jfn);
- pc->jfn = NULL;
- }
- if (cp && cp->defined && cp->counterpart == pc)
- proxy_entry_mark_for_close (cp, es);
+ if (pc->defined)
+ {
+ struct proxy_connection *cp = pc->counterpart;
+ proxy_entry_close_sd(pc, es);
+ free_buf(&pc->buf);
+ pc->buffer_initial = false;
+ pc->rwflags = 0;
+ pc->defined = false;
+ if (pc->jfn)
+ {
+ unlink(pc->jfn);
+ free(pc->jfn);
+ pc->jfn = NULL;
+ }
+ if (cp && cp->defined && cp->counterpart == pc)
+ {
+ proxy_entry_mark_for_close(cp, es);
+ }
}
}
@@ -286,28 +302,34 @@ proxy_entry_mark_for_close (struct proxy_connection *pc, struct event_set *es)
* for close.
*/
static void
-proxy_list_housekeeping (struct proxy_connection **list)
+proxy_list_housekeeping(struct proxy_connection **list)
{
- if (list)
- {
- struct proxy_connection *prev = NULL;
- struct proxy_connection *pc = *list;
-
- while (pc)
- {
- struct proxy_connection *next = pc->next;
- if (!pc->defined)
- {
- free (pc);
- if (prev)
- prev->next = next;
- else
- *list = next;
- }
- else
- prev = pc;
- pc = next;
- }
+ if (list)
+ {
+ struct proxy_connection *prev = NULL;
+ struct proxy_connection *pc = *list;
+
+ while (pc)
+ {
+ struct proxy_connection *next = pc->next;
+ if (!pc->defined)
+ {
+ free(pc);
+ if (prev)
+ {
+ prev->next = next;
+ }
+ else
+ {
+ *list = next;
+ }
+ }
+ else
+ {
+ prev = pc;
+ }
+ pc = next;
+ }
}
}
@@ -316,70 +338,72 @@ proxy_list_housekeeping (struct proxy_connection **list)
* the proxy can determine true client origin.
*/
static void
-journal_add (const char *journal_dir, struct proxy_connection *pc, struct proxy_connection *cp)
+journal_add(const char *journal_dir, struct proxy_connection *pc, struct proxy_connection *cp)
{
- struct gc_arena gc = gc_new ();
- struct openvpn_sockaddr from, to;
- socklen_t slen, dlen;
- int fnlen;
- char *jfn;
- int fd;
-
- slen = sizeof(from.addr.sa);
- dlen = sizeof(to.addr.sa);
- if (!getpeername (pc->sd, (struct sockaddr *) &from.addr.sa, &slen)
- && !getsockname (cp->sd, (struct sockaddr *) &to.addr.sa, &dlen))
- {
- const char *f = print_openvpn_sockaddr (&from, &gc);
- const char *t = print_openvpn_sockaddr (&to, &gc);
- fnlen = strlen(journal_dir) + strlen(t) + 2;
- jfn = (char *) malloc(fnlen);
- check_malloc_return (jfn);
- openvpn_snprintf (jfn, fnlen, "%s/%s", journal_dir, t);
- dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: client origin %s -> %s", jfn, f);
- fd = platform_open (jfn, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP);
- if (fd != -1)
- {
- if (write(fd, f, strlen(f)) != strlen(f))
- msg(M_WARN, "PORT SHARE: writing to journal file (%s) failed", jfn);
- close (fd);
- cp->jfn = jfn;
- }
- else
- {
- msg (M_WARN|M_ERRNO, "PORT SHARE: unable to write journal file in %s", jfn);
- free (jfn);
- }
- }
- gc_free (&gc);
+ struct gc_arena gc = gc_new();
+ struct openvpn_sockaddr from, to;
+ socklen_t slen, dlen;
+ int fnlen;
+ char *jfn;
+ int fd;
+
+ slen = sizeof(from.addr.sa);
+ dlen = sizeof(to.addr.sa);
+ if (!getpeername(pc->sd, (struct sockaddr *) &from.addr.sa, &slen)
+ && !getsockname(cp->sd, (struct sockaddr *) &to.addr.sa, &dlen))
+ {
+ const char *f = print_openvpn_sockaddr(&from, &gc);
+ const char *t = print_openvpn_sockaddr(&to, &gc);
+ fnlen = strlen(journal_dir) + strlen(t) + 2;
+ jfn = (char *) malloc(fnlen);
+ check_malloc_return(jfn);
+ openvpn_snprintf(jfn, fnlen, "%s/%s", journal_dir, t);
+ dmsg(D_PS_PROXY_DEBUG, "PORT SHARE PROXY: client origin %s -> %s", jfn, f);
+ fd = platform_open(jfn, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP);
+ if (fd != -1)
+ {
+ if (write(fd, f, strlen(f)) != strlen(f))
+ {
+ msg(M_WARN, "PORT SHARE: writing to journal file (%s) failed", jfn);
+ }
+ close(fd);
+ cp->jfn = jfn;
+ }
+ else
+ {
+ msg(M_WARN|M_ERRNO, "PORT SHARE: unable to write journal file in %s", jfn);
+ free(jfn);
+ }
+ }
+ gc_free(&gc);
}
/*
* Cleanup function, on proxy process exit.
*/
static void
-proxy_list_close (struct proxy_connection **list)
+proxy_list_close(struct proxy_connection **list)
{
- if (list)
+ if (list)
{
- struct proxy_connection *pc = *list;
- while (pc)
- {
- proxy_entry_mark_for_close (pc, NULL);
- pc = pc->next;
- }
- proxy_list_housekeeping (list);
+ struct proxy_connection *pc = *list;
+ while (pc)
+ {
+ proxy_entry_mark_for_close(pc, NULL);
+ pc = pc->next;
+ }
+ proxy_list_housekeeping(list);
}
}
static inline void
-proxy_connection_io_requeue (struct proxy_connection *pc, const int rwflags_new, struct event_set *es)
+proxy_connection_io_requeue(struct proxy_connection *pc, const int rwflags_new, struct event_set *es)
{
- if (socket_defined (pc->sd) && pc->rwflags != rwflags_new)
+ if (socket_defined(pc->sd) && pc->rwflags != rwflags_new)
{
- /*dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: requeue[%d] rwflags=%d", (int)pc->sd, rwflags_new);*/
- event_ctl (es, pc->sd, rwflags_new, (void*)pc);
- pc->rwflags = rwflags_new;
+ /*dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: requeue[%d] rwflags=%d", (int)pc->sd, rwflags_new);*/
+ event_ctl(es, pc->sd, rwflags_new, (void *)pc);
+ pc->rwflags = rwflags_new;
}
}
@@ -391,72 +415,74 @@ proxy_connection_io_requeue (struct proxy_connection *pc, const int rwflags_new,
* on success and false on failure to connect to server.
*/
static bool
-proxy_entry_new (struct proxy_connection **list,
- struct event_set *es,
- const struct sockaddr_in server_addr,
- const socket_descriptor_t sd_client,
- struct buffer *initial_data,
- const char *journal_dir)
+proxy_entry_new(struct proxy_connection **list,
+ struct event_set *es,
+ const struct sockaddr_in server_addr,
+ const socket_descriptor_t sd_client,
+ struct buffer *initial_data,
+ const char *journal_dir)
{
- socket_descriptor_t sd_server;
- int status;
- struct proxy_connection *pc;
- struct proxy_connection *cp;
-
- /* connect to port share server */
- if ((sd_server = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
- {
- msg (M_WARN|M_ERRNO, "PORT SHARE PROXY: cannot create socket");
- return false;
- }
- status = openvpn_connect (sd_server,(const struct sockaddr*) &server_addr, 5, NULL);
- if (status)
- {
- msg (M_WARN, "PORT SHARE PROXY: connect to port-share server failed");
- openvpn_close_socket (sd_server);
- return false;
- }
- dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: connect to port-share server succeeded");
-
- set_nonblock (sd_client);
- set_nonblock (sd_server);
-
- /* allocate 2 new proxy_connection objects */
- ALLOC_OBJ_CLEAR (pc, struct proxy_connection);
- ALLOC_OBJ_CLEAR (cp, struct proxy_connection);
-
- /* client object */
- pc->defined = true;
- pc->next = cp;
- pc->counterpart = cp;
- pc->buf = *initial_data;
- pc->buffer_initial = true;
- pc->rwflags = EVENT_UNDEF;
- pc->sd = sd_client;
-
- /* server object */
- cp->defined = true;
- cp->next = *list;
- cp->counterpart = pc;
- cp->buf = alloc_buf (PROXY_CONNECTION_BUFFER_SIZE);
- cp->buffer_initial = false;
- cp->rwflags = EVENT_UNDEF;
- cp->sd = sd_server;
-
- /* add to list */
- *list = pc;
-
- /* add journal entry */
- if (journal_dir)
- journal_add (journal_dir, pc, cp);
-
- dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: NEW CONNECTION [c=%d s=%d]", (int)sd_client, (int)sd_server);
-
- /* set initial i/o states */
- proxy_connection_io_requeue (pc, EVENT_READ, es);
- proxy_connection_io_requeue (cp, EVENT_READ|EVENT_WRITE, es);
-
- return true;
+ socket_descriptor_t sd_server;
+ int status;
+ struct proxy_connection *pc;
+ struct proxy_connection *cp;
+
+ /* connect to port share server */
+ if ((sd_server = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
+ {
+ msg(M_WARN|M_ERRNO, "PORT SHARE PROXY: cannot create socket");
+ return false;
+ }
+ status = openvpn_connect(sd_server,(const struct sockaddr *) &server_addr, 5, NULL);
+ if (status)
+ {
+ msg(M_WARN, "PORT SHARE PROXY: connect to port-share server failed");
+ openvpn_close_socket(sd_server);
+ return false;
+ }
+ dmsg(D_PS_PROXY_DEBUG, "PORT SHARE PROXY: connect to port-share server succeeded");
+
+ set_nonblock(sd_client);
+ set_nonblock(sd_server);
+
+ /* allocate 2 new proxy_connection objects */
+ ALLOC_OBJ_CLEAR(pc, struct proxy_connection);
+ ALLOC_OBJ_CLEAR(cp, struct proxy_connection);
+
+ /* client object */
+ pc->defined = true;
+ pc->next = cp;
+ pc->counterpart = cp;
+ pc->buf = *initial_data;
+ pc->buffer_initial = true;
+ pc->rwflags = EVENT_UNDEF;
+ pc->sd = sd_client;
+
+ /* server object */
+ cp->defined = true;
+ cp->next = *list;
+ cp->counterpart = pc;
+ cp->buf = alloc_buf(PROXY_CONNECTION_BUFFER_SIZE);
+ cp->buffer_initial = false;
+ cp->rwflags = EVENT_UNDEF;
+ cp->sd = sd_server;
+
+ /* add to list */
+ *list = pc;
+
+ /* add journal entry */
+ if (journal_dir)
+ {
+ journal_add(journal_dir, pc, cp);
+ }
+
+ dmsg(D_PS_PROXY_DEBUG, "PORT SHARE PROXY: NEW CONNECTION [c=%d s=%d]", (int)sd_client, (int)sd_server);
+
+ /* set initial i/o states */
+ proxy_connection_io_requeue(pc, EVENT_READ, es);
+ proxy_connection_io_requeue(cp, EVENT_READ|EVENT_WRITE, es);
+
+ return true;
}
/*
@@ -466,146 +492,148 @@ proxy_entry_new (struct proxy_connection **list,
* exit, true otherwise.
*/
static bool
-control_message_from_parent (const socket_descriptor_t sd_control,
- struct proxy_connection **list,
- struct event_set *es,
- const struct sockaddr_in server_addr,
- const int max_initial_buf,
- const char *journal_dir)
+control_message_from_parent(const socket_descriptor_t sd_control,
+ struct proxy_connection **list,
+ struct event_set *es,
+ const struct sockaddr_in server_addr,
+ const int max_initial_buf,
+ const char *journal_dir)
{
- /* this buffer needs to be large enough to handle the largest buffer
- that might be returned by the link_socket_read call in read_incoming_link. */
- struct buffer buf = alloc_buf (max_initial_buf);
-
- struct msghdr mesg;
- struct cmsghdr* h;
- struct iovec iov[2];
- char command = 0;
- ssize_t status;
- int ret = true;
-
- CLEAR (mesg);
-
- iov[0].iov_base = &command;
- iov[0].iov_len = sizeof (command);
- iov[1].iov_base = BPTR (&buf);
- iov[1].iov_len = BCAP (&buf);
- mesg.msg_iov = iov;
- mesg.msg_iovlen = 2;
-
- mesg.msg_controllen = cmsg_size ();
- mesg.msg_control = (char *) malloc (mesg.msg_controllen);
- check_malloc_return (mesg.msg_control);
- mesg.msg_flags = 0;
-
- h = CMSG_FIRSTHDR(&mesg);
- h->cmsg_len = CMSG_LEN(sizeof(socket_descriptor_t));
- h->cmsg_level = SOL_SOCKET;
- h->cmsg_type = SCM_RIGHTS;
- static const socket_descriptor_t socket_undefined = SOCKET_UNDEFINED;
- memcpy (CMSG_DATA(h), &socket_undefined, sizeof(socket_undefined));
-
- status = recvmsg (sd_control, &mesg, MSG_NOSIGNAL);
- if (status != -1)
- {
- if ( h == NULL
- || h->cmsg_len != CMSG_LEN(sizeof(socket_descriptor_t))
- || h->cmsg_level != SOL_SOCKET
- || h->cmsg_type != SCM_RIGHTS )
- {
- msg (M_WARN, "PORT SHARE PROXY: received unknown message");
- }
- else
- {
- socket_descriptor_t received_fd;
- memcpy (&received_fd, CMSG_DATA(h), sizeof(received_fd));
- dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: RECEIVED sd=%d", (int)received_fd);
-
- if (status >= 2 && command == COMMAND_REDIRECT)
- {
- buf.len = status - 1;
- if (proxy_entry_new (list,
- es,
- server_addr,
- received_fd,
- &buf,
- journal_dir))
- {
- CLEAR (buf); /* we gave the buffer to proxy_entry_new */
- }
- else
- {
- openvpn_close_socket (received_fd);
- }
- }
- else if (status >= 1 && command == COMMAND_EXIT)
- {
- dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: RECEIVED COMMAND_EXIT");
- openvpn_close_socket (received_fd); /* null socket */
- ret = false;
- }
- }
- }
- free (mesg.msg_control);
- free_buf (&buf);
- return ret;
+ /* this buffer needs to be large enough to handle the largest buffer
+ * that might be returned by the link_socket_read call in read_incoming_link. */
+ struct buffer buf = alloc_buf(max_initial_buf);
+
+ struct msghdr mesg;
+ struct cmsghdr *h;
+ struct iovec iov[2];
+ char command = 0;
+ ssize_t status;
+ int ret = true;
+
+ CLEAR(mesg);
+
+ iov[0].iov_base = &command;
+ iov[0].iov_len = sizeof(command);
+ iov[1].iov_base = BPTR(&buf);
+ iov[1].iov_len = BCAP(&buf);
+ mesg.msg_iov = iov;
+ mesg.msg_iovlen = 2;
+
+ mesg.msg_controllen = cmsg_size();
+ mesg.msg_control = (char *) malloc(mesg.msg_controllen);
+ check_malloc_return(mesg.msg_control);
+ mesg.msg_flags = 0;
+
+ h = CMSG_FIRSTHDR(&mesg);
+ h->cmsg_len = CMSG_LEN(sizeof(socket_descriptor_t));
+ h->cmsg_level = SOL_SOCKET;
+ h->cmsg_type = SCM_RIGHTS;
+ static const socket_descriptor_t socket_undefined = SOCKET_UNDEFINED;
+ memcpy(CMSG_DATA(h), &socket_undefined, sizeof(socket_undefined));
+
+ status = recvmsg(sd_control, &mesg, MSG_NOSIGNAL);
+ if (status != -1)
+ {
+ if (h == NULL
+ || h->cmsg_len != CMSG_LEN(sizeof(socket_descriptor_t))
+ || h->cmsg_level != SOL_SOCKET
+ || h->cmsg_type != SCM_RIGHTS)
+ {
+ msg(M_WARN, "PORT SHARE PROXY: received unknown message");
+ }
+ else
+ {
+ socket_descriptor_t received_fd;
+ memcpy(&received_fd, CMSG_DATA(h), sizeof(received_fd));
+ dmsg(D_PS_PROXY_DEBUG, "PORT SHARE PROXY: RECEIVED sd=%d", (int)received_fd);
+
+ if (status >= 2 && command == COMMAND_REDIRECT)
+ {
+ buf.len = status - 1;
+ if (proxy_entry_new(list,
+ es,
+ server_addr,
+ received_fd,
+ &buf,
+ journal_dir))
+ {
+ CLEAR(buf); /* we gave the buffer to proxy_entry_new */
+ }
+ else
+ {
+ openvpn_close_socket(received_fd);
+ }
+ }
+ else if (status >= 1 && command == COMMAND_EXIT)
+ {
+ dmsg(D_PS_PROXY_DEBUG, "PORT SHARE PROXY: RECEIVED COMMAND_EXIT");
+ openvpn_close_socket(received_fd); /* null socket */
+ ret = false;
+ }
+ }
+ }
+ free(mesg.msg_control);
+ free_buf(&buf);
+ return ret;
}
static int
-proxy_connection_io_recv (struct proxy_connection *pc)
+proxy_connection_io_recv(struct proxy_connection *pc)
{
- /* recv data from socket */
- const int status = recv (pc->sd, BPTR(&pc->buf), BCAP(&pc->buf), MSG_NOSIGNAL);
- if (status < 0)
+ /* recv data from socket */
+ const int status = recv(pc->sd, BPTR(&pc->buf), BCAP(&pc->buf), MSG_NOSIGNAL);
+ if (status < 0)
{
- return (errno == EAGAIN) ? IOSTAT_EAGAIN_ON_READ : IOSTAT_READ_ERROR;
+ return (errno == EAGAIN) ? IOSTAT_EAGAIN_ON_READ : IOSTAT_READ_ERROR;
}
- else
+ else
{
- if (!status)
- return IOSTAT_READ_ERROR;
- dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: read[%d] %d", (int)pc->sd, status);
- pc->buf.len = status;
+ if (!status)
+ {
+ return IOSTAT_READ_ERROR;
+ }
+ dmsg(D_PS_PROXY_DEBUG, "PORT SHARE PROXY: read[%d] %d", (int)pc->sd, status);
+ pc->buf.len = status;
}
- return IOSTAT_GOOD;
+ return IOSTAT_GOOD;
}
static int
-proxy_connection_io_send (struct proxy_connection *pc, int *bytes_sent)
+proxy_connection_io_send(struct proxy_connection *pc, int *bytes_sent)
{
- const socket_descriptor_t sd = pc->counterpart->sd;
- const int status = send (sd, BPTR(&pc->buf), BLEN(&pc->buf), MSG_NOSIGNAL);
+ const socket_descriptor_t sd = pc->counterpart->sd;
+ const int status = send(sd, BPTR(&pc->buf), BLEN(&pc->buf), MSG_NOSIGNAL);
- if (status < 0)
+ if (status < 0)
{
- const int e = errno;
- return (e == EAGAIN) ? IOSTAT_EAGAIN_ON_WRITE : IOSTAT_WRITE_ERROR;
+ const int e = errno;
+ return (e == EAGAIN) ? IOSTAT_EAGAIN_ON_WRITE : IOSTAT_WRITE_ERROR;
}
- else
+ else
{
- *bytes_sent += status;
- if (status != pc->buf.len)
- {
- dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: partial write[%d], tried=%d got=%d", (int)sd, pc->buf.len, status);
- buf_advance (&pc->buf, status);
- return IOSTAT_EAGAIN_ON_WRITE;
- }
- else
- {
- dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: wrote[%d] %d", (int)sd, status);
- pc->buf.len = 0;
- pc->buf.offset = 0;
- }
+ *bytes_sent += status;
+ if (status != pc->buf.len)
+ {
+ dmsg(D_PS_PROXY_DEBUG, "PORT SHARE PROXY: partial write[%d], tried=%d got=%d", (int)sd, pc->buf.len, status);
+ buf_advance(&pc->buf, status);
+ return IOSTAT_EAGAIN_ON_WRITE;
+ }
+ else
+ {
+ dmsg(D_PS_PROXY_DEBUG, "PORT SHARE PROXY: wrote[%d] %d", (int)sd, status);
+ pc->buf.len = 0;
+ pc->buf.offset = 0;
+ }
}
- /* realloc send buffer after initial send */
- if (pc->buffer_initial)
+ /* realloc send buffer after initial send */
+ if (pc->buffer_initial)
{
- free_buf (&pc->buf);
- pc->buf = alloc_buf (PROXY_CONNECTION_BUFFER_SIZE);
- pc->buffer_initial = false;
+ free_buf(&pc->buf);
+ pc->buf = alloc_buf(PROXY_CONNECTION_BUFFER_SIZE);
+ pc->buffer_initial = false;
}
- return IOSTAT_GOOD;
+ return IOSTAT_GOOD;
}
/*
@@ -613,52 +641,60 @@ proxy_connection_io_send (struct proxy_connection *pc, int *bytes_sent)
*/
static int
-proxy_connection_io_xfer (struct proxy_connection *pc, const int max_transfer)
+proxy_connection_io_xfer(struct proxy_connection *pc, const int max_transfer)
{
- int transferred = 0;
- while (transferred < max_transfer)
- {
- if (!BLEN (&pc->buf))
- {
- const int status = proxy_connection_io_recv (pc);
- if (status != IOSTAT_GOOD)
- return status;
- }
-
- if (BLEN (&pc->buf))
- {
- const int status = proxy_connection_io_send (pc, &transferred);
- if (status != IOSTAT_GOOD)
- return status;
- }
- }
- return IOSTAT_EAGAIN_ON_READ;
+ int transferred = 0;
+ while (transferred < max_transfer)
+ {
+ if (!BLEN(&pc->buf))
+ {
+ const int status = proxy_connection_io_recv(pc);
+ if (status != IOSTAT_GOOD)
+ {
+ return status;
+ }
+ }
+
+ if (BLEN(&pc->buf))
+ {
+ const int status = proxy_connection_io_send(pc, &transferred);
+ if (status != IOSTAT_GOOD)
+ {
+ return status;
+ }
+ }
+ }
+ return IOSTAT_EAGAIN_ON_READ;
}
/*
* Decide how the receipt of an EAGAIN status should affect our next IO queueing.
*/
static bool
-proxy_connection_io_status (const int status, int *rwflags_pc, int *rwflags_cp)
+proxy_connection_io_status(const int status, int *rwflags_pc, int *rwflags_cp)
{
- switch (status)
- {
- case IOSTAT_EAGAIN_ON_READ:
- *rwflags_pc |= EVENT_READ;
- *rwflags_cp &= ~EVENT_WRITE;
- return true;
- case IOSTAT_EAGAIN_ON_WRITE:
- *rwflags_pc &= ~EVENT_READ;
- *rwflags_cp |= EVENT_WRITE;
- return true;
- case IOSTAT_READ_ERROR:
- return false;
- case IOSTAT_WRITE_ERROR:
- return false;
- default:
- msg (M_FATAL, "PORT SHARE PROXY: unexpected status=%d", status);
- }
- return false; /* NOTREACHED */
+ switch (status)
+ {
+ case IOSTAT_EAGAIN_ON_READ:
+ *rwflags_pc |= EVENT_READ;
+ *rwflags_cp &= ~EVENT_WRITE;
+ return true;
+
+ case IOSTAT_EAGAIN_ON_WRITE:
+ *rwflags_pc &= ~EVENT_READ;
+ *rwflags_cp |= EVENT_WRITE;
+ return true;
+
+ case IOSTAT_READ_ERROR:
+ return false;
+
+ case IOSTAT_WRITE_ERROR:
+ return false;
+
+ default:
+ msg(M_FATAL, "PORT SHARE PROXY: unexpected status=%d", status);
+ }
+ return false; /* NOTREACHED */
}
/*
@@ -666,107 +702,115 @@ proxy_connection_io_status (const int status, int *rwflags_pc, int *rwflags_cp)
* in the proxied connection.
*/
static int
-proxy_connection_io_dispatch (struct proxy_connection *pc,
- const int rwflags,
- struct event_set *es)
+proxy_connection_io_dispatch(struct proxy_connection *pc,
+ const int rwflags,
+ struct event_set *es)
{
- const int max_transfer_per_iteration = 10000;
- struct proxy_connection *cp = pc->counterpart;
- int rwflags_pc = pc->rwflags;
- int rwflags_cp = cp->rwflags;
+ const int max_transfer_per_iteration = 10000;
+ struct proxy_connection *cp = pc->counterpart;
+ int rwflags_pc = pc->rwflags;
+ int rwflags_cp = cp->rwflags;
- ASSERT(pc->defined && cp->defined && cp->counterpart == pc);
+ ASSERT(pc->defined && cp->defined && cp->counterpart == pc);
- if (rwflags & EVENT_READ)
+ if (rwflags & EVENT_READ)
{
- const int status = proxy_connection_io_xfer (pc, max_transfer_per_iteration);
- if (!proxy_connection_io_status (status, &rwflags_pc, &rwflags_cp))
- goto bad;
+ const int status = proxy_connection_io_xfer(pc, max_transfer_per_iteration);
+ if (!proxy_connection_io_status(status, &rwflags_pc, &rwflags_cp))
+ {
+ goto bad;
+ }
}
- if (rwflags & EVENT_WRITE)
+ if (rwflags & EVENT_WRITE)
{
- const int status = proxy_connection_io_xfer (cp, max_transfer_per_iteration);
- if (!proxy_connection_io_status (status, &rwflags_cp, &rwflags_pc))
- goto bad;
+ const int status = proxy_connection_io_xfer(cp, max_transfer_per_iteration);
+ if (!proxy_connection_io_status(status, &rwflags_cp, &rwflags_pc))
+ {
+ goto bad;
+ }
}
- proxy_connection_io_requeue (pc, rwflags_pc, es);
- proxy_connection_io_requeue (cp, rwflags_cp, es);
+ proxy_connection_io_requeue(pc, rwflags_pc, es);
+ proxy_connection_io_requeue(cp, rwflags_cp, es);
- return true;
+ return true;
- bad:
- proxy_entry_mark_for_close (pc, es);
- return false;
+bad:
+ proxy_entry_mark_for_close(pc, es);
+ return false;
}
/*
* This is the main function for the port share proxy background process.
*/
static void
-port_share_proxy (const struct sockaddr_in hostaddr,
- const socket_descriptor_t sd_control,
- const int max_initial_buf,
- const char *journal_dir)
+port_share_proxy(const struct sockaddr_in hostaddr,
+ const socket_descriptor_t sd_control,
+ const int max_initial_buf,
+ const char *journal_dir)
{
- if (send_control (sd_control, RESPONSE_INIT_SUCCEEDED) >= 0)
- {
- void *sd_control_marker = (void *)1;
- int maxevents = 256;
- struct event_set *es;
- struct event_set_return esr[64];
- struct proxy_connection *list = NULL;
- time_t last_housekeeping = 0;
-
- msg (D_PS_PROXY, "PORT SHARE PROXY: proxy starting");
-
- es = event_set_init (&maxevents, 0);
- event_ctl (es, sd_control, EVENT_READ, sd_control_marker);
- while (true)
- {
- int n_events;
- struct timeval tv;
- time_t current;
-
- tv.tv_sec = 10;
- tv.tv_usec = 0;
- n_events = event_wait (es, &tv, esr, SIZE(esr));
- /*dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: event_wait returned %d", n_events);*/
- current = time(NULL);
- if (n_events > 0)
- {
- int i;
- for (i = 0; i < n_events; ++i)
- {
- const struct event_set_return *e = &esr[i];
- if (e->arg == sd_control_marker)
- {
- if (!control_message_from_parent (sd_control, &list, es, hostaddr, max_initial_buf, journal_dir))
- goto done;
- }
- else
- {
- struct proxy_connection *pc = (struct proxy_connection *)e->arg;
- if (pc->defined)
- proxy_connection_io_dispatch (pc, e->rwflags, es);
- }
- }
- }
- else if (n_events < 0)
- {
- dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: event_wait failed");
- }
- if (current > last_housekeeping)
- {
- proxy_list_housekeeping (&list);
- last_housekeeping = current;
- }
- }
-
- done:
- proxy_list_close (&list);
- event_free (es);
- }
- msg (M_INFO, "PORT SHARE PROXY: proxy exiting");
+ if (send_control(sd_control, RESPONSE_INIT_SUCCEEDED) >= 0)
+ {
+ void *sd_control_marker = (void *)1;
+ int maxevents = 256;
+ struct event_set *es;
+ struct event_set_return esr[64];
+ struct proxy_connection *list = NULL;
+ time_t last_housekeeping = 0;
+
+ msg(D_PS_PROXY, "PORT SHARE PROXY: proxy starting");
+
+ es = event_set_init(&maxevents, 0);
+ event_ctl(es, sd_control, EVENT_READ, sd_control_marker);
+ while (true)
+ {
+ int n_events;
+ struct timeval tv;
+ time_t current;
+
+ tv.tv_sec = 10;
+ tv.tv_usec = 0;
+ n_events = event_wait(es, &tv, esr, SIZE(esr));
+ /*dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: event_wait returned %d", n_events);*/
+ current = time(NULL);
+ if (n_events > 0)
+ {
+ int i;
+ for (i = 0; i < n_events; ++i)
+ {
+ const struct event_set_return *e = &esr[i];
+ if (e->arg == sd_control_marker)
+ {
+ if (!control_message_from_parent(sd_control, &list, es, hostaddr, max_initial_buf, journal_dir))
+ {
+ goto done;
+ }
+ }
+ else
+ {
+ struct proxy_connection *pc = (struct proxy_connection *)e->arg;
+ if (pc->defined)
+ {
+ proxy_connection_io_dispatch(pc, e->rwflags, es);
+ }
+ }
+ }
+ }
+ else if (n_events < 0)
+ {
+ dmsg(D_PS_PROXY_DEBUG, "PORT SHARE PROXY: event_wait failed");
+ }
+ if (current > last_housekeeping)
+ {
+ proxy_list_housekeeping(&list);
+ last_housekeeping = current;
+ }
+ }
+
+done:
+ proxy_list_close(&list);
+ event_free(es);
+ }
+ msg(M_INFO, "PORT SHARE PROXY: proxy exiting");
}
/*
@@ -774,155 +818,157 @@ port_share_proxy (const struct sockaddr_in hostaddr,
* share proxy.
*/
struct port_share *
-port_share_open (const char *host,
- const char *port,
- const int max_initial_buf,
- const char *journal_dir)
+port_share_open(const char *host,
+ const char *port,
+ const int max_initial_buf,
+ const char *journal_dir)
{
- pid_t pid;
- socket_descriptor_t fd[2];
- struct sockaddr_in hostaddr;
- struct port_share *ps;
- int status;
- struct addrinfo* ai;
-
- ALLOC_OBJ_CLEAR (ps, struct port_share);
- ps->foreground_fd = -1;
- ps->background_pid = -1;
-
- /*
- * Get host's IP address
- */
-
- status = openvpn_getaddrinfo (GETADDR_RESOLVE|GETADDR_FATAL,
+ pid_t pid;
+ socket_descriptor_t fd[2];
+ struct sockaddr_in hostaddr;
+ struct port_share *ps;
+ int status;
+ struct addrinfo *ai;
+
+ ALLOC_OBJ_CLEAR(ps, struct port_share);
+ ps->foreground_fd = -1;
+ ps->background_pid = -1;
+
+ /*
+ * Get host's IP address
+ */
+
+ status = openvpn_getaddrinfo(GETADDR_RESOLVE|GETADDR_FATAL,
host, port, 0, NULL, AF_INET, &ai);
- ASSERT (status==0);
- hostaddr = *((struct sockaddr_in*) ai->ai_addr);
- freeaddrinfo(ai);
-
- /*
- * Make a socket for foreground and background processes
- * to communicate.
- */
- if (socketpair (PF_UNIX, SOCK_DGRAM, 0, fd) == -1)
+ ASSERT(status==0);
+ hostaddr = *((struct sockaddr_in *) ai->ai_addr);
+ freeaddrinfo(ai);
+
+ /*
+ * Make a socket for foreground and background processes
+ * to communicate.
+ */
+ if (socketpair(PF_UNIX, SOCK_DGRAM, 0, fd) == -1)
{
- msg (M_WARN, "PORT SHARE: socketpair call failed");
- goto error;
+ msg(M_WARN, "PORT SHARE: socketpair call failed");
+ goto error;
}
- /*
- * Fork off background proxy process.
- */
- pid = fork ();
+ /*
+ * Fork off background proxy process.
+ */
+ pid = fork();
- if (pid)
+ if (pid)
{
- int status;
-
- /*
- * Foreground Process
- */
-
- ps->background_pid = pid;
-
- /* close our copy of child's socket */
- openvpn_close_socket (fd[1]);
-
- /* don't let future subprocesses inherit child socket */
- set_cloexec (fd[0]);
-
- /* wait for background child process to initialize */
- status = recv_control (fd[0]);
- if (status == RESPONSE_INIT_SUCCEEDED)
- {
- /* note that this will cause possible EAGAIN when writing to
- control socket if proxy process is backlogged */
- set_nonblock (fd[0]);
-
- ps->foreground_fd = fd[0];
- return ps;
- }
- else
- {
- msg (M_ERR, "PORT SHARE: unexpected init recv_control status=%d", status);
- }
+ int status;
+
+ /*
+ * Foreground Process
+ */
+
+ ps->background_pid = pid;
+
+ /* close our copy of child's socket */
+ openvpn_close_socket(fd[1]);
+
+ /* don't let future subprocesses inherit child socket */
+ set_cloexec(fd[0]);
+
+ /* wait for background child process to initialize */
+ status = recv_control(fd[0]);
+ if (status == RESPONSE_INIT_SUCCEEDED)
+ {
+ /* note that this will cause possible EAGAIN when writing to
+ * control socket if proxy process is backlogged */
+ set_nonblock(fd[0]);
+
+ ps->foreground_fd = fd[0];
+ return ps;
+ }
+ else
+ {
+ msg(M_ERR, "PORT SHARE: unexpected init recv_control status=%d", status);
+ }
}
- else
+ else
{
- /*
- * Background Process
- */
+ /*
+ * Background Process
+ */
- /* Ignore most signals (the parent will receive them) */
- set_signals ();
+ /* Ignore most signals (the parent will receive them) */
+ set_signals();
- /* Let msg know that we forked */
- msg_forked ();
+ /* Let msg know that we forked */
+ msg_forked();
#ifdef ENABLE_MANAGEMENT
- /* Don't interact with management interface */
- management = NULL;
+ /* Don't interact with management interface */
+ management = NULL;
#endif
- /* close all parent fds except our socket back to parent */
- close_fds_except (fd[1]);
+ /* close all parent fds except our socket back to parent */
+ close_fds_except(fd[1]);
- /* no blocking on control channel back to parent */
- set_nonblock (fd[1]);
+ /* no blocking on control channel back to parent */
+ set_nonblock(fd[1]);
- /* initialize prng */
- prng_init (NULL, 0);
+ /* initialize prng */
+ prng_init(NULL, 0);
- /* execute the event loop */
- port_share_proxy (hostaddr, fd[1], max_initial_buf, journal_dir);
+ /* execute the event loop */
+ port_share_proxy(hostaddr, fd[1], max_initial_buf, journal_dir);
- openvpn_close_socket (fd[1]);
+ openvpn_close_socket(fd[1]);
- exit (0);
- return 0; /* NOTREACHED */
+ exit(0);
+ return 0; /* NOTREACHED */
}
- error:
- port_share_close (ps);
- return NULL;
+error:
+ port_share_close(ps);
+ return NULL;
}
void
-port_share_close (struct port_share *ps)
+port_share_close(struct port_share *ps)
{
- if (ps)
+ if (ps)
{
- if (ps->foreground_fd >= 0)
- {
- /* tell background process to exit */
- port_share_sendmsg (ps->foreground_fd, COMMAND_EXIT, NULL, SOCKET_UNDEFINED);
-
- /* wait for background process to exit */
- dmsg (D_PS_PROXY_DEBUG, "PORT SHARE: waiting for background process to exit");
- if (ps->background_pid > 0)
- waitpid (ps->background_pid, NULL, 0);
- dmsg (D_PS_PROXY_DEBUG, "PORT SHARE: background process exited");
-
- openvpn_close_socket (ps->foreground_fd);
- ps->foreground_fd = -1;
- }
-
- free (ps);
+ if (ps->foreground_fd >= 0)
+ {
+ /* tell background process to exit */
+ port_share_sendmsg(ps->foreground_fd, COMMAND_EXIT, NULL, SOCKET_UNDEFINED);
+
+ /* wait for background process to exit */
+ dmsg(D_PS_PROXY_DEBUG, "PORT SHARE: waiting for background process to exit");
+ if (ps->background_pid > 0)
+ {
+ waitpid(ps->background_pid, NULL, 0);
+ }
+ dmsg(D_PS_PROXY_DEBUG, "PORT SHARE: background process exited");
+
+ openvpn_close_socket(ps->foreground_fd);
+ ps->foreground_fd = -1;
+ }
+
+ free(ps);
}
}
void
-port_share_abort (struct port_share *ps)
+port_share_abort(struct port_share *ps)
{
- if (ps)
+ if (ps)
{
- /* tell background process to exit */
- if (ps->foreground_fd >= 0)
- {
- send_control (ps->foreground_fd, COMMAND_EXIT);
- openvpn_close_socket (ps->foreground_fd);
- ps->foreground_fd = -1;
- }
+ /* tell background process to exit */
+ if (ps->foreground_fd >= 0)
+ {
+ send_control(ps->foreground_fd, COMMAND_EXIT);
+ openvpn_close_socket(ps->foreground_fd);
+ ps->foreground_fd = -1;
+ }
}
}
@@ -932,22 +978,24 @@ port_share_abort (struct port_share *ps)
* client attempting to connect with an OpenVPN server.
*/
bool
-is_openvpn_protocol (const struct buffer *buf)
+is_openvpn_protocol(const struct buffer *buf)
{
- const unsigned char *p = (const unsigned char *) BSTR (buf);
- const int len = BLEN (buf);
- if (len >= 3)
+ const unsigned char *p = (const unsigned char *) BSTR(buf);
+ const int len = BLEN(buf);
+ if (len >= 3)
{
- return p[0] == 0
- && p[1] >= 14
- && p[2] == (P_CONTROL_HARD_RESET_CLIENT_V2<<P_OPCODE_SHIFT);
+ return p[0] == 0
+ && p[1] >= 14
+ && p[2] == (P_CONTROL_HARD_RESET_CLIENT_V2<<P_OPCODE_SHIFT);
}
- else if (len >= 2)
+ else if (len >= 2)
{
- return p[0] == 0 && p[1] >= 14;
+ return p[0] == 0 && p[1] >= 14;
+ }
+ else
+ {
+ return true;
}
- else
- return true;
}
/*
@@ -956,12 +1004,12 @@ is_openvpn_protocol (const struct buffer *buf)
* call.
*/
void
-port_share_redirect (struct port_share *ps, const struct buffer *head, socket_descriptor_t sd)
+port_share_redirect(struct port_share *ps, const struct buffer *head, socket_descriptor_t sd)
{
- if (ps)
+ if (ps)
{
- port_share_sendmsg (ps->foreground_fd, COMMAND_REDIRECT, head, sd);
+ port_share_sendmsg(ps->foreground_fd, COMMAND_REDIRECT, head, sd);
}
}
-#endif
+#endif /* if PORT_SHARE */