You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modproxy-dev@apache.org by Graham Leggett <mi...@sharp.fm> on 2001/07/21 09:31:09 UTC

gethostbyname threadsafe

Hi all,

Has mod_proxy been patched yet for gethostbyname threadsafe-ness? Does
anything need to be done?

Regards,
Graham 
-- 
-----------------------------------------
minfrin@sharp.fm		"There's a moon
					over Bourbon Street
						tonight..."

Re: gethostbyname threadsafe

Posted by "Victor J. Orlikowski" <v....@gte.net>.
Chuck Murcko writes:
 > Out of curiosity, do we get the host's address list then using 
 > apr_sockaddr_info_get()?

As I understand it, yes.
We basically spin around using a while loop, tranversing the linked
list of alternate addresses that is constructed by
apr_sockaddr_info_get().

Victor
-- 
Victor J. Orlikowski   | The Wall is Down, But the Threat Remains!
==================================================================
v.j.orlikowski@gte.net | orlikowski@apache.org | vjo@us.ibm.com

Re: gethostbyname threadsafe

Posted by Chuck Murcko <ch...@topsail.org>.
Out of curiosity, do we get the host's address list then using 
apr_sockaddr_info_get()?

Directives like ProxyBlock and NoProxy need to spin through the 
alternate address list when they look for a match to the configuration's 
list.

On Monday, July 30, 2001, at 06:45 PM, Ryan Bloom wrote:

> On Monday 30 July 2001 15:30, Graham Leggett wrote:
>> "Victor J. Orlikowski" wrote:
>>> The dirconn_entry structure is tied to a lot of the functionality of
>>> the proxy.  APR handles in_addr and in6_addr inside of the
>>> apr_sockaddr_t structure, and these are referred to by a void *.
>>>
>>> Best we can hope for is to yank any direct mucking with in_addr
>>> structures out, and use APR functions to do it (if the functionality
>>> we desire is available).
>>
>> As I remember the only part of the proxy where any low level DNS magic
>> was being used was the NoProxy option. Everything else uses APR calls
>> and data hidden inside apr_sockaddr_t.
>>
>> NoProxy accepts IP address subranges like "192.168." - his needs to be
>> changed so that it allows IPv6 subranges as well.
>>
>> Isn't there an APR function that can handle IP address subranges like
>> this?
>
> Yep.  :-)   apr_parse_addr_port.
>

Chuck Murcko
Topsail Group
http://www.topsail.org/

Re: gethostbyname threadsafe

Posted by Ryan Bloom <rb...@covalent.net>.
On Monday 30 July 2001 15:30, Graham Leggett wrote:
> "Victor J. Orlikowski" wrote:
> > The dirconn_entry structure is tied to a lot of the functionality of
> > the proxy.  APR handles in_addr and in6_addr inside of the
> > apr_sockaddr_t structure, and these are referred to by a void *.
> >
> > Best we can hope for is to yank any direct mucking with in_addr
> > structures out, and use APR functions to do it (if the functionality
> > we desire is available).
>
> As I remember the only part of the proxy where any low level DNS magic
> was being used was the NoProxy option. Everything else uses APR calls
> and data hidden inside apr_sockaddr_t.
>
> NoProxy accepts IP address subranges like "192.168." - his needs to be
> changed so that it allows IPv6 subranges as well.
>
> Isn't there an APR function that can handle IP address subranges like
> this?

Yep.  :-)   apr_parse_addr_port.

Ryan

_____________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
Covalent Technologies			rbb@covalent.net
-----------------------------------------------------------------------------

Re: gethostbyname threadsafe

Posted by Graham Leggett <mi...@sharp.fm>.
"Victor J. Orlikowski" wrote:

> The dirconn_entry structure is tied to a lot of the functionality of
> the proxy.  APR handles in_addr and in6_addr inside of the
> apr_sockaddr_t structure, and these are referred to by a void *.
> 
> Best we can hope for is to yank any direct mucking with in_addr
> structures out, and use APR functions to do it (if the functionality
> we desire is available).

As I remember the only part of the proxy where any low level DNS magic
was being used was the NoProxy option. Everything else uses APR calls
and data hidden inside apr_sockaddr_t.

NoProxy accepts IP address subranges like "192.168." - his needs to be
changed so that it allows IPv6 subranges as well.

Isn't there an APR function that can handle IP address subranges like
this?

