apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From traw...@locus.apache.org
Subject cvs commit: apr/network_io/unix sa_common.c
Date Mon, 18 Dec 2000 20:17:54 GMT
trawick     00/12/18 12:17:53

  Modified:    .        CHANGES
               include  apr_network_io.h
               network_io/unix sa_common.c
  Log:
  apr_getaddrinfo() can now return multiple addresses for a host via
  the next field in apr_sockaddr_t.
  
  Revision  Changes    Path
  1.27      +3 -0      apr/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apr/CHANGES,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- CHANGES	2000/12/18 17:00:39	1.26
  +++ CHANGES	2000/12/18 20:17:46	1.27
  @@ -1,4 +1,7 @@
   Changes with APR b1
  +  *) apr_getaddrinfo() can now return multiple addresses for a host
  +     via the next field in apr_sockaddr_t.  [Jeff Trawick]
  +
     *) Tighten up the check for getaddrinfo().  If it can't figure out
        the appropriate address family for 127.0.0.1, it fails.  
        Unfortunately, Tru64 fails this test so we won't do IPv6 on
  
  
  
  1.92      +3 -0      apr/include/apr_network_io.h
  
  Index: apr_network_io.h
  ===================================================================
  RCS file: /home/cvs/apr/include/apr_network_io.h,v
  retrieving revision 1.91
  retrieving revision 1.92
  diff -u -r1.91 -r1.92
  --- apr_network_io.h	2000/12/18 17:00:41	1.91
  +++ apr_network_io.h	2000/12/18 20:17:49	1.92
  @@ -187,6 +187,9 @@
       /** This points to the IP address structure within the appropriate
        *  sockaddr structure.  */
       void *ipaddr_ptr;
  +    /** If multiple addresses were found by apr_getaddrinfo(), this 
  +     *  points to a representation of the next address. */
  +    apr_sockaddr_t *next;
   };
   
   #if APR_HAS_SENDFILE
  
  
  
  1.23      +69 -21    apr/network_io/unix/sa_common.c
  
  Index: sa_common.c
  ===================================================================
  RCS file: /home/cvs/apr/network_io/unix/sa_common.c,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- sa_common.c	2000/12/15 20:56:55	1.22
  +++ sa_common.c	2000/12/18 20:17:51	1.23
  @@ -274,6 +274,29 @@
       return APR_SUCCESS;
   }
   
  +#if defined(HAVE_GETADDRINFO) && APR_HAVE_IPV6
  +static void save_addrinfo(apr_pool_t *p, apr_sockaddr_t *sa, 
  +                          struct addrinfo *ai, apr_port_t port)
  +{
  +    sa->pool = p;
  +    sa->sa.sin.sin_family = ai->ai_family;
  +    memcpy(&sa->sa, ai->ai_addr, ai->ai_addrlen);
  +    /* XXX IPv6: assumes sin_port and sin6_port at same offset */
  +    sa->sa.sin.sin_port = htons(port);
  +    set_sockaddr_vars(sa, sa->sa.sin.sin_family);
  +}
  +#else
  +static void save_addrinfo(apr_pool_t *p, apr_sockaddr_t *sa,
  +                          struct in_addr ipaddr, apr_port_t port)
  +{
  +    sa->pool = p;
  +    sa->sa.sin.sin_family = AF_INET;
  +    sa->sa.sin.sin_addr = ipaddr;
  +    sa->sa.sin.sin_port = htons(port);
  +    set_sockaddr_vars(sa, sa->sa.sin.sin_family);
  +}
  +#endif
  +
   apr_status_t apr_getaddrinfo(apr_sockaddr_t **sa, const char *hostname, 
                                apr_int32_t family, apr_port_t port,
                                apr_int32_t flags, apr_pool_t *p)
  @@ -281,12 +304,12 @@
       (*sa) = (apr_sockaddr_t *)apr_pcalloc(p, sizeof(apr_sockaddr_t));
       if ((*sa) == NULL)
           return APR_ENOMEM;
  -    (*sa)->pool = p;
       (*sa)->hostname = apr_pstrdup(p, hostname);
   
   #if defined(HAVE_GETADDRINFO) && APR_HAVE_IPV6
       if (hostname != NULL) {
           struct addrinfo hints, *ai;
  +        apr_sockaddr_t *cursa;
           int error;
           char num[8];
   
  @@ -312,8 +335,14 @@
                   return error + APR_OS_START_SYSERR;
               }
           }
  -        (*sa)->sa.sin.sin_family = ai->ai_family;
  -        memcpy(&(*sa)->sa, ai->ai_addr, ai->ai_addrlen);
  +        cursa = *sa;
  +        save_addrinfo(p, cursa, ai, port);
  +        while (ai->ai_next) { /* while more addresses to report */
  +            cursa->next = apr_pcalloc(p, sizeof(apr_sockaddr_t));
  +            ai = ai->ai_next;
  +            cursa = cursa->next;
  +            save_addrinfo(p, cursa, ai, port);
  +        }
           freeaddrinfo(ai);
       }
       else {
  @@ -323,24 +352,28 @@
           else {
               (*sa)->sa.sin.sin_family = family;
           }
  +        (*sa)->pool = p;
  +        /* XXX IPv6: assumes sin_port and sin6_port at same offset */
  +        (*sa)->sa.sin.sin_port = htons(port);
  +        set_sockaddr_vars(*sa, (*sa)->sa.sin.sin_family);
       }
  -    set_sockaddr_vars(*sa, (*sa)->sa.sin.sin_family);
   #else
  -    if (family == APR_UNSPEC) {
  -        (*sa)->sa.sin.sin_family = APR_INET; /* we don't support IPv6 here */
  -    }
  -    else {
  -        (*sa)->sa.sin.sin_family = family;
  -    }
  -    set_sockaddr_vars(*sa, (*sa)->sa.sin.sin_family);
       if (hostname != NULL) {
           struct hostent *hp;
  +        apr_sockaddr_t *cursa;
  +        int curaddr;
  +
  +        if (family == APR_UNSPEC) {
  +            family = APR_INET; /* we don't support IPv6 here */
  +        }
   
   #ifndef GETHOSTBYNAME_HANDLES_NAS
           if (*hostname >= '0' && *hostname <= '9' &&
               strspn(hostname, "0123456789.") == strlen(hostname)) {
  -            (*sa)->sa.sin.sin_addr.s_addr = inet_addr(hostname);
  -            (*sa)->salen = sizeof(struct sockaddr_in);
  +            struct in_addr ipaddr;
  +
  +            ipaddr.s_addr = inet_addr(hostname);
  +            save_addrinfo(p, *sa, ipaddr, port);
           }
           else {
   #endif
  @@ -353,19 +386,34 @@
               return (h_errno + APR_OS_START_SYSERR);
   #endif
           }
  -
  -        memcpy((char *)&(*sa)->sa.sin.sin_addr, hp->h_addr_list[0],
  -               hp->h_length);
  -        (*sa)->salen = sizeof(struct sockaddr_in);
  -        (*sa)->ipaddr_len = hp->h_length;
  -
  +        cursa = *sa;
  +        curaddr = 0;
  +        save_addrinfo(p, cursa, *(struct in_addr *)hp->h_addr_list[curaddr], 
  +                      port);
  +        ++curaddr;
  +        while (hp->h_addr_list[curaddr]) {
  +            cursa->next = apr_pcalloc(p, sizeof(apr_sockaddr_t));
  +            cursa = cursa->next;
  +            save_addrinfo(p, cursa, *(struct in_addr *)hp->h_addr_list[curaddr], 
  +                          port);
  +            ++curaddr;
  +        }
   #ifndef GETHOSTBYNAME_HANDLES_NAS
           }
   #endif
       }
  +    else {
  +        if (family == APR_UNSPEC) {
  +            (*sa)->sa.sin.sin_family = APR_INET;
  +        }
  +        else {
  +            (*sa)->sa.sin.sin_family = family;
  +        }
  +        (*sa)->pool = p;
  +        (*sa)->sa.sin.sin_port = htons(port);
  +        set_sockaddr_vars(*sa, (*sa)->sa.sin.sin_family);
  +    }
   #endif
  -    /* XXX IPv6: assumes sin_port and sin6_port at same offset */
  -    (*sa)->sa.sin.sin_port = htons(port);
       return APR_SUCCESS;
   }
   
  
  
  

Mime
View raw message