[icecast-dev] src/net/resolver.c patches for better IPv6 resolution
BOUWSMA Beery
beerstream at ipv6.netscum.dyndns.dk
Sun Sep 29 11:32:15 PDT 2002
[caution: this is an IPv6 e-mail address. if you don't have
IPv6-capable mail then best keep replies on the list only]
> >existing getipnodebyname() call fails with IPv4 on my machine)...
> Well, if you can make it work properly - send your patches in, please.
The following enhancements to src/net/resolver.c (which looks identical
across icecast, ices, libshout, and who knows what all) suffice here to
get the test_resolver.c program to produce useful output on my FreeBSD
machine -- if it's true that (some) Linux doesn't have getipnodebyname()
then a different solution might be needed.
The results when built with -DHAVE_IPV6=1 -DHAVE_GETIPNODEBYNAME=1
added to the Makefile DEFS on my FreeBSD 4.x:
I got 172.27.72.27, when looking up stable.netscum.dyndns.dk.
I got 2002:50da:100d:0:250:daff:fe21:edca, when looking up ipv6.netscum.dyndns.d
k.
I got 2002:50da:100d:0:250:daff:fe21:edca, when looking up netscum.dyndns.dk.
I got ::1, when looking up localhost.
I got news-feed02.inet.tele.dk, when looking up 193.162.153.122.
I got swi6netCE1-A2-0-1.switch.ch, when looking up 2001:620:0:39::1.
I got localhost, when looking up ::1.
Much more satisfying than before.
The results without the above added DEFS:
I got (null), when looking up ipv6.netscum.dyndns.dk.
I got 80.218.16.13, when looking up netscum.dyndns.dk.
I got news-feed02.inet.tele.dk, when looking up 193.162.153.122.
I got (null), when looking up 10.0.2.53.
I got 2001:620:0:39::1, when looking up 2001:620:0:39::1.
Now the question, for which I started to hack a bit:
On an IPv6-aware system, _isip("2001:620:0:39::1") is true.
On a non-IPv6-aware system, it's false, even though that's an IP
of the IPv6 family. Should it be true?
And if it's false, as you can see, it's interpreted as a hostname,
and returned by resolver_getname(), instead of returning (null).
Should I bother with this at all? (For example, should resolver_getname()
verify that what it's returning is in fact a hostname and not garbage?)
<p>Anyway, the patch. I'm sure there's a better way to do this, as
I don't know what I'm doing, so I'd like to know what IPv6-capable
OSen aren't able to get proper results -- it appears to work on my
FreeBSD machine... Did I say I have no clue what I'm doing yet?
<p>--- resolver.c-ORIG Mon Aug 5 16:48:03 2002
+++ resolver.c Sun Sep 29 19:43:54 2002
@@ -42,6 +42,13 @@
static mutex_t _resolver_mutex;
static int _initialized = 0;
+/* ugly hacks */
+struct in_addr inp;
+union {
+ struct in_addr v4addr;
+ struct in6_addr v6addr;
+} addr_u;
+
char *resolver_getname(const char *ip, char *buff, int len)
{
if (!_isip(ip)) {
@@ -65,18 +72,11 @@
static int _isip(const char *what)
{
#ifdef HAVE_IPV6
- union {
- struct in_addr v4addr;
- struct in6_addr v6addr;
- } addr_u;
-
if (inet_pton(AF_INET, what, &addr_u.v4addr) <= 0)
return inet_pton(AF_INET6, what, &addr_u.v6addr) > 0 ? 1 : 0;
return 1;
#else
- struct in_addr inp;
-
return inet_aton(what, &inp);
#endif
}
@@ -87,27 +87,56 @@
#ifdef HAVE_GETIPNODEBYNAME
int err;
#else
- struct in_addr inp;
+ char *temp;
#endif
struct hostent *host = NULL;
- char *temp;
/* do a little sanity checking */
if (what == NULL || buff == NULL || len <= 0)
return NULL;
#ifdef HAVE_GETIPNODEBYNAME
- host = getipnodebyname(what, AF_INET6, AI_DEFAULT, &err);
- if (host) {
- if (_isip(what))
+ if (_isip(what)) {
+ /* According to FreeBSD's man page, getipnodebyname and such
+ * aren't threadsafe either */
+ _lock_resolver();
+ host = getipnodebyaddr(&addr_u.v4addr, sizeof(struct in_addr),
+ AF_INET, &err);
+ _unlock_resolver();
+ if (host == NULL) {
+ _lock_resolver();
+ host = getipnodebyaddr(&addr_u.v6addr,
+ sizeof(struct in6_addr), AF_INET6, &err);
+ _unlock_resolver();
+ }
+ if (host == NULL) {
+ buff = NULL;
+ } else {
strncpy(buff, host->h_name, len);
- else
- inet_ntop(host->h_addrtype, host->h_addr_list[0], buff, len);
-
- freehostent(host);
- } else
- buff = NULL;
-#else
+ freehostent(host);
+ }
+ } else {
+ /* According to FreeBSD's man page, getipnodebyname and such
+ * aren't threadsafe either */
+ _lock_resolver();
+ /* Try IPv6 if available and configured; else try IPv4 */
+ host = getipnodebyname(what, AF_INET6, AI_ADDRCONFIG, &err);
+ _unlock_resolver();
+ if (host == NULL) {
+ _lock_resolver();
+ host = getipnodebyname(what, AF_INET, AI_ADDRCONFIG,
+ &err);
+ _unlock_resolver();
+ }
+ if (host) {
+ inet_ntop(host->h_addrtype, host->h_addr_list[0],
+ buff, len);
+ freehostent(host);
+ } else {
+ buff = NULL;
+ }
+ }
+#else /* HAVE_GETIPNODEBYNAME */
if (_isip(what)) {
/* gotta lock calls for now, since gethostbyname and such
* aren't threadsafe */
@@ -133,7 +162,7 @@
}
}
-#endif
+#endif /* HAVE_GETIPNODEBYNAME */
return buff;
}
thanks,
barry bouwsma, beer streamer
--- >8 ----
List archives: http://www.xiph.org/archives/
icecast project homepage: http://www.icecast.org/
To unsubscribe from this list, send a message to 'icecast-dev-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the Icecast-dev
mailing list