Regards,
Graham
-- 
-----------------------------------------
minfrin@sharp.fm		"There's a moon
					over Bourbon Street
						tonight..."

Re: gethostbyname threadsafe

Posted by "Victor J. Orlikowski" <v....@gte.net>.
No. 

The dirconn_entry structure is tied to a lot of the functionality of
the proxy.  APR handles in_addr and in6_addr inside of the
apr_sockaddr_t structure, and these are referred to by a void *.

Best we can hope for is to yank any direct mucking with in_addr
structures out, and use APR functions to do it (if the functionality
we desire is available).

Victor
-- 
Victor J. Orlikowski   | The Wall is Down, But the Threat Remains!
==================================================================
v.j.orlikowski@gte.net | orlikowski@apache.org | vjo@us.ibm.com

Re: gethostbyname threadsafe

Posted by Graham Leggett <mi...@sharp.fm>.
"Victor J. Orlikowski" wrote:

> Anything using the dirconn structure will not be IPv6 compliant, as it
> uses an in_addr, and does not make provisions for the use of an
> in6_addr.

Can the dircon structure not be removed completely, using APR structures
instead?

Regards,
Graham
-- 
-----------------------------------------
minfrin@sharp.fm		"There's a moon
					over Bourbon Street
						tonight..."

Re: gethostbyname threadsafe

Posted by "Victor J. Orlikowski" <v....@gte.net>.
Anything using the dirconn structure will not be IPv6 compliant, as it
uses an in_addr, and does not make provisions for the use of an
in6_addr.

Victor
-- 
Victor J. Orlikowski   | The Wall is Down, But the Threat Remains!
==================================================================
v.j.orlikowski@gte.net | orlikowski@apache.org | vjo@us.ibm.com

Re: gethostbyname threadsafe

Posted by Graham Leggett <mi...@sharp.fm>.
"Victor J. Orlikowski" wrote:

> So, I got told the proper way to do things. ;)
> At any rate, here is a patch to get rid of gethostbyname().
> Please review; if no-one screams within 24 hours or so, I'll commit.
> NOTE: This is not quite IPv6 safe. There are a lot of IPv4 assumptions
> made in the proxy. If no-one beats be to fixing them (after I commit
> this), I'll take care of it.

Is there anyone out there who can verify whether the proxy works with
IPv6?

Regards,
Graham
-- 
-----------------------------------------
minfrin@sharp.fm		"There's a moon
					over Bourbon Street
						tonight..."

Re: gethostbyname threadsafe

Posted by "Victor J. Orlikowski" <v....@gte.net>.
So, I got told the proper way to do things. ;)
At any rate, here is a patch to get rid of gethostbyname().
Please review; if no-one screams within 24 hours or so, I'll commit.
NOTE: This is not quite IPv6 safe. There are a lot of IPv4 assumptions
made in the proxy. If no-one beats be to fixing them (after I commit
this), I'll take care of it.

Index: modules/proxy/mod_proxy.c
===================================================================
RCS file: /home/cvs/httpd-proxy/module-2.0/mod_proxy.c,v
retrieving revision 1.49
diff -u -d -r1.49 mod_proxy.c
--- modules/proxy/mod_proxy.c	2001/07/09 06:35:51	1.49
+++ modules/proxy/mod_proxy.c	2001/07/30 21:31:43
@@ -615,7 +615,7 @@
     if (!found) {
 	New = apr_array_push(conf->dirconn);
         New->name = apr_pstrdup(parms->pool, arg);
-	New->hostentry = NULL;
+	New->hostaddr = NULL;
 
 	if (ap_proxy_is_ipaddr(New, parms->pool)) {
 #if DEBUGGING
Index: modules/proxy/mod_proxy.h
===================================================================
RCS file: /home/cvs/httpd-proxy/module-2.0/mod_proxy.h,v
retrieving revision 1.53
diff -u -d -r1.53 mod_proxy.h
--- modules/proxy/mod_proxy.h	2001/06/06 21:51:56	1.53
+++ modules/proxy/mod_proxy.h	2001/07/30 21:31:43
@@ -150,7 +150,7 @@
 struct dirconn_entry {
     char *name;
     struct in_addr addr, mask;
-    struct hostent *hostentry;
+    struct apr_sockaddr_t *hostaddr;
     int (*matcher) (struct dirconn_entry * This, request_rec *r);
 };
 
@@ -244,7 +244,6 @@
 PROXY_DECLARE(char *)ap_proxy_removestr(apr_pool_t *pool, const char *list, const char *val);
 PROXY_DECLARE(int) ap_proxy_hex2sec(const char *x);
 PROXY_DECLARE(void) ap_proxy_sec2hex(int t, char *y);
-PROXY_DECLARE(const char *)ap_proxy_host2addr(const char *host, struct hostent *reqhp);
 PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message);
 PROXY_DECLARE(int) ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *p);
 PROXY_DECLARE(int) ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *p);
