Andreas Otto wrote:
Dear APR Support Team,

  some time ago I made the strategic decision to port my software:

        http://libmsgque.sourceforge.net/

  to APR by able to use all of the nice features.

  Some days ago I finally start to do this job ... but today I got a massive
  disappointment ...

  You ask why ?

  It's the UNIX Domain Socket issue !!!

  well Unix-Domains are very beautiful in terms of usability

  you only have to create the "sockaddr_un" as part of "sockaddr"
  and you can use the same code you allready written for
  network sockets to use local sockets

  The main advantages are:

        1. 50% faster as network sockets (on linux)
        2. absolute secure -> no network access

 now the problem:

   APR does not support Unix Domain Sockets


Perhaps it will in the future.
Here is a patch that allows to do that.
The apr_sockadr_local_get could be included
inside apr_sockaddr_info_get and use hostname
for filename.

Not sure if some addr functions need some extra
check for AF_UNIX, since they'll probably
fail or return some junk. Nevertheless
I doubt they are useful anyhow for domain sockets.

I've tested the API, and bind/connect/accept
works fine. However probably there will be
needed some unlik callback on bind.

Regards
--
^(TM)
Index: network_io/unix/sockaddr.c
===================================================================
--- network_io/unix/sockaddr.c	(revision 744613)
+++ network_io/unix/sockaddr.c	(working copy)
@@ -1023,3 +1023,27 @@
 #endif /* APR_HAVE_IPV6 */
     return 0; /* no match */
 }
+
+APR_DECLARE(apr_status_t) apr_sockaddr_local_get(apr_sockaddr_t **sa,
+                                                 const char *filename, 
+                                                 apr_pool_t *p)
+{
+#if APR_HAVE_SOCKADDR_UN
+    *sa = apr_pcalloc(p, sizeof(apr_sockaddr_t));
+    (*sa)->pool = p;
+    apr_cpystrn((*sa)->sa.unx.sun_path, filename,
+                sizeof((*sa)->sa.unx.sun_path));
+
+    (*sa)->family = APR_UNIX;
+    (*sa)->sa.sin.sin_family = APR_UNIX;
+    (*sa)->salen = sizeof(struct sockaddr_un);
+    (*sa)->addr_str_len = sizeof((*sa)->sa.unx.sun_path);
+    (*sa)->ipaddr_ptr = &((*sa)->sa.unx.sun_path[0]);
+    (*sa)->ipaddr_len = (*sa)->addr_str_len;
+
+    return APR_SUCCESS;
+#else
+    *sa = NULL;
+    return APR_ENOTIMPL;
+#endif
+}
Index: network_io/unix/sockets.c
===================================================================
--- network_io/unix/sockets.c	(revision 744613)
+++ network_io/unix/sockets.c	(working copy)
@@ -81,9 +81,10 @@
 }
 
 apr_status_t apr_socket_create(apr_socket_t **new, int ofamily, int type,
-                               int protocol, apr_pool_t *cont)
+                               int oprotocol, apr_pool_t *cont)
 {
     int family = ofamily;
+    int protocol = oprotocol;
 
     if (family == APR_UNSPEC) {
 #if APR_HAVE_IPV6
@@ -92,7 +93,11 @@
         family = APR_INET;
 #endif
     }
-
+#if APR_HAVE_SOCKADDR_UN
+    if (family == APR_UNIX) {
+        protocol = 0;
+    }
+#endif
     alloc_socket(new, cont);
 
 #ifndef BEOS_R5
@@ -128,7 +133,7 @@
     if ((*new)->socketdes < 0) {
         return errno;
     }
-    set_socket_vars(*new, family, type, protocol);
+    set_socket_vars(*new, family, type, oprotocol);
 
     (*new)->timeout = -1;
     (*new)->inherit = 0;
@@ -225,6 +230,12 @@
         (*new)->local_addr->ipaddr_ptr = &(*new)->local_addr->sa.sin6.sin6_addr;
     }
 #endif
