---
 src/openvpn/manage.c |   88 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/openvpn/manage.h |    4 +++
 2 files changed, 92 insertions(+)

diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c
index 0a4542a..c4e6fe5 100644
--- a/src/openvpn/manage.c
+++ b/src/openvpn/manage.c
@@ -1779,6 +1779,79 @@ man_io_error (struct management *man, const char *prefix)
     return false;
 }

+#ifdef TARGET_ANDROID
+static ssize_t write_fd (int fd, void *ptr, size_t nbytes, int flags, int 
sendfd)
+{
+    struct msghdr msg;
+    struct iovec iov[1];
+    
+    union {
+        struct cmsghdr cm;
+        char    control[CMSG_SPACE(sizeof(int))];
+    } control_un;
+    struct cmsghdr *cmptr;
+    
+    msg.msg_control = control_un.control;
+    msg.msg_controllen = sizeof(control_un.control);
+    
+    cmptr = CMSG_FIRSTHDR(&msg);
+    cmptr->cmsg_len = CMSG_LEN(sizeof(int));
+    cmptr->cmsg_level = SOL_SOCKET;
+    cmptr->cmsg_type = SCM_RIGHTS;
+    *((int *) CMSG_DATA(cmptr)) = sendfd;
+    
+    msg.msg_name = NULL;
+    msg.msg_namelen = 0;
+    
+    iov[0].iov_base = ptr;
+    iov[0].iov_len = nbytes;
+    msg.msg_iov = iov;
+    msg.msg_iovlen = 1;
+    
+    return (sendmsg(fd, &msg, flags));
+}
+
+static ssize_t read_fd(int fd, void *ptr, size_t nbytes, int flags, int 
*recvfd)
+{
+    struct msghdr msghdr;
+    struct iovec iov[1];
+    ssize_t n;
+    
+    union {
+        struct cmsghdr cm;
+        char     control[CMSG_SPACE(sizeof (int))];
+    } control_un;
+    struct cmsghdr  *cmptr;
+    
+    msghdr.msg_control  = control_un.control;
+    msghdr.msg_controllen = sizeof(control_un.control);
+    
+    msghdr.msg_name = NULL;
+    msghdr.msg_namelen = 0;
+    
+    iov[0].iov_base = ptr;
+    iov[0].iov_len = nbytes;
+    msghdr.msg_iov = iov;
+    msghdr.msg_iovlen = 1;
+    
+    if ( (n = recvmsg(fd, &msghdr, flags)) <= 0)
+        return (n);
+    
+    if ( (cmptr = CMSG_FIRSTHDR(&msghdr)) != NULL &&
+        cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
+        if (cmptr->cmsg_level != SOL_SOCKET)
+            msg (M_ERR, "control level != SOL_SOCKET");
+        if (cmptr->cmsg_type != SCM_RIGHTS)
+            msg (M_ERR, "control type != SCM_RIGHTS");
+        *recvfd = *((int *) CMSG_DATA(cmptr));
+    } else
+        *recvfd = -1;           /* descriptor was not passed */
+    
+    return (n);
+}
+#endif
+
+
 static int
 man_read (struct management *man)
 {
@@ -1788,7 +1861,15 @@ man_read (struct management *man)
   unsigned char buf[256];
   int len = 0;

+#ifdef TARGET_ANDROID
+  int fd;
+  len = read_fd (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL, &fd);
+  if(fd >= 0) 
+     man->connection.lastfdreceived = fd;
+#else
   len = recv (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL);
+#endif
+
   if (len == 0)
     {
       man_reset_client_socket (man, false);
@@ -1865,6 +1946,13 @@ man_write (struct management *man)
   if (buf && BLEN (buf))
     {
       const int len = min_int (size_hint, BLEN (buf));
+#ifdef TARGET_ANDROID
+      if (man->connection.fdtosend > 0) 
+        {
+         sent = write_fd (man->connection.sd_cli, BPTR (buf), len, 
MSG_NOSIGNAL,man->connection.fdtosend);
+            man->connection.fdtosend = -1;
+        } else
+#endif
       sent = send (man->connection.sd_cli, BPTR (buf), len, MSG_NOSIGNAL);
       if (sent >= 0)
        {
diff --git a/src/openvpn/manage.h b/src/openvpn/manage.h
index 28da69f..eec24a2 100644
--- a/src/openvpn/manage.h
+++ b/src/openvpn/manage.h
@@ -299,6 +299,10 @@ struct man_connection {
 #ifdef MANAGMENT_EXTERNAL_KEY
   struct buffer_list *rsa_sig;
 #endif
+#ifdef TARGET_ANDROID
+    int fdtosend;
+    int lastfdreceived;
+#endif
 };

 struct management
-- 
1.7.9.5


Reply via email to