trawick 2002/10/11 13:41:23
Modified: . CHANGES
include apr_network_io.h
network_io/unix sa_common.c
Log:
Add APR_IPV4_ADDR_OK flag to apr_sockaddr_info_get() to allow
apps to avoid lookup of IPv6 address if IPv4 address is sufficient.
(New APR_IPV6_ADDR_OK flag is similar.)
Revision Changes Path
1.342 +4 -0 apr/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr/CHANGES,v
retrieving revision 1.341
retrieving revision 1.342
diff -u -r1.341 -r1.342
--- CHANGES 3 Oct 2002 15:31:49 -0000 1.341
+++ CHANGES 11 Oct 2002 20:41:22 -0000 1.342
@@ -1,5 +1,9 @@
Changes with APR 0.9.2
+ *) Add APR_IPV4_ADDR_OK flag to apr_sockaddr_info_get() to allow
+ apps to avoid lookup of IPv6 address if IPv4 address is sufficient.
+ (New APR_IPV6_ADDR_OK flag is similar.) [Jeff Trawick]
+
*) Disable IPv6 support on Darwin. The current IPv6 support has a
problem in getnameinfo() which breaks certain applications.
[Sander Temme <[EMAIL PROTECTED]>, Jeff Trawick]
1.129 +18 -2 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.128
retrieving revision 1.129
diff -u -r1.128 -r1.129
--- apr_network_io.h 15 Aug 2002 03:23:36 -0000 1.128
+++ apr_network_io.h 11 Oct 2002 20:41:23 -0000 1.129
@@ -136,6 +136,9 @@
typedef enum {APR_SHUTDOWN_READ, APR_SHUTDOWN_WRITE,
APR_SHUTDOWN_READWRITE} apr_shutdown_how_e;
+#define APR_IPV4_ADDR_OK 0x01 /* see doc for apr_sockaddr_info_get() */
+#define APR_IPV6_ADDR_OK 0x02 /* see doc for apr_sockaddr_info_get() */
+
#if (!APR_HAVE_IN_ADDR)
/**
* We need to make sure we always have an in_addr type, so APR will just
@@ -335,11 +338,24 @@
/**
* Create apr_sockaddr_t from hostname, address family, and port.
* @param sa The new apr_sockaddr_t.
- * @param hostname The hostname or numeric address string to resolve/parse.
+ * @param hostname The hostname or numeric address string to resolve/parse,
or
+ * NULL to build an address that corresponds to 0.0.0.0 or ::
* @param family The address family to use, or APR_UNSPEC if the system
should
* decide.
* @param port The port number.
- * @param flags Special processing flags.
+ * @param flags Special processing flags:
+ * <PRE>
+ * APR_IPV4_ADDR_OK first query for IPv4 addresses; only look
+ * for IPv6 addresses if the first query
failed;
+ * only valid if family is APR_UNSPEC and
hostname
+ * isn't NULL; mutually exclusive with
+ * APR_IPV6_ADDR_OK
+ * APR_IPV6_ADDR_OK first query for IPv6 addresses; only look
+ * for IPv4 addresses if the first query
failed;
+ * only valid if family is APR_UNSPEC and
hostname
+ * isn't NULL and APR_HAVE_IPV6; mutually
exclusive
+ * with APR_IPV4_ADDR_OK
+ * </PRE>
* @param p The pool for the apr_sockaddr_t and associated storage.
*/
APR_DECLARE(apr_status_t) apr_sockaddr_info_get(apr_sockaddr_t **sa,
1.59 +51 -5 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.58
retrieving revision 1.59
diff -u -r1.58 -r1.59
--- sa_common.c 11 Oct 2002 18:28:36 -0000 1.58
+++ sa_common.c 11 Oct 2002 20:41:23 -0000 1.59
@@ -376,12 +376,44 @@
return APR_SUCCESS;
}
+static apr_status_t find_addresses(apr_sockaddr_t **sa,
+ const char *hostname, apr_int32_t family,
+ apr_port_t port, apr_int32_t flags,
+ apr_pool_t *p)
+{
+ if (flags & APR_IPV4_ADDR_OK) {
+ apr_status_t error = call_resolver(sa, hostname, AF_INET, port,
flags, p);
+
+#if APR_HAVE_IPV6
+ if (error) {
+ family = AF_INET6; /* try again */
+ }
+ else
+#endif
+ return error;
+ }
+#if APR_HAVE_IPV6
+ else if (flags & APR_IPV6_ADDR_OK) {
+ apr_status_t error = call_resolver(sa, hostname, AF_INET6, port,
flags, p);
+
+ if (error) {
+ family = AF_INET; /* try again */
+ }
+ else {
+ return APR_SUCCESS;
+ }
+ }
+#endif
+
+ return call_resolver(sa, hostname, family, port, flags, p);
+}
+
#else /* end of HAVE_GETADDRINFO code */
-static apr_status_t call_resolver(apr_sockaddr_t **sa,
- const char *hostname, apr_int32_t family,
- apr_port_t port, apr_int32_t flags,
- apr_pool_t *p)
+static apr_status_t find_addresses(apr_sockaddr_t **sa,
+ const char *hostname, apr_int32_t family,
+ apr_port_t port, apr_int32_t flags,
+ apr_pool_t *p)
{
struct hostent *hp;
apr_sockaddr_t *prev_sa;
@@ -478,14 +510,28 @@
apr_int32_t flags,
apr_pool_t *p)
{
*sa = NULL;
+ apr_int32_t masked;
+ if ((masked = flags & (APR_IPV4_ADDR_OK | APR_IPV6_ADDR_OK))) {
+ if (!hostname ||
+ family != AF_UNSPEC ||
+ masked == (APR_IPV4_ADDR_OK | APR_IPV6_ADDR_OK)) {
+ return APR_EINVAL;
+ }
+#if !APR_HAVE_IPV6
+ if (flags & APR_IPV6_ADDR_OK) {
+ return APR_ENOTIMPL;
+ }
+#endif
+ }
+
if (hostname) {
#if !APR_HAVE_IPV6
if (family == APR_UNSPEC) {
family = APR_INET;
}
#endif
- return call_resolver(sa, hostname, family, port, flags, p);
+ return find_addresses(sa, hostname, family, port, flags, p);
}
*sa = apr_pcalloc(p, sizeof(apr_sockaddr_t));