apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "David Reid" <dr...@jetnet.co.uk>
Subject Re: [PATCH] change apr_connect() to take apr_sockaddr_t, add apr_getaddrinfo()
Date Thu, 16 Nov 2000 20:12:00 GMT
Looks OK with that suplicate line removed.

+1

david
----- Original Message -----
From: "Jeff Trawick" <trawickj@bellsouth.net>
To: <dev@apr.apache.org>
Sent: Thursday, November 16, 2000 6:25 PM
Subject: [PATCH] change apr_connect() to take apr_sockaddr_t, add
apr_getaddrinfo()


> This started off as David Reid's patch which he posted this a.m.  I
> renamed his apr_gethostbyname() to apr_getaddrinfo(), added fields
> family and port to apr_getaddrinfo(), made some fixes, and changed the
> remaining callers of apr_connect() to use the new parameter list.
>
> Changes to the currently-committed API:
>
> . apr_connect() takes an apr_sockaddr_t parameter instead of hostname
>
> . apr_getaddrinfo() is new; this builds an apr_sockaddr_t representing
>   the peer you wish to communicate with
>
> Suggestions?  Concerns?
>
> Index: lib/apr/include/apr_network_io.h
> ===================================================================
> RCS file:
/home/cvspublic/apache-2.0/src/lib/apr/include/apr_network_io.h,v
> retrieving revision 1.71
> diff -u -r1.71 apr_network_io.h
> --- lib/apr/include/apr_network_io.h 2000/11/16 14:48:50 1.71
> +++ lib/apr/include/apr_network_io.h 2000/11/16 18:07:26
> @@ -265,7 +265,7 @@
>   *                 APR assumes that the sockaddr_in in the apr_socket is
>   *                 completely filled out.
>   */
> -apr_status_t apr_connect(apr_socket_t *sock, const char *hostname);
> +apr_status_t apr_connect(apr_socket_t *sock, apr_sockaddr_t *sa);
>
>  /**
>   * Get name of a machine we are currently connected to.
> @@ -274,6 +274,12 @@
>   * @param sock The socket to examine.
>   */
>  apr_status_t apr_get_hostname(char **name, apr_interface_e which,
apr_socket_t *sock);
> +
> +apr_status_t apr_getaddrinfo(apr_sockaddr_t **sa,
> +                             const char *hostname,
> +                             apr_int32_t family,
> +                             apr_port_t port,
> +                             apr_pool_t *p);
>
>  /**
>   * Get name of the current machine
> Index: lib/apr/network_io/unix/sa_common.c
> ===================================================================
> RCS file:
/home/cvspublic/apache-2.0/src/lib/apr/network_io/unix/sa_common.c,v
> retrieving revision 1.6
> diff -u -r1.6 sa_common.c
> --- lib/apr/network_io/unix/sa_common.c 2000/11/16 14:48:49 1.6
> +++ lib/apr/network_io/unix/sa_common.c 2000/11/16 18:07:27
> @@ -171,3 +171,65 @@
>      return APR_SUCCESS;
>  }
>
> +static void set_sockaddr_vars(apr_sockaddr_t *addr, int family)
> +{
> +    addr->sa.sin.sin_family = family;
> +    addr->sa.sin.sin_family = family;
> +
> +    if (family == AF_INET) {
> +        addr->sa_len = sizeof(struct sockaddr_in);
> +        addr->addr_str_len = 16;
> +        addr->ipaddr_ptr = &(addr->sa.sin.sin_addr);
> +        addr->ipaddr_len = sizeof(struct in_addr);
> +    }
> +#if APR_HAVE_IPV6
> +    else if (family == AF_INET6) {
> +        addr->sa_len = sizeof(struct sockaddr_in6);
> +        addr->addr_str_len = 46;
> +        addr->ipaddr_ptr = &(addr->sa.sin6.sin6_addr);
> +        addr->ipaddr_len = sizeof(struct in6_addr);
> +    }
> +#endif
> +}
> +
> +apr_status_t apr_getaddrinfo(apr_sockaddr_t **sa, const char *hostname,
> +                             apr_int32_t family, apr_port_t port,
> +                             apr_pool_t *p)
> +{
> +    struct hostent *hp;
> +
> +    (*sa) = (apr_sockaddr_t *)apr_pcalloc(p, sizeof(apr_sockaddr_t));
> +    if ((*sa) == NULL)
> +        return APR_ENOMEM;
> +    (*sa)->pool = p;
> +    (*sa)->sa.sin.sin_family = AF_INET; /* we don't yet support IPv6 */
> +    (*sa)->sa.sin.sin_port = htons(port);
> +    set_sockaddr_vars(*sa, (*sa)->sa.sin.sin_family);
> +
> +    if (hostname != NULL) {
> +#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)->sa_len = sizeof(struct sockaddr_in);
> +        }
> +        else {
> +#endif
> +        hp = gethostbyname(hostname);
> +
> +        if (!hp)  {
> +            return (h_errno + APR_OS_START_SYSERR);
> +        }
> +
> +        memcpy((char *)&(*sa)->sa.sin.sin_addr, hp->h_addr_list[0],
> +               hp->h_length);
> +        (*sa)->sa_len = sizeof(struct sockaddr_in);
> +        (*sa)->ipaddr_len = hp->h_length;
> +
> +#ifndef GETHOSTBYNAME_HANDLES_NAS
> +        }
> +#endif
> +    }
> +   (*sa)->hostname = apr_pstrdup(p, hostname);
> +    return APR_SUCCESS;
> +}
> Index: lib/apr/network_io/unix/sockets.c
> ===================================================================
> RCS file:
/home/cvspublic/apache-2.0/src/lib/apr/network_io/unix/sockets.c,v
> retrieving revision 1.56
> diff -u -r1.56 sockets.c
> --- lib/apr/network_io/unix/sockets.c 2000/11/16 14:48:49 1.56
> +++ lib/apr/network_io/unix/sockets.c 2000/11/16 18:07:27
> @@ -226,57 +226,35 @@
>      return APR_SUCCESS;
>  }
>
> -apr_status_t apr_connect(apr_socket_t *sock, const char *hostname)
> +apr_status_t apr_connect(apr_socket_t *sock, apr_sockaddr_t *sa)
>  {
> -    struct hostent *hp;
> -
>      if ((sock->socketdes < 0) || (!sock->remote_addr)) {
>          return APR_ENOTSOCK;
>      }
> -    if (hostname != NULL) {
> -#ifndef GETHOSTBYNAME_HANDLES_NAS
> -        if (*hostname >= '0' && *hostname <= '9' &&
> -            strspn(hostname, "0123456789.") == strlen(hostname)) {
> -            sock->remote_addr->sa.sin.sin_addr.s_addr =
inet_addr(hostname);
> -        }
> -        else {
> -#endif
> -        hp = gethostbyname(hostname);
> -
> -        if (!hp)  {
> -            return (h_errno + APR_OS_START_SYSERR);
> -        }
> -
> -        /* XXX IPv6: move name resolution out of this function */
> -        memcpy((char *)&sock->remote_addr->sa.sin.sin_addr,
hp->h_addr_list[0],
> -               hp->h_length);
> -
> -#ifndef GETHOSTBYNAME_HANDLES_NAS
> -        }
> -#endif
> -    }
>
> -    if ((connect(sock->socketdes,
> -                 (const struct sockaddr *)&sock->remote_addr->sa.sin,
> -                 sock->remote_addr->sa_len) < 0) &&
> +    if ((connect(sock->socketdes,
> +                 (const struct sockaddr *)&sa->sa.sin,
> +                 sa->sa_len) < 0) &&
>          (errno != EINPROGRESS)) {
>          return errno;
>      }
>      else {
> -        /* XXX IPv6 */
> +        sock->remote_addr = sa;
> +        /* XXX IPv6 assumes sin_port and sin6_port at same offset */
>          if (sock->local_addr->sa.sin.sin_port == 0) {
>              /* connect() got us an ephemeral port */
>              sock->local_port_unknown = 1;
>          }
> -        /* XXX IPv6 */
> -        if (sock->local_addr->sa.sin.sin_addr.s_addr == 0) {
> +        /* XXX IPv6 to be handled better later... */
> +        if (sock->local_addr->sa.sin.sin_family == AF_INET6 ||
> +            sock->local_addr->sa.sin.sin_addr.s_addr == 0) {
>              /* not bound to specific local interface; connect() had to
assign
>               * one for the socket
>               */
>              sock->local_interface_unknown = 1;
>          }
>  #ifndef HAVE_POLL
> - sock->connected=1;
> +        sock->connected=1;
>  #endif
>          return APR_SUCCESS;
>      }
> Index: lib/apr/test/client.c
> ===================================================================
> RCS file: /home/cvspublic/apache-2.0/src/lib/apr/test/client.c,v
> retrieving revision 1.17
> diff -u -r1.17 client.c
> --- lib/apr/test/client.c 2000/11/09 15:01:35 1.17
> +++ lib/apr/test/client.c 2000/11/16 18:07:28
> @@ -73,6 +73,7 @@
>      char *dest = "127.0.0.1";
>      apr_port_t local_port, remote_port;
>      apr_interval_time_t read_timeout = -1;
> +    apr_sockaddr_t *destsa;
>
>      setbuf(stdout, NULL);
>      if (argc > 1) {
> @@ -115,17 +116,18 @@
>          fprintf(stdout, "OK\n");
>      }
>
> -    fprintf(stdout, "\tClient:  Setting port for socket.......");
> -    if (apr_set_port(sock, APR_REMOTE, 8021) != APR_SUCCESS) {
> +    fprintf(stdout,"\tClient:  Making socket address...............");
> +    if (apr_getaddrinfo(&destsa, dest, AF_INET, 8021, context) !=
APR_SUCCESS) {
>          apr_close_socket(sock);
> -        fprintf(stderr, "Couldn't set the port correctly\n");
> +        fprintf(stdout, "Failed!\n");
> +        fprintf(stdout, "Couldn't create a socket address structure for
%s\n", dest);
>          exit(-1);
>      }
> -    fprintf(stdout, "OK\n");
> +    fprintf(stdout,"OK\n");
>
>      fprintf(stdout, "\tClient:  Connecting to socket.......");
>
> -    stat = apr_connect(sock, dest);
> +    stat = apr_connect(sock, destsa);
>
>      if (stat != APR_SUCCESS) {
>          apr_close_socket(sock);
> Index: lib/apr/test/testsf.c
> ===================================================================
> RCS file: /home/cvspublic/apache-2.0/src/lib/apr/test/testsf.c,v
> retrieving revision 1.13
> diff -u -r1.13 testsf.c
> --- lib/apr/test/testsf.c 2000/11/14 19:32:26 1.13
> +++ lib/apr/test/testsf.c 2000/11/16 18:07:28
> @@ -205,6 +205,7 @@
>      apr_pollfd_t *pfd;
>      apr_int32_t nsocks;
>      int i;
> +    apr_sockaddr_t *destsa;
>
>      apr_setup(&p, &sock);
>      create_testfile(p, TESTFILE);
> @@ -217,15 +218,15 @@
>          exit(1);
>      }
>
> -    rv = apr_set_port(sock, APR_REMOTE, TESTSF_PORT);
> +    rv = apr_getaddrinfo(&destsa, "127.0.0.1", AF_INET, TESTSF_PORT, p);
>      if (rv != APR_SUCCESS) {
> -        fprintf(stderr, "apr_set_remote_port()->%d/%s\n",
> +        fprintf(stderr, "apr_getaddrinfo()->%d/%s\n",
>                  rv,
>                  apr_strerror(rv, buf, sizeof buf));
>          exit(1);
>      }
>
> -    rv = apr_connect(sock, "127.0.0.1");
> +    rv = apr_connect(sock, destsa);
>      if (rv != APR_SUCCESS) {
>          fprintf(stderr, "apr_connect()->%d/%s\n",
>                  rv,
> Index: main/rfc1413.c
> ===================================================================
> RCS file: /home/cvspublic/apache-2.0/src/main/rfc1413.c,v
> retrieving revision 1.28
> diff -u -r1.28 rfc1413.c
> --- main/rfc1413.c 2000/11/09 15:09:50 1.28
> +++ main/rfc1413.c 2000/11/16 18:07:30
> @@ -108,8 +108,8 @@
>
>  /* bind_connect - bind both ends of a socket */
>  /* Ambarish fix this. Very broken */
> -static int get_rfc1413(apr_socket_t *sock, const char *local_ip,
> -        const char *rmt_ip,
> +static int get_rfc1413(apr_socket_t *sock, apr_pool_t *p,
> +                       const char *local_ip, const char *rmt_ip,
>          char user[RFC1413_USERLEN+1], server_rec *srv)
>  {
>      apr_port_t rmt_port, our_port;
> @@ -119,6 +119,7 @@
>      char *cp;
>      char buffer[RFC1413_MAXDATA + 1];
>      int buflen;
> +    apr_sockaddr_t *destsa;
>
>      /*
>       * Bind the local and remote ends of the query socket to the same
> @@ -138,14 +139,19 @@
>   return -1;
>      }
>
> +    if ((status = apr_getaddrinfo(&destsa, rmt_ip, AF_INET, RFC1413_PORT,
> +                                  p)) != APR_SUCCESS) {
> +        /* This should not fail since we have a numeric address string
> +         * as the host. */
> +        ap_log_error(APLOG_MARK, APLOG_CRIT, status, srv,
> +                     "rfc1413: apr_getaddrinfo() failed");
> +        return -1;
> +    }
>  /*
>   * errors from connect usually imply the remote machine doesn't support
>   * the service
>   */
> -    apr_set_port(sock, APR_REMOTE, RFC1413_PORT);
> -    apr_set_ipaddr(sock, APR_REMOTE, rmt_ip);
> -
> -    if (apr_connect(sock, NULL) != APR_SUCCESS)
> +    if (apr_connect(sock, destsa) != APR_SUCCESS)
>          return -1;
>      apr_get_port(&sav_our_port, APR_LOCAL, sock);
>      apr_get_port(&sav_rmt_port, APR_REMOTE, sock);
> @@ -235,7 +241,7 @@
>   conn->remote_logname = result;
>      }
>
> -    if (get_rfc1413(sock, conn->local_ip, conn->remote_ip, user, srv) >=
0)
> +    if (get_rfc1413(sock, conn->pool, conn->local_ip, conn->remote_ip,
user, srv) >= 0)
>          result = user;
>      apr_close_socket(sock);
>      conn->remote_logname = result;
> Index: modules/proxy/proxy_util.c
> ===================================================================
> RCS file: /home/cvspublic/apache-2.0/src/modules/proxy/proxy_util.c,v
> retrieving revision 1.26
> diff -u -r1.26 proxy_util.c
> --- modules/proxy/proxy_util.c 2000/11/16 01:57:46 1.26
> +++ modules/proxy/proxy_util.c 2000/11/16 18:07:32
> @@ -1135,25 +1135,15 @@
>  {
>      apr_status_t rv;
>      int i;
> +    apr_sockaddr_t *destsa;
>
> -    for (i = 0; host[i] != '\0'; i++)
> -        if (!apr_isdigit(host[i]) && host[i] != '.')
> -            break;
> -
> -    apr_set_port(sock, APR_REMOTE, port);
> -    if (host[i] == '\0') {
> -        apr_set_ipaddr(sock, APR_REMOTE, host);
> -        host = NULL;
> +    rv = apr_getaddrinfo(&destsa, host, AF_INET, port, r->pool);
> +    if (rv == APR_SUCCESS) {
> +        rv = apr_connect(sock, destsa);
>      }
> -
> -    do
> -    {
> -        rv = apr_connect(sock, host);
> -    } while (APR_STATUS_IS_EINTR(rv));
> -
>      if (rv != APR_SUCCESS)
>      {
> -        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
> +        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
>              "proxy connect to %s port %d failed", host, port);
>      }
>      return rv;
> Index: support/ab.c
> ===================================================================
> RCS file: /home/cvspublic/apache-2.0/src/support/ab.c,v
> retrieving revision 1.32
> diff -u -r1.32 ab.c
> --- support/ab.c 2000/11/10 19:01:33 1.32
> +++ support/ab.c 2000/11/16 18:07:36
> @@ -482,6 +482,7 @@
>  static void start_connect(struct connection *c)
>  {
>      apr_status_t rv;
> +    apr_sockaddr_t *destsa;
>
>      if(!(started < requests)) return;
>
> @@ -491,14 +492,15 @@
>      c->cbx = 0;
>      c->gotheader = 0;
>
> +    if ((rv = apr_getaddrinfo(&destsa, hostname, AF_INET, port, cntxt))
> +         != APR_SUCCESS) {
> +        apr_err("apr_getaddrinfo()", rv);
> +    }
>      if ((rv = apr_create_tcp_socket(&c->aprsock, cntxt)) != APR_SUCCESS)
{
>          apr_err("Socket:", rv);
>      }
> -    if ((rv = apr_set_port(c->aprsock, APR_REMOTE, port)) != APR_SUCCESS)
{
> -        apr_err("Port:", rv);
> -    }
>      c->start = apr_now();
> -    if ((rv = apr_connect(c->aprsock, hostname)) != APR_SUCCESS) {
> +    if ((rv = apr_connect(c->aprsock, destsa)) != APR_SUCCESS) {
>          if (APR_STATUS_IS_EINPROGRESS(rv)) {
>              c->state = STATE_CONNECTING;
>              apr_add_poll_socket(readbits, c->aprsock, APR_POLLOUT);
>
> --
> Jeff Trawick | trawick@ibm.net | PGP public key at web site:
>      http://www.geocities.com/SiliconValley/Park/9289/
>           Born in Roswell... married an alien...
>


Mime
View raw message