On 02/19/2009 08:15 AM, mt...@apache.org wrote:
> Author: mturk
> Date: Thu Feb 19 07:15:23 2009
> New Revision: 745763
> 
> URL: http://svn.apache.org/viewvc?rev=745763&view=rev
> Log:
> Enable unix domain (AF_UNIX) sockets if supported by the OS
> 
> Modified:
>     apr/apr/trunk/CHANGES
>     apr/apr/trunk/build/apr_network.m4
>     apr/apr/trunk/configure.in
>     apr/apr/trunk/include/apr.h.in
>     apr/apr/trunk/include/apr.hnw
>     apr/apr/trunk/include/apr.hw
>     apr/apr/trunk/include/apr_network_io.h
>     apr/apr/trunk/include/arch/unix/apr_arch_networkio.h
>     apr/apr/trunk/network_io/unix/sockaddr.c
>     apr/apr/trunk/network_io/unix/sockets.c
>     apr/apr/trunk/network_io/unix/sockopt.c
>     apr/apr/trunk/test/sockchild.c
>     apr/apr/trunk/test/testsock.c
> 

> Modified: apr/apr/trunk/network_io/unix/sockaddr.c
> URL: 
> http://svn.apache.org/viewvc/apr/apr/trunk/network_io/unix/sockaddr.c?rev=745763&r1=745762&r2=745763&view=diff
> ==============================================================================
> --- apr/apr/trunk/network_io/unix/sockaddr.c (original)
> +++ apr/apr/trunk/network_io/unix/sockaddr.c Thu Feb 19 07:15:23 2009

> @@ -564,6 +572,32 @@
>          }
>  #endif
>      }
> +    if (family == APR_UNSPEC && hostname && *hostname == '/')
> +        family = APR_UNIX;
> +    if (family == APR_UNIX) {
> +#if APR_HAVE_SOCKADDR_UN
> +        if (hostname && *hostname == '/') {

Why is it needed that hostname always starts with a '/'?

> +            *sa = apr_pcalloc(p, sizeof(apr_sockaddr_t));
> +            (*sa)->pool = p;
> +            apr_cpystrn((*sa)->sa.unx.sun_path, hostname,
> +                        sizeof((*sa)->sa.unx.sun_path));
> +            (*sa)->hostname = apr_pstrdup(p, hostname);
> +            (*sa)->family = APR_UNIX;
> +            (*sa)->sa.unx.sun_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);
> +            (*sa)->ipaddr_len = (*sa)->addr_str_len;
> +
> +            return APR_SUCCESS;
> +        }
> +        else
> +#endif
> +        {
> +            *sa = NULL;
> +            return APR_ENOTIMPL;
> +        }
> +    }
>  #if !APR_HAVE_IPV6
>      /* What may happen is that APR is not IPv6-enabled, but we're still
>       * going to call getaddrinfo(), so we have to tell the OS we only
> @@ -616,6 +650,12 @@
>                           tmphostname, sizeof(tmphostname), NULL, 0,
>                           flags != 0 ? flags : NI_NAMEREQD);
>      }
> +#if APR_HAVE_SOCKADDR_UN
> +    else if (sockaddr->family == APR_UNIX) {
> +        *hostname = sockaddr->hostname;

Shouldn't we do

apr_pstrdup(sockaddr->pool, sockaddr->hostname)

to protect our internal hostname in sockaddr?


> +        return APR_SUCCESS;
> +    }
> +#endif
>      else
>  #endif
>      rc = getnameinfo((const struct sockaddr *)&sockaddr->sa, sockaddr->salen,
> 
> Modified: apr/apr/trunk/network_io/unix/sockets.c
> URL: 
> http://svn.apache.org/viewvc/apr/apr/trunk/network_io/unix/sockets.c?rev=745763&r1=745762&r2=745763&view=diff
> ==============================================================================
> --- apr/apr/trunk/network_io/unix/sockets.c (original)
> +++ apr/apr/trunk/network_io/unix/sockets.c Thu Feb 19 07:15:23 2009
> @@ -26,12 +26,37 @@
>  #define close closesocket
>  #endif /* BEOS_R5 */
>  
> -static char generic_inaddr_any[16] = {0}; /* big enough for IPv4 or IPv6 */
> +#if APR_HAVE_SOCKADDR_UN
> +#define GENERIC_INADDR_ANY_LEN  sizeof(struct sockaddr_un)

Do we know that sizeof(struct sockaddr_un) is always >= 16?

> +#else
> +#define GENERIC_INADDR_ANY_LEN  16
> +#endif
> +
> +/* big enough for IPv4, IPv6 and optionaly sun_path */
> +static char generic_inaddr_any[GENERIC_INADDR_ANY_LEN] = {0};
>  
>  static apr_status_t socket_cleanup(void *sock)
>  {
>      apr_socket_t *thesocket = sock;
>  
> +#if APR_HAVE_SOCKADDR_UN
> +    if (thesocket->bound && thesocket->local_addr->family == APR_UNIX) {
> +        /* XXX: Check for return values ? */
> +        unlink(thesocket->local_addr->hostname);

Shouldn't we close the socket before unlinking?

> +    }
> +#endif        
> +    if (close(thesocket->socketdes) == 0) {
> +        thesocket->socketdes = -1;
> +        return APR_SUCCESS;
> +    }
> +    else {
> +        return errno;
> +    }
> +}
> +
> +static apr_status_t socket_child_cleanup(void *sock)
> +{
> +    apr_socket_t *thesocket = sock;
>      if (close(thesocket->socketdes) == 0) {
>          thesocket->socketdes = -1;
>          return APR_SUCCESS;

Regards

RĂ¼diger

Reply via email to