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...