Index: modules/proxy/proxy_util.c
===================================================================
RCS file: /home/cvs/httpd-proxy/module-2.0/proxy_util.c,v
retrieving revision 1.63
diff -u -d -r1.63 proxy_util.c
--- modules/proxy/proxy_util.c	2001/06/28 12:48:57	1.63
+++ modules/proxy/proxy_util.c	2001/07/30 21:31:44
@@ -64,7 +64,6 @@
 static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);
 static int proxy_match_hostname(struct dirconn_entry *This, request_rec *r);
 static int proxy_match_word(struct dirconn_entry *This, request_rec *r);
-static struct per_thread_data *get_per_thread_data(void);
 
 /* already called in the knowledge that the characters are hex digits */
 PROXY_DECLARE(int) ap_proxy_hex2c(const char *x)
@@ -595,42 +594,6 @@
     return statuscode;
 }
 
-/*
- * This routine returns its own error message
- */
-PROXY_DECLARE(const char *)ap_proxy_host2addr(const char *host, struct hostent *reqhp)
-{
-    int i;
-    struct hostent *hp;
-    struct per_thread_data *ptd = get_per_thread_data();
-
-    for (i = 0; host[i] != '\0'; i++)
-	if (!apr_isdigit(host[i]) && host[i] != '.')
-	    break;
-
-    if (host[i] != '\0') {
-	hp = gethostbyname(host);
-	if (hp == NULL)
-	    return "Host not found";
-    }
-    else {
-	ptd->ipaddr = ap_inet_addr(host);
-	hp = gethostbyaddr((char *) &ptd->ipaddr, sizeof(ptd->ipaddr), AF_INET);
-	if (hp == NULL) {
-	    memset(&ptd->hpbuf, 0, sizeof(ptd->hpbuf));
-	    ptd->hpbuf.h_name = 0;
-	    ptd->hpbuf.h_addrtype = AF_INET;
-	    ptd->hpbuf.h_length = sizeof(ptd->ipaddr);
-	    ptd->hpbuf.h_addr_list = ptd->charpbuf;
-	    ptd->hpbuf.h_addr_list[0] = (char *) &ptd->ipaddr;
-	    ptd->hpbuf.h_addr_list[1] = 0;
-	    hp = &ptd->hpbuf;
-	}
-    }
-    *reqhp = *hp;
-    return NULL;
-}
-
 static const char *
      proxy_get_host_of_request(request_rec *r)
 {
@@ -766,12 +729,8 @@
 /* Return TRUE if addr represents an IP address (or an IP network address) */
 static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r)
 {
-    int i;
-    int ip_addr[4];
-    struct in_addr addr;
-    struct in_addr *ip_list;
-    char **ip_listptr;
-    const char *found;
+    int i, ip_addr[4];
+    struct in_addr addr, *ip;
     const char *host = proxy_get_host_of_request(r);
 
     if (host == NULL)   /* oops! */
@@ -807,48 +766,46 @@
 #endif
     }
     else {
-	struct hostent the_host;
-
-	memset(&the_host, '\0', sizeof the_host);
-	found = ap_proxy_host2addr(host, &the_host);
+	struct apr_sockaddr_t *reqaddr;
 
-	if (found != NULL) {
+        if (apr_sockaddr_info_get(&reqaddr, host, APR_UNSPEC, 0, 0, r->pool)
+	    != APR_SUCCESS) {
 #if DEBUGGING
-        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
-                         "2)IP-NoMatch: hostname=%s msg=%s", host, found);
+	    ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+			 "2)IP-NoMatch: hostname=%s msg=Host not found", 
+			 host);
 #endif
 	    return 0;
 	}
 
-	if (the_host.h_name != NULL)
-	    found = the_host.h_name;
-	else
-	    found = host;
-
 	/* Try to deal with multiple IP addr's for a host */