+#if APR_HAVE_SOCKADDR_UN
+    else if (sock->local_addr->sa.sin.sin_family == AF_UNIX) {
+        (*new)->local_addr->ipaddr_ptr = &((*new)->local_addr->sa.unx.sun_path[0]);
+    }
+#endif
+
     (*new)->remote_addr->port = ntohs((*new)->remote_addr->sa.sin.sin_port);
     if (sock->local_port_unknown) {
         /* not likely for a listening socket, but theoretically possible :) */
Index: include/apr.h.in
===================================================================
--- include/apr.h.in	(revision 744613)
+++ include/apr.h.in	(working copy)
@@ -208,6 +208,7 @@
 #define APR_HAVE_INET_ADDR      @have_inet_addr@
 #define APR_HAVE_INET_NETWORK   @have_inet_network@
 #define APR_HAVE_IPV6           @have_ipv6@
+#define APR_HAVE_SOCKADDR_UN    @have_sockaddr_un@
 #define APR_HAVE_MEMMOVE        @have_memmove@
 #define APR_HAVE_SETRLIMIT      @have_setrlimit@
 #define APR_HAVE_SIGACTION      @have_sigaction@
Index: include/apr.hw
===================================================================
--- include/apr.hw	(revision 744613)
+++ include/apr.hw	(working copy)
@@ -278,6 +278,7 @@
 #define APR_HAVE_INET_ADDR      1
 #define APR_HAVE_INET_NETWORK   0
 #define APR_HAVE_IPV6           0
+#define APR_HAVE_SOCKADDR_UN    0
 #define APR_HAVE_MEMMOVE        1
 #define APR_HAVE_SETRLIMIT      0
 #define APR_HAVE_SIGACTION      0
Index: include/apr_network_io.h
===================================================================
--- include/apr_network_io.h	(revision 744613)
+++ include/apr_network_io.h	(working copy)
@@ -30,6 +30,9 @@
 #if APR_HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
+#if APR_HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -111,6 +114,7 @@
 
 #define APR_IPV4_ADDR_OK  0x01  /**< @see apr_sockaddr_info_get() */
 #define APR_IPV6_ADDR_OK  0x02  /**< @see apr_sockaddr_info_get() */
+#define APR_UNIX_ADDR_OK  0x04  /**< @see apr_sockaddr_info_get() */
 
 #if (!APR_HAVE_IN_ADDR)
 /**
@@ -154,6 +158,14 @@
 #define APR_INET6    AF_INET6
 #endif
 
+#if defined(AF_UNIX)
+#define APR_UNIX     AF_UNIX
+#elif defined(AF_LOCAL)
+#define APR_UNIX     AF_LOCAL
+#else
+#define APR_UNIX     APR_UNSPEC
+#endif
+
 /**
  * @defgroup IP_Proto IP Protocol Definitions for use when creating sockets
  * @{
@@ -245,6 +257,10 @@
          * dependent on whether APR_HAVE_IPV6 is defined. */
         struct sockaddr_storage sas;
 #endif
+#if APR_HAVE_SOCKADDR_UN
+        /** Unix domain socket sockaddr structure */
+        struct sockaddr_un unx;
+#endif
     } sa;
 };
 
@@ -377,7 +393,18 @@
                                           apr_int32_t flags,
                                           apr_pool_t *p);
 
+
 /**
+ * Create domain socket apr_sockaddr_t.
+ * @param sa The new apr_sockaddr_t.
+ * @param filename The socket file name.
+ * @param p The pool for the apr_sockaddr_t and associated storage.
+ */
+APR_DECLARE(apr_status_t) apr_sockaddr_local_get(apr_sockaddr_t **sa,
+                                                 const char *filename, 
+                                                 apr_pool_t *p);
+
+/**
  * Look up the host name from an apr_sockaddr_t.
  * @param hostname The hostname.
  * @param sa The apr_sockaddr_t.
Index: include/apr.hnw
===================================================================
--- include/apr.hnw	(revision 744613)
+++ include/apr.hnw	(working copy)
@@ -178,6 +178,7 @@
 #else
 #define APR_HAVE_IPV6           0
 #endif
+#define APR_HAVE_SOCKADDR_UN    0
 #define APR_HAVE_MEMCHR         1
 #define APR_HAVE_MEMMOVE        1
 #define APR_HAVE_SETRLIMIT      0
Index: configure.in
===================================================================
--- configure.in	(revision 744613)
+++ configure.in	(working copy)
@@ -2294,6 +2294,7 @@
 APR_CHECK_WORKING_GETNAMEINFO
 APR_CHECK_SOCKADDR_IN6
 APR_CHECK_SOCKADDR_STORAGE
+APR_CHECK_SOCKADDR_UN
 
 have_ipv6="0"
 if test "$user_disabled_ipv6" = 1; then
Index: build/apr_network.m4
===================================================================
--- build/apr_network.m4	(revision 744613)
+++ build/apr_network.m4	(working copy)
@@ -788,6 +788,36 @@
 fi
 ])
 
+dnl Check for presence of struct sockaddr_un.
+AC_DEFUN([APR_CHECK_SOCKADDR_UN], [
+AC_CACHE_CHECK(for sockaddr_un, ac_cv_define_sockaddr_un,[
+AC_TRY_COMPILE([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+],[
+struct sockaddr_un sa;
+],[
+    ac_cv_define_sockaddr_un=yes
+],[
+    ac_cv_define_sockaddr_un=no
+])
+])
+
+if test "$ac_cv_define_sockaddr_un" = "yes"; then
+  have_sockaddr_un=1
+else
+  have_sockaddr_un=0
+fi
+AC_SUBST(have_sockaddr_un)
+])
+
 dnl
 dnl APR_H_ERRNO_COMPILE_CHECK
 dnl

Reply via email to