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 | [EMAIL PROTECTED] | PGP public key at web site: http://www.geocities.com/SiliconValley/Park/9289/ Born in Roswell... married an alien...