-	for (ip_listptr = the_host.h_addr_list; *ip_listptr; ++ip_listptr) {
-	    ip_list = (struct in_addr *) *ip_listptr;
-	    if (This->addr.s_addr == (ip_list->s_addr & This->mask.s_addr)) {
+	/* FIXME: This needs to be able to deal with IPv6 */
+	while (reqaddr) {
+	    ip = (struct in_addr *) reqaddr->ipaddr_ptr;
+	    if (This->addr.s_addr == (ip->s_addr & This->mask.s_addr)) {
 #if DEBUGGING
-        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
-                       "3)IP-Match: %s[%s] <-> ", found, inet_ntoa(*ip_list));
-        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
-                       "%s/", inet_ntoa(This->addr));
-        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
-                       "%s", inet_ntoa(This->mask));
+		ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+			     "3)IP-Match: %s[%s] <-> ", host, 
+			     inet_ntoa(*ip));
+		ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+			     "%s/", inet_ntoa(This->addr));
+		ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+			     "%s", inet_ntoa(This->mask));
 #endif
 		return 1;
 	    }
 #if DEBUGGING
 	    else {
                 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
-                       "3)IP-NoMatch: %s[%s] <-> ", found, inet_ntoa(*ip_list));
+			     "3)IP-NoMatch: %s[%s] <-> ", host, 
+			     inet_ntoa(*ip));
                 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
-                       "%s/", inet_ntoa(This->addr));
+			     "%s/", inet_ntoa(This->addr));
                 ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
-                       "%s", inet_ntoa(This->mask));
+			     "%s", inet_ntoa(This->mask));
 	    }
 #endif
+	    reqaddr = reqaddr->next;
 	}
     }
 
@@ -908,81 +865,29 @@
     return h_len > d_len
 	&& strncasecmp(&host[h_len - d_len], This->name, d_len) == 0;
 }
-
-/* Create a copy of a "struct hostent" record; it was presumably returned
- * from a call to gethostbyname() and lives in static storage.
- * By creating a copy we can tuck it away for later use.
- */
-static struct hostent * pduphostent(apr_pool_t *p, const struct hostent *hp)
-{
-    struct hostent *newent;
-    char	  **ptrs;
-    char	  **aliases;
-    struct in_addr *addrs;
-    int		   i = 0, j = 0;
-
-    if (hp == NULL)
-	return NULL;
-
-    /* Count number of alias entries */
-    if (hp->h_aliases != NULL)
-	for (; hp->h_aliases[j] != NULL; ++j)
-	    continue;
-
-    /* Count number of in_addr entries */
-    if (hp->h_addr_list != NULL)
-	for (; hp->h_addr_list[i] != NULL; ++i)
-	    continue;
-
-    /* Allocate hostent structure, alias ptrs, addr ptrs, addrs */
-    newent = (struct hostent *) apr_palloc(p, sizeof(*hp));
-    aliases = (char **) apr_palloc(p, (j+1) * sizeof(char*));
-    ptrs = (char **) apr_palloc(p, (i+1) * sizeof(char*));
-    addrs  = (struct in_addr *) apr_palloc(p, (i+1) * sizeof(struct in_addr));
-
-    *newent = *hp;
-    newent->h_name = apr_pstrdup(p, hp->h_name);
-    newent->h_aliases = aliases;
-    newent->h_addr_list = (char**) ptrs;
-
-    /* Copy Alias Names: */
-    for (j = 0; hp->h_aliases[j] != NULL; ++j) {
-       aliases[j] = apr_pstrdup(p, hp->h_aliases[j]);
-    }
-    aliases[j] = NULL;
-
-    /* Copy address entries */
-    for (i = 0; hp->h_addr_list[i] != NULL; ++i) {
-	ptrs[i] = (char*) &addrs[i];
-	addrs[i] = *(struct in_addr *) hp->h_addr_list[i];
-    }
-    ptrs[i] = NULL;
-
-    return newent;
-}
 
