On Mon, Oct 29, 2007 at 09:31:06PM +0100, Christian Kellermann wrote:
Dear List,
this project seems to gain some speed again and I am very happy seeing the patches flowing around. I won't step back.
Good!
For I am running on a BSD I configured dillo2 with --disable-threaded-dns.
This won't compile because of this typo:
RCS file: /sfhome/cvs/dillo/dillo2/src/dns.c,v retrieving revision 1.2 diff -b -u -p -r1.2 dns.c --- dns.c 11 Oct 2007 18:55:13 -0000 1.2 +++ dns.c 29 Oct 2007 20:32:04 -0000 @@ -316,7 +316,7 @@ static void Dns_blocking_server(void) { int channel = 0; struct hostent *host = NULL; - dList *hosts = dList_new(2); + Dlist *hosts = dList_new(2); #ifdef LIBC5 int h_err; #endif
Commited.
Also I experience crashes every time I try to open a URL. See the backtrace attached to this message. In this example I am using a privoxy http proxy. The crashes occur independendly from this. Can someone point me to the right direction? I am using the stock dillorc2 and OpenBSD-4.1 on a i386.
Thanks for your hints!
Thank you Jorge!
Good timing you have (as Yoda says). I've been working on this a couple of days. Just test latest CVS and let me know if it works for you (same for Jan S.). -- Cheers Jorge.-
* Jorge Arellano Cid <jcid@dillo.org> [071029 23:20]:
Good timing you have (as Yoda says).
I've been working on this a couple of days. Just test latest CVS and let me know if it works for you (same for Jan S.).
AH! Yes, dillo has become usable now. Sites are rendered (and redrawn alot but this is another issue to be addressed) but the race condition seems to be gone now. Thanks! Another thing: Actually what is the dw-testbed for? Will the code from there slowly merge into dillo2? Or am I missing something... Cheers, Christian -- You may use my gpg key for replies: pub 1024D/47F79788 2005/02/02 Christian Kellermann (C-Keen)
Hello, as I'm also using a BSD system, I converted the D_DNS_THREADED code to use the inherently thread-safe getaddrinfo(3) interface that also has some other advantages (e.g. a predictable ordering of the returned addresses). Jorge, what do you think about this? Are there supported platforms that do not have getaddrinfo? Should we add a compile option for this? Johannes diff --git a/src/dns.c b/src/dns.c --- a/src/dns.c +++ b/src/dns.c @@ -239,58 +239,86 @@ static void Dns_note_hosts(Dlist *list, } } +static void Dns_note_hosts2(Dlist *list, struct addrinfo *res0) +{ + struct addrinfo *res; + DilloHost *dh; + + for (res = res0; res; res = res->ai_next) { + + if (res->ai_family == AF_INET) { + struct sockaddr_in *in_addr; + + if (res->ai_addrlen < sizeof(struct sockaddr_in)) { + continue; + } + + dh = dNew0(DilloHost, 1); + dh->af = AF_INET; + + in_addr = (struct sockaddr_in*) res->ai_addr; + dh->alen = sizeof (struct in_addr); + memcpy(&dh->data[0], &in_addr->sin_addr.s_addr, dh->alen); + + dList_append(list, dh); +#ifdef ENABLE_IPV6 + } else if (res->ai_family == AF_INET6) { + struct sockaddr_in6 *in6_addr; + + if (res->ai_addrlen < sizeof(struct sockaddr_in6)) { + continue; + } + + dh = dNew0(DilloHost, 1); + dh->af = AF_INET6; + + in6_addr = (struct sockaddr_in6*) res->ai_addr; + dh->alen = sizeof (struct in6_addr); + memcpy(&dh->data[0], &in6_addr->sin6_addr.s6_addr, dh->alen); + + dList_append(list, dh); +#endif + } + } +} + #ifdef D_DNS_THREADED /* * Server function (runs on its own thread) */ static void *Dns_server(void *data) { - struct hostent *host; int channel = VOIDP2INT(data); -#ifdef LIBC5 - int h_err; - char buff[1024]; - struct hostent sh; -#endif + struct addrinfo hints, *res0; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_INET; + hints.ai_socktype = SOCK_STREAM; + Dlist *hosts = dList_new(2); DEBUG_MSG(3, "Dns_server: starting...\n ch: %d host: %s\n", channel, dns_server[channel].hostname); -#ifdef ENABLE_IPV6 - if (ipv6_enabled) { - host = gethostbyname2(dns_server[channel].hostname, AF_INET6); - if (host) { - Dns_note_hosts(hosts, AF_INET6, host); - } - } -#endif - -#ifdef LIBC5 - host = gethostbyname_r(dns_server[channel].hostname, &sh, buff, - sizeof(buff), &h_err); -#else - host = gethostbyname(dns_server[channel].hostname); -#endif - - if (!host) { -#ifdef LIBC5 - dns_server[channel].status = h_err; -#else - dns_server[channel].status = h_errno; - if (h_errno == HOST_NOT_FOUND) + error = getaddrinfo(dns_server[channel].hostname, NULL, &hints, &res0); + + if (error != 0) { + dns_server[channel].status = error; + if (error == EAI_NONAME) MSG("DNS error: HOST_NOT_FOUND\n"); - else if (h_errno == TRY_AGAIN) + else if (error == EAI_AGAIN) MSG("DNS error: TRY_AGAIN\n"); - else if (h_errno == NO_RECOVERY) - MSG("DNS error: NO_RECOVERY\n"); - else if (h_errno == NO_ADDRESS) + else if (error == EAI_NODATA) MSG("DNS error: NO_ADDRESS\n"); -#endif - } else { + else if (h_errno == EAI_FAIL) + MSG("DNS error: NO_RECOVERY\n"); + } else { + Dns_note_hosts2(hosts, res0); dns_server[channel].status = 0; - Dns_note_hosts(hosts, AF_INET, host); - } + freeaddrinfo(res0); + } + if (dList_length(hosts) > 0) { dns_server[channel].status = 0; } else { diff --git a/src/dns.h b/src/dns.h --- a/src/dns.h +++ b/src/dns.h @@ -1,5 +1,7 @@ #ifndef __DNS_H__ #define __DNS_H__ + +#include <netinet/in.h> #include "chain.h" @@ -14,7 +16,7 @@ void a_Dns_freeall(void); void a_Dns_freeall(void); void a_Dns_resolve(const char *hostname, DnsCallback_t cb_func, void *cb_data); -#define DILLO_ADDR_MAX 16 +#define DILLO_ADDR_MAX sizeof(struct in6_addr) typedef struct _DilloHost {
* Johannes Hofmann <Johannes.Hofmann@gmx.de> [071104 14:50]:
Hello,
as I'm also using a BSD system, I converted the D_DNS_THREADED code to use the inherently thread-safe getaddrinfo(3) interface that also has some other advantages (e.g. a predictable ordering of the returned addresses).
Thanks, I will try this. Is you git repo public? Regards, Christian -- You may use my gpg key for replies: pub 1024D/47F79788 2005/02/02 Christian Kellermann (C-Keen)
Hi Johannes, On Sun, Nov 04, 2007 at 01:48:50PM +0100, Johannes Hofmann wrote:
Hello,
as I'm also using a BSD system, I converted the D_DNS_THREADED code to use the inherently thread-safe getaddrinfo(3) interface that also has some other advantages (e.g. a predictable ordering of the returned addresses). Jorge, what do you think about this? Are there supported platforms that do not have getaddrinfo? Should we add a compile option for this?
I gave it a look. AFAIS there're a few ways to do it. Considering that getaddrinfo is thread-safe by definition and also inside POSIX, it's a good candidate. The gethostbyname* family is thread-safe in glibc2, but who knows in other libraries. dns.c has too much #defines for my taste (yes, I wrote it! ;-), and getting rid of the libc5 lines may also help simplicity. I'd say, get the current CVS (patch applied), please also convert Dns_blocking_server to getaddrinfo, and get rid of libc5 lines. That way we end with a cleaner dns.c and will know for sure who still may need the missing lines, because they can ask in dillo-dev. OTOH, if we provide all the options at compile time, we may end not knowing whether they're still used or not. -- Cheers Jorge.-
Hi Jorge, On Mon, Nov 05, 2007 at 12:38:16PM -0300, Jorge Arellano Cid wrote:
Hi Johannes,
On Sun, Nov 04, 2007 at 01:48:50PM +0100, Johannes Hofmann wrote:
Hello,
as I'm also using a BSD system, I converted the D_DNS_THREADED code to use the inherently thread-safe getaddrinfo(3) interface that also has some other advantages (e.g. a predictable ordering of the returned addresses). Jorge, what do you think about this? Are there supported platforms that do not have getaddrinfo? Should we add a compile option for this?
I gave it a look.
AFAIS there're a few ways to do it.
Considering that getaddrinfo is thread-safe by definition and also inside POSIX, it's a good candidate. The gethostbyname* family is thread-safe in glibc2, but who knows in other libraries.
dns.c has too much #defines for my taste (yes, I wrote it! ;-), and getting rid of the libc5 lines may also help simplicity.
Exactly.
I'd say, get the current CVS (patch applied), please also convert Dns_blocking_server to getaddrinfo, and get rid of libc5 lines. That way we end with a cleaner dns.c and will know for sure who still may need the missing lines, because they can ask in dillo-dev.
Ok, I will do that. I also think we should keep the Dns_blocking_server for now.
OTOH, if we provide all the options at compile time, we may end not knowing whether they're still used or not.
Very true. Cheers, Johannes
Ok, here is a patch that removes the LIBC5 special case and uses getaddrinfo() also if --disable-threaded-dns is specified. As far as I could see there were no real differences other than logging between Dns_server() and Dns_blocking_server(), or am I missing something? Cheers, Johannes diff --git a/src/dns.c b/src/dns.c --- a/src/dns.c +++ b/src/dns.c @@ -39,11 +39,6 @@ * Uncomment the following line for debugging or gprof profiling. */ /* #undef D_DNS_THREADED */ - -/* - * Uncomment the following line for libc5 optimization - */ -/* #define LIBC5 */ /* Maximum dns resolving threads */ @@ -224,22 +219,8 @@ void a_Dns_init(void) /* * Allocate a host structure and add it to the list */ -static void Dns_note_hosts(Dlist *list, int af, struct hostent *host) -{ - int i; - if (host->h_length > DILLO_ADDR_MAX) - return; - for (i = 0; host->h_addr_list[i]; i++) { - DilloHost *dh = dNew0(DilloHost, 1); - dh->af = af; - dh->alen = host->h_length; - memcpy(&dh->data[0], host->h_addr_list[i], (size_t)host->h_length); - dList_append(list, dh); - } -} - -static void Dns_note_hosts2(Dlist *list, struct addrinfo *res0) +static void Dns_note_hosts(Dlist *list, struct addrinfo *res0) { struct addrinfo *res; DilloHost *dh; @@ -282,7 +263,6 @@ static void Dns_note_hosts2(Dlist *list, } } -#ifdef D_DNS_THREADED /* * Server function (runs on its own thread) */ @@ -314,7 +294,7 @@ static void *Dns_server(void *data) else if (h_errno == EAI_FAIL) MSG("DNS error: NO_RECOVERY\n"); } else { - Dns_note_hosts2(hosts, res0); + Dns_note_hosts(hosts, res0); dns_server[channel].status = 0; freeaddrinfo(res0); } @@ -334,67 +314,7 @@ static void *Dns_server(void *data) return NULL; /* (avoids a compiler warning) */ } -#endif -#ifndef D_DNS_THREADED -/* - * Blocking server-function (it doesn't use threads) - */ -static void Dns_blocking_server(void) -{ - int channel = 0; - struct hostent *host = NULL; - Dlist *hosts = dList_new(2); -#ifdef LIBC5 - int h_err; -#endif - - DEBUG_MSG(3, "Dns_blocking_server: starting...\n"); - DEBUG_MSG(3, "Dns_blocking_server: dns_server[%d].hostname = %s\n", - channel, dns_server[channel].hostname); - -#ifdef ENABLE_IPV6 - if (ipv6_enabled) { - host = gethostbyname2(dns_server[channel].hostname, AF_INET6); - if (host) { - Dns_note_hosts(hosts, AF_INET6, host); - } - } -#endif - -#ifdef LIBC5 - host = gethostbyname_r(dns_server[channel].hostname, &sh, buff, - sizeof(buff), &h_err); -#else - host = gethostbyname(dns_server[channel].hostname); -#endif - - if (!host) { -#ifdef LIBC5 - dns_server[channel].status = h_err; -#else - dns_server[channel].status = h_errno; -#endif - } else { - Dns_note_hosts(hosts, AF_INET, host); - } - if (dList_length(hosts) > 0) { - /* at least one entry on the list is ok */ - dns_server[channel].status = 0; - } else { - dList_free(hosts); - hosts = NULL; - } - - /* write IP to server data channel */ - DEBUG_MSG(3, "Dns_blocking_server: IP of %s is %p\n", - dns_server[channel].hostname, hosts); - dns_server[channel].addr_list = hosts; - dns_server[channel].ip_ready = TRUE; - - DEBUG_MSG(3, "Dns_blocking_server: leaving...\n"); -} -#endif /* * Request function (spawn a server and let it handle the request) @@ -426,7 +346,7 @@ static void Dns_server_req(int channel, pthread_create(&dns_server[channel].th1, &thrATTR, Dns_server, INT2VOIDP(dns_server[channel].channel)); #else - Dns_blocking_server(); + Dns_server(0); #endif }
On Mon, Nov 05, 2007 at 05:51:17PM +0100, Johannes Hofmann wrote:
Ok, here is a patch that removes the LIBC5 special case and uses getaddrinfo() also if --disable-threaded-dns is specified. As far as I could see there were no real differences other than logging between Dns_server() and Dns_blocking_server(), or am I missing something?
Commited. They're basically the same, but Dns_server runs in a thread and doesn't block the browser (with a max. of 4). The other blocks until the resolving function returns. It looks ok. -- Cheers Jorge.-
participants (3)
-
Christian.Kellermann@nefkom.net
-
jcid@dillo.org
-
Johannes.Hofmann@gmx.de