-/* Return TRUE if addr represents a host name */
+/* Return TRUE if host represents a host name */
 PROXY_DECLARE(int) ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p)
 {
-    struct hostent host;
-    char *addr = This->name;
+    struct apr_sockaddr_t *addr;
+    char *host = This->name;
     int i;
 
     /* Host names must not start with a '.' */
-    if (addr[0] == '.')
+    if (host[0] == '.')
 	return 0;
 
     /* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */
-    for (i = 0; apr_isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i);
+    for (i = 0; apr_isalnum(host[i]) || host[i] == '-' || host[i] == '.'; ++i);
 
-    if (addr[i] != '\0' || ap_proxy_host2addr(addr, &host) != NULL)
+    if (host[i] != '\0' || apr_sockaddr_info_get(&addr, host, APR_UNSPEC, 0, 0, p) != APR_SUCCESS)
 	return 0;
-
-    This->hostentry = pduphostent (p, &host);
+    
+    This->hostaddr = addr;
 
     /* Strip trailing dots */
-    for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i)
-	addr[i] = '\0';
+    for (i = strlen(host) - 1; i > 0 && host[i] == '.'; --i)
+	host[i] = '\0';
 
     This->matcher = proxy_match_hostname;
     return 1;
@@ -1003,12 +908,14 @@
     h1_len = strlen(host);
 
 #if 0
-    unsigned long *ip_list;
+    struct apr_sockaddr_t *addr = *This->hostaddr;
 
     /* Try to deal with multiple IP addr's for a host */
-    for (ip_list = *This->hostentry->h_addr_list; *ip_list != 0UL; ++ip_list)
-	if (*ip_list == ? ? ? ? ? ? ? ? ? ? ? ? ?)
+    while (addr) {
+	if (addr->ipaddr_ptr == ? ? ? ? ? ? ? ? ? ? ? ? ?)
 	    return 1;
+	addr = addr->next;
+    }
 #endif
 
     /* Ignore trailing dots in host2 comparison: */
@@ -1182,8 +1089,3 @@
 }
 
 #endif
-
-static struct per_thread_data *get_per_thread_data(void)
-{
-    return NULL;
-}


Victor
-- 
Victor J. Orlikowski   | The Wall is Down, But the Threat Remains!
==================================================================
v.j.orlikowski@gte.net | orlikowski@apache.org | vjo@us.ibm.com

Re: gethostbyname threadsafe

Posted by Graham Leggett <mi...@sharp.fm>.
"Victor J. Orlikowski" wrote:

> I'm hoping there's no good reason that there has not been an
> apr_gethostbyname function yet.
> If so, I'll implement it, and then use that to take core of this
> little dilemma.
> 
> Work for everyone?

The last remaining gethostbyname in proxy_util is a remnant of the old
proxy. There is an option called NoProxy which can be configured to
exclude hosts...

...but this option is presently IPV6 non-aware - and needs to be
changed. If also needs to be changed to use apr_getaddr (I think,
whatever the rest of the proxy uses).

I know precious little about IPv6... :(

Regards,
Graham
-- 
-----------------------------------------
minfrin@sharp.fm		"There's a moon
					over Bourbon Street
						tonight..."

Re: gethostbyname threadsafe

Posted by Chuck Murcko <ch...@topsail.org>.
+1. The more generic stuff we can move from proxy_util.c to the core, 
the better.

Chuck

On Monday, July 23, 2001, at 02:50 PM, Victor J. Orlikowski wrote:

> I'm hoping there's no good reason that there has not been an
> apr_gethostbyname function yet.
> If so, I'll implement it, and then use that to take core of this
> little dilemma.
>
> Work for everyone?

Chuck Murcko
Topsail Group
http://www.topsail.org/

Re: gethostbyname threadsafe

Posted by "Victor J. Orlikowski" <v....@gte.net>.
I'm hoping there's no good reason that there has not been an
apr_gethostbyname function yet.
If so, I'll implement it, and then use that to take core of this
little dilemma.

Work for everyone?

Victor
-- 
Victor J. Orlikowski   | The Wall is Down, But the Threat Remains!
==================================================================
v.j.orlikowski@gte.net | orlikowski@apache.org | vjo@us.ibm.com

Re: gethostbyname threadsafe

Posted by Ian Holsman <ia...@cnet.com>.
Graham Leggett wrote:

>Hi all,
>
>Has mod_proxy been patched yet for gethostbyname threadsafe-ness? Does
>anything need to be done?
>
>Regards,
>Graham 
>
i think we call it once in proxy_util

we probably need to do the same logic that justin did in the APR,
or better yet make it a APR call which has all the ifdefs


(BTW..I'm off for a week..starting today..)

..Ian