Broken ipv6 behavior?

View: New views
15 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 | Next >

Re: : Broken ipv6 behavior?

by Matthew Dempsky-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Apr 9, 2008 at 8:05 AM, Rory Byrne <rory@...> wrote:
>  Might be a problem. I'm guessing that most people are
>  going to expect to resolve all their DNS queries over
>  IPv4 for many years to come. I would have assumed the
>  following:

Setting {inet6, true} only changes inet:gethostbyname/1 to default to
asking for an inet6 address before falling back to inet.  It doesn't
affect what network layer Erlang uses to communicate with the DNS
cache.
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: : : Broken ipv6 behavior?

by Matthew Dempsky-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Apr 9, 2008 at 9:03 AM, Raimo Niskanen
<raimo+erlang-questions@...> wrote:
>  In that case I can report that:
>  1> inet:gethostbyname("orange.kame.net", inet6).
>  {ok,{hostent,"orange.kame.net",[],inet6,16,
>              [{0,0,0,0,0,65535,52146,36290}]}}
>  works on:
>  Darwin hostname 9.2.2 Darwin Kernel Version 9.2.2: Tue Mar  4 21:17:34 PST 2008; root:xnu-1228.4.31~1/RELEASE_I386 i386
>  Which should be MacOS X Leopard

That's not the correct result though.  That's an IPv4 mapped address
for a node name that has actual IPv6 addresses.

Having IPv6 support is silly if the only hosts you can access are ones
that also have IPv4.
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: : Broken ipv6 behavior?

by Matthew Dempsky-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Apr 9, 2008 at 3:41 AM, Matthew Dempsky <matthew@...> wrote:
>  Testing at home with OS X (IPv6 link-local access only), I get
>  {error,notfound} with or without {inet6, true}.
>
>  ipv6.google.com's AAAA records still resolve fine with dig/host/etc.

I see the same behavior with a globally routable local IPv6 address.

matthew@pollux:~$ erl
Erlang (BEAM) emulator version 5.6.1 [source] [smp:2]
[async-threads:0] [kernel-poll:false]

Eshell V5.6.1  (abort with ^G)
1> inet_gethost_native:control({debug_level,4}).
ok
2> inet_gethost[68255] (DEBUG):debug_level = 4
inet_gethost_native:gethostbyname("ipv6.google.com", inet6).
inet_gethost[68255] (DEBUG):Saved domainname .google.com.
inet_gethost[68255] (DEBUG):Created worker[68256] with fd 3
inet_gethost[68255] (DEBUG):Saved domainname .google.com.
inet_gethost[68256] (DEBUG):Worker got request, op = 1, proto = 2,
data = ipv6.google.com.
{error,notfound}
3> ets:tab2list(inet_db).
[{socks5_noproxy,[]},
 {res_recurse,1},
 {res_id,0},
 {hostname,"pollux"},
 {res_alt_ns,[]},
 {cache_refresh_interval,3600000},
 {res_inet6,false},
 {socks5_port,1080},
 {socks5_methods,[none]},
 {res_timeout,2000},
 {cache_size,100},
 {res_domain,"local"},
 {res_retry,3},
 {res_ns,[]},
 {res_lookup,[native,file]},
 {sctp_module,inet_sctp},
 {udp_module,inet_udp},
 {tcp_module,inet_tcp},
 {socks5_server,[]},
 {res_search,["local"]},
 {res_usevc,false}]
4> ets:tab2list(inet_hosts).
[{{10,0,1,195},inet,["pollux.local","pollux"]}]
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: Broken ipv6 behavior?

by Mikael Magnusson-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Raimo Niskanen wrote:

> Give us the result of:
> $ uname -a
> $ cat /etc/resolv.conf
> $ erl
> 1> inet_gethost_native:control({debug_level,4}).
> 2> inet_gethost_native:gethostbyname("ipv6.google.com", inet6).
> 3> ets:tab2list(inet_db).
> 4> ets:tab2list(inet_hosts).
>
> For starters.
>

It looks beautiful on Debian Lenny/Sid GNU/Linux, which contains my IPv6
patch:

1> inet_gethost_native:gethostbyname("ipv6.google.com", inet6).
{ok,{hostent,"ipv6.l.google.com",
              ["ipv6.google.com"],
              inet6,16,
              [{8193,18528,0,4097,0,0,0,104}]}}

(The patch is also used in Ubuntu.)

/Mikael
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: : Broken ipv6 behavior?

by Rory Byrne-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Apr 09, 2008 at 11:08:55AM -0700, Matthew Dempsky wrote:

> On Wed, Apr 9, 2008 at 8:05 AM, Rory Byrne <rory@...> wrote:
> >  Might be a problem. I'm guessing that most people are
> >  going to expect to resolve all their DNS queries over
> >  IPv4 for many years to come. I would have assumed the
> >  following:
>
> Setting {inet6, true} only changes inet:gethostbyname/1 to default to
> asking for an inet6 address before falling back to inet.  It doesn't
> affect what network layer Erlang uses to communicate with the DNS
> cache.

I should of tapped the source on that one - less of this
speculation stuff. Cheers!

_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: : : Broken ipv6 behavior?

by Fredrik Thulin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Raimo Niskanen wrote:
...
> In this particular case there has to be an investigation
> in if the test suites are wrong or the implementation,
> or the test site (DNS vs NIS).
>
> Would it be acceptable that there are no hostent aliases
> on getaddrinfo hosts but there are on getipnodebyname
> hosts?

It sounds icky to have different results based on what the libc you are
using supports, but NIS is as far as I'm concerned totally irrelevant
(today) - the world runs on DNS! ;)

So to put it differently - I'd rather have working IPv6 hostname
resolving, than support for struct hostent aliases at all.

> Or since there is alias information in DNS,
> should the inet_gethost_native code be able to
> find alias information also on getaddrinfo hosts?
> And how?

How do you mean? In DNS, aliases are CNAMEs, DNAMEs (not very widely
used) or if you stretch the definition a bit - multiple A records
pointing at the same IP address.

There is no way to ask DNS "what is all the aliases for host
www.example.com?" or "what is all the names for IP 192.0.2.2?". The
reason for this? There is no central place to ask, so you can't know if
someone far far away has created an alias pointing at you.

To illustrate - you have a CNAME pointing www3.erlang.org at
erlang.mirrors.su.se (which in turn happens to be an alias for
afs-ftp1.it.su.se). There can be aliases to one of _my_ hosts in _any_
domain on the internet.

/Fredrik
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: : : Broken ipv6 behavior?

by Rory Byrne-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Apr 09, 2008 at 06:03:41PM +0200, Raimo Niskanen wrote:
> On Wed, Apr 09, 2008 at 05:05:56PM +0200, Rory Byrne wrote:
> >
> > Anyway, it appears that the problem is on the link
> > between erlang and the local resolver. However, if
>
> Or the local resolver configuration.
>

Yeah, fair point.

It's a good puzzle! I look forward to the Linux edition. :-)

Regards,

Rory
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: Broken ipv6 behavior?

by Matthew Dempsky-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Apr 9, 2008 at 1:00 PM, Mikael Magnusson <mikma264@...> wrote:
>  It looks beautiful on Debian Lenny/Sid GNU/Linux, which contains my IPv6
>  patch:

I applied the patch attached to
http://www.erlang.org/pipermail/erlang-questions/2006-November/024099.html
(needed to change www2 to www in the URL), but it doesn't work for me
on OS X.

OS X has getipnodebyname so the previous #ifdef runs first, but it
returns the wrong results (e.g., not finding ipv6.google.com and
returning an IPv4-mapped address instead of a native IPv6 address for
www.kame.net).  If I move the gethostbyname2 block first, then it
works fine for me.
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: : Broken ipv6 behavior?

by Raimo Niskanen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Apr 16, 2008 at 11:50:07AM -0700, Matthew Dempsky wrote:
> On Wed, Apr 9, 2008 at 1:00 PM, Mikael Magnusson <mikma264@...> wrote:
> >  It looks beautiful on Debian Lenny/Sid GNU/Linux, which contains my IPv6
> >  patch:
>
> I applied the patch attached to
> http://www.erlang.org/pipermail/erlang-questions/2006-November/024099.html
> (needed to change www2 to www in the URL), but it doesn't work for me
> on OS X.
>

That patch uses gethostbyname2, which is just as or even more obsoleted
than getipnodebyname. I wonder when I (finally) have added
getaddrinfo support if there is need for gethostbyname2 support too?

> OS X has getipnodebyname so the previous #ifdef runs first, but it
> returns the wrong results (e.g., not finding ipv6.google.com and
> returning an IPv4-mapped address instead of a native IPv6 address for
> www.kame.net).  If I move the gethostbyname2 block first, then it
> works fine for me.

It is strange getipnodebyname works so differently from gethostbyname2
on OS X. They should do the same job. The flags to getipnodebyname
are (AF_V4MAPPED | AI_ADDRINFO), which means that it should return
mapped v4 addresses only if no IPv6 addresses are found and
that it should return IPv6 addresses only if the machine runs
IPv6 ("Only if IPv6 configured" according to Solaris 10 headers,
"Only if there is an interface on the host that is not a loopback
interface that has an IPv6 address" according to Steven's
Unix Network Programming).

So maybe gethostbyname2 returns IPv6 records even though your
machine has no external IPv6 interface?

> _______________________________________________
> erlang-questions mailing list
> erlang-questions@...
> http://www.erlang.org/mailman/listinfo/erlang-questions

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: : Broken ipv6 behavior?

by Matthew Dempsky-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Apr 17, 2008 at 1:03 AM, Raimo Niskanen
<raimo+erlang-questions@...> wrote:
>  That patch uses gethostbyname2, which is just as or even more obsoleted
>  than getipnodebyname. I wonder when I (finally) have added
>  getaddrinfo support if there is need for gethostbyname2 support too?

I tested that patch because the author suggested it worked for him on
Linux, and it's a relatively non-intrusive change.  (I don't
particularly care what functions are used for IPv6 support as long as
they work.)

>  It is strange getipnodebyname works so differently from gethostbyname2
>  on OS X. They should do the same job.

Yeah.

>  The flags to getipnodebyname
>  are (AF_V4MAPPED | AI_ADDRINFO), which means that it should return
>  mapped v4 addresses only if no IPv6 addresses are found and
>  that it should return IPv6 addresses only if the machine runs
>  IPv6 ("Only if IPv6 configured" according to Solaris 10 headers,
>  "Only if there is an interface on the host that is not a loopback
>  interface that has an IPv6 address" according to Steven's
>  Unix Network Programming).

On OS X, AI_DEFAULT is defined to (AI_V4MAPPED_CFG | AI_ADDRCONFIG).

I tested various a few different flags options, and ipv6.google.com
would only resolve when AI_V4MAPPED(_CFG) was *not* set.  0 and
AI_ADDRCONFIG both returned an IPv6 hostent structure.

>  So maybe gethostbyname2 returns IPv6 records even though your
>  machine has no external IPv6 interface?

No, every test I have run regarding Erlang and IPv6 in this thread has
involved a machine with a globally routable IPv6 address configured.
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: : : Broken ipv6 behavior?

by Raimo Niskanen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Apr 17, 2008 at 01:18:06AM -0700, Matthew Dempsky wrote:

> On Thu, Apr 17, 2008 at 1:03 AM, Raimo Niskanen
> <raimo+erlang-questions@...> wrote:
> >  That patch uses gethostbyname2, which is just as or even more obsoleted
> >  than getipnodebyname. I wonder when I (finally) have added
> >  getaddrinfo support if there is need for gethostbyname2 support too?
>
> I tested that patch because the author suggested it worked for him on
> Linux, and it's a relatively non-intrusive change.  (I don't
> particularly care what functions are used for IPv6 support as long as
> they work.)
>

I am working on getaddrinfo support. When it seems to work I will publish
a source patch for OTP_R12B-2 and then start on the test cases,
to get feedback for a final version.

> >  It is strange getipnodebyname works so differently from gethostbyname2
> >  on OS X. They should do the same job.
>
> Yeah.
>
> >  The flags to getipnodebyname
> >  are (AF_V4MAPPED | AI_ADDRINFO), which means that it should return
> >  mapped v4 addresses only if no IPv6 addresses are found and
> >  that it should return IPv6 addresses only if the machine runs
> >  IPv6 ("Only if IPv6 configured" according to Solaris 10 headers,
> >  "Only if there is an interface on the host that is not a loopback
> >  interface that has an IPv6 address" according to Steven's
> >  Unix Network Programming).
>
> On OS X, AI_DEFAULT is defined to (AI_V4MAPPED_CFG | AI_ADDRCONFIG).
>
> I tested various a few different flags options, and ipv6.google.com
> would only resolve when AI_V4MAPPED(_CFG) was *not* set.  0 and
> AI_ADDRCONFIG both returned an IPv6 hostent structure.
>

The header files on MacOS X 10.5.2 says:
#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */

Would that indicate that the kernel does not support
mapped IPv4 addresses or what does it not support?

Is this a MacOS X support question?

Or just wait for the getaddrinfo patch and see if it works better.

> >  So maybe gethostbyname2 returns IPv6 records even though your
> >  machine has no external IPv6 interface?
>
> No, every test I have run regarding Erlang and IPv6 in this thread has
> involved a machine with a globally routable IPv6 address configured.
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@...
> http://www.erlang.org/mailman/listinfo/erlang-questions

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

IPv6 name resolver patch for R12B-2

by Raimo Niskanen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Apr 17, 2008 at 11:48:33AM +0200, Raimo Niskanen wrote:
:
>
> I am working on getaddrinfo support. When it seems to work I will publish
> a source patch for OTP_R12B-2 and then start on the test cases,
> to get feedback for a final version.

I now have a solution running in our daily builds.
I attach a patch for R12B-2. Please try it!

>
:
> > On OS X, AI_DEFAULT is defined to (AI_V4MAPPED_CFG | AI_ADDRCONFIG).
> >
> > I tested various a few different flags options, and ipv6.google.com
> > would only resolve when AI_V4MAPPED(_CFG) was *not* set.  0 and
> > AI_ADDRCONFIG both returned an IPv6 hostent structure.
> >

ipv6.google.com has no IPv4 address hence there can not exist
an IPv6 mapped IPv4 address for it. AI_V4MAPPED_CFG should not
affect pure IPv6 addresses.

>
> The header files on MacOS X 10.5.2 says:
> #define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */
>
> Would that indicate that the kernel does not support
> mapped IPv4 addresses or what does it not support?
>
> Is this a MacOS X support question?
>

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB


--- erts/configure.in@@//OTP_R12B-2 2008-04-07 15:58:03.000000000 +0200
+++ erts/configure.in 2008-04-23 10:28:02.000000000 +0200
@@ -1263,7 +1263,37 @@
 
 dnl Check if we have these, in which case we'll try to build
 dnl inet_gethost with ipv6 support.
-AC_CHECK_FUNCS([getipnodebyname getipnodebyaddr])
+AC_CHECK_FUNC(getaddrinfo, have_getaddrinfo=yes, have_getaddrinfo=no)
+if test $have_getaddrinfo = yes; then
+        AC_MSG_CHECKING([whether getaddrinfo accepts enough flags])
+        AC_TRY_RUN([
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netdb.h>
+int main(int argc, char **argv) {
+    struct addrinfo hints, *ai;
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_flags = (AI_CANONNAME|AI_V4MAPPED|AI_ADDRCONFIG);
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_family = AF_INET6;
+    if (getaddrinfo("::", NULL, &hints, &ai) == 0) {
+ freeaddrinfo(ai);
+ exit(0);
+    } else {
+ exit(1);
+    }
+}
+ ],, have_getaddrinfo=no)
+ if test $have_getaddrinfo = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_GETADDRINFO, [1],
+          [Define to 1 if you have a good `getaddrinfo' function.])
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+AC_CHECK_FUNCS([getnameinfo getipnodebyname getipnodebyaddr gethostbyname2])
 
 AC_CHECK_FUNCS([ieee_handler fpsetmask finite isnan isinf res_gethostbyname dlopen \
  pread pwrite writev memmove strerror strerror_r strncasecmp \
--- erts/etc/common/inet_gethost.c@@//OTP_R12B-2 2008-02-05 14:37:32.000000000 +0100
+++ erts/etc/common/inet_gethost.c 2008-04-23 11:02:53.000000000 +0200
@@ -23,6 +23,13 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+/* These are not used even if they would exist which they should not */
+#undef HAVE_GETADDRINFO
+#undef HAVE_GETIPNODEBYNAME
+#undef HAVE_GETHOSTBYNAME2
+#undef HAVE_GETNAMEINFO
+#undef HAVE_GETIPNODEBYADDR
+
 #else /* Unix */
 
 #include <stdio.h>
@@ -50,6 +57,24 @@
 #define RETSIGTYPE void
 #endif
 
+/* To simplify #ifdef code further down - select only one to be defined...
+** Use them in pairs - if one is broken do not trust its mate.
+**/
+#if defined(HAVE_GETADDRINFO) && defined(HAVE_GETNAMEINFO)
+#undef HAVE_GETIPNODEBYNAME
+#undef HAVE_GETIPNODEBYADDR
+#undef HAVE_GETHOSTBYNAME2
+#elif defined(HAVE_GETIPNODEBYNAME) && defined(HAVE_GETIPNODEBYADDR)
+#undef HAVE_GETADDRINFO
+#undef HAVE_GETNAMEINFO
+#undef HAVE_GETHOSTBYNAME2
+#else
+#undef HAVE_GETIPNODEBYNAME
+#undef HAVE_GETIPNODEBYADDR
+#undef HAVE_GETADDRINFO
+#undef HAVE_GETNAMEINFO
+#endif
+
 #endif /* !WIN32 */
 
 #define PACKET_BYTES 4
@@ -244,12 +269,19 @@
 static void put_int32(AddrByte *buff, int value);
 static int create_worker(Worker *pworker, int save_que);
 static int map_netdb_error(int netdb_code);
+#if defined(HAVE_GETADDRINFO) || defined(HAVE_GETNAMEINFO)
+static int map_netdb_error_ai(int netdb_code);
+#endif
 static char *errcode_to_string(int errcode);
 static size_t build_error_reply(SerialType serial, int errnum,
  AddrByte **preply,
  size_t *preply_size);
-static size_t build_reply(SerialType serial, struct hostent *he,
-  AddrByte **preply, size_t *preply_size);
+#ifdef HAVE_GETADDRINFO
+static size_t build_reply_ai(SerialType serial, int, struct addrinfo *,
+                            AddrByte **preply, size_t *preply_size);
+#endif
+static size_t build_reply(SerialType serial, struct hostent *he,
+                         AddrByte **preply, size_t *preply_size);
 static int read_request(AddrByte **buff, size_t *buff_size);
 static OpType get_op(AddrByte *buff);
 static AddrByte *get_op_addr(AddrByte *buff);
@@ -1553,19 +1585,13 @@
 static int worker_loop(void)
 #endif
 {
-    struct hostent *he;
     AddrByte *req = NULL;
     size_t req_size = 0;
     int this_size;
     AddrByte *reply = NULL;
     size_t reply_size = 0;
     size_t data_size;
-    int error_num;
-    SerialType serial;
-    OpType op;
-    ProtoType proto;
-    AddrByte *data;
-    int free_he;
+
 #ifdef WIN32
     QueItem *m = NULL;
     MesQ *readfrom = ((MesQ **) v)[0];
@@ -1574,6 +1600,23 @@
 #endif
 
     for(;;) {
+#ifdef HAVE_GETADDRINFO
+ struct addrinfo *ai = NULL;
+#endif
+ struct hostent *he = NULL;
+#ifdef HAVE_GETNAMEINFO
+ struct sockaddr *sa = NULL;
+ char name[NI_MAXHOST];
+#endif
+#if defined(HAVE_GETIPNODEBYNAME) || defined(HAVE_GETIPNODEBYADDR)
+ int free_he = 0;
+#endif
+ int error_num = 0;
+ SerialType serial;
+ OpType op;
+ ProtoType proto;
+ AddrByte *data;
+
 #ifdef WIN32
  WaitForSingleObject(event_mesq(readfrom),INFINITE);
  DEBUGF(4,("Worker got data on message que."));
@@ -1622,92 +1665,191 @@
  DEBUGF(4,("Worker got request, op = %d, proto = %d, data = %s.",
   op,proto,data));
  /* Got a request, lets go... */
- free_he = 0;
  switch (op) {
  case OP_GETHOSTBYNAME:
-    if (proto != PROTO_IPV4) {
-#if defined(HAVE_GETIPNODEBYNAME) && !defined(WIN32) /* IP V6 support */
- if (proto == PROTO_IPV6) {
-    he = getipnodebyname(data, AF_INET6, AI_DEFAULT,
- &error_num);
+    switch (proto) {
+
+#ifdef HAVE_IN6
+    case PROTO_IPV6: { /* switch (proto) { */
+#ifdef HAVE_GETADDRINFO
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = (AI_CANONNAME|AI_V4MAPPED|AI_ADDRCONFIG);
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_family = AF_INET6;
+ DEBUGF(5, ("Starting getaddrinfo(%s, ...)", data));
+ error_num = getaddrinfo((char *)data, NULL, &hints, &ai);
+ DEBUGF(5,("getaddrinfo returned %d", error_num));
+ if (error_num) {
+    error_num = map_netdb_error_ai(error_num);
+ }
+#elif defined(HAVE_GETIPNODEBYNAME) /*#ifdef HAVE_GETADDRINFO */
+ DEBUGF(5,("Starting getipnodebyname(%s)",data));
+ he = getipnodebyname(data, AF_INET6, AI_DEFAULT, &error_num);
+ if (he) {
     free_he = 1;
+    error_num = 0;
+    DEBUGF(5,("getipnodebyname(,AF_INET6,,) OK"));
+ } else {
+    DEBUGF(5,("getipnodebyname(,AF_INET6,,) error", error_num));
     error_num = map_netdb_error(error_num);
+ }
+#elif defined(HAVE_GETHOSTBYNAME2) /*#ifdef HAVE_GETADDRINFO */
+ DEBUGF(5,("Starting gethostbyname2(%s, AF_INET6)",data));
+ he = gethostbyname2((char*)data, AF_INET6);
+ if (he) {
+    error_num = 0;
+    DEBUGF(5,("gethostbyname2(, AF_INET6) OK"));
  } else {
-    /* Not supported... */
-    he = NULL;
-    error_num = ERRCODE_NOTSUP;
- }
+    error_num = map_netdb_error(h_errno);
+    DEBUGF(5,("gethostbyname2(, AF_INET6) error: %d", h_errno));
+ }
 #else
- /* Not supported... */
- he = NULL;
  error_num = ERRCODE_NOTSUP;
-#endif
-    } else {
- DEBUGF(4,("Starting gethostbyname(%s)",data));
+#endif /*#ifdef HAVE_GETADDRINFO */
+    } break;
+#endif /*ifdef HAVE_IN6 */
+    
+    case PROTO_IPV4: { /* switch (proto) { */
+ DEBUGF(5,("Starting gethostbyname(%s)",data));
  he = gethostbyname((char*)data);
- error_num = he ? 0 : map_netdb_error(h_errno);
- if (error_num) {
-    DEBUGF(4,("gethostbyname(%s) gave error: %d",
-      data, error_num));
+ if (he) {
+    error_num = 0;
+    DEBUGF(5,("gethostbyname OK"));
  } else {
-    DEBUGF(4,("gethostbyname(%s) gave success",
-      data));
+    error_num = map_netdb_error(h_errno);
+    DEBUGF(5,("gethostbyname error %d", h_errno));
  }
-    }
-    if (!he) {
- data_size = build_error_reply(serial, error_num,
-      &reply, &reply_size);
-    } else {
+    } break;
+    
+    default: /* switch (proto) { */
+ /* Not supported... */
+ error_num = ERRCODE_NOTSUP;
+ break;
+    } /* switch (proto) { */
+    
+    if (he) {
  data_size = build_reply(serial, he, &reply, &reply_size);
-#if defined(HAVE_GETIPNODEBYNAME) && !defined(WIN32) /* IP V6 support */
+#ifdef HAVE_GETIPNODEBYNAME
  if (free_he) {
     freehostent(he);
  }
 #endif
+#ifdef HAVE_GETADDRINFO
+    } else if (ai) {
+ data_size = build_reply_ai(serial, 16, ai,
+   &reply, &reply_size);
+ freeaddrinfo(ai);
+#endif
+    } else {
+ data_size = build_error_reply(serial, error_num,
+      &reply, &reply_size);
     }
-    break;
- case OP_GETHOSTBYADDR:
-    if (proto != PROTO_IPV4) {
-#if defined(HAVE_GETIPNODEBYADDR) && !defined(WIN32) /* IP V6 support */
- if (proto == PROTO_IPV6) {
-    struct in6_addr ia;
-    memcpy(ia.s6_addr, data, 16);
-    he = getipnodebyaddr(&ia, 16, AF_INET6, &error_num);
-    free_he = 1;
+    break; /* case OP_GETHOSTBYNAME: */
+
+ case OP_GETHOSTBYADDR: /* switch (op) { */
+    switch (proto) {
+#ifdef HAVE_IN6
+    case PROTO_IPV6: {
+#ifdef HAVE_GETNAMEINFO
+ struct sockaddr_in6 *sin;
+ socklen_t salen = sizeof(*sin);
+
+ sin = ALLOC(salen);
+#ifndef NO_SA_LEN
+ sin->sin6_len = salen;
+#endif
+ sin->sin6_family = AF_INET6;
+ sin->sin6_port = 0;
+ memcpy(&sin->sin6_addr, data, 16);
+ sa = (struct sockaddr *)sin;
+ DEBUGF(5,("Starting getnameinfo(,,%s,16,,,)",
+  format_address(16, data)));
+ error_num = getnameinfo(sa, salen, name, sizeof(name),
+ NULL, 0, NI_NAMEREQD);
+ DEBUGF(5,("getnameinfo returned %d", error_num));
+ if (error_num) {
+    error_num = map_netdb_error_ai(error_num);
+    sa = NULL;
+ }
+#elif defined(HAVE_GETIPNODEBYADDR) /*#ifdef HAVE_GETNAMEINFO*/
+ struct in6_addr ia;
+ memcpy(ia.s6_addr, data, 16);
+ DEBUGF(5,("Starting getipnodebyaddr(%s,16,AF_INET6,)",
+  format_address(16, data)));
+ he = getipnodebyaddr(&ia, 16, AF_INET6, &error_num);
+ free_he = 1;
+ if (! he) {
+    DEBUGF(5,("getipnodebyaddr error %d", error_num));
     error_num = map_netdb_error(error_num);
  } else {
-    /* Not supported... */
-    he = NULL;
-    error_num = ERRCODE_NOTSUP;
- }
-#else
- /* Not supported... */
- he = NULL;
- error_num = ERRCODE_NOTSUP;
-#endif
-    } else {
+    DEBUGF(5,("getipnodebyaddr OK"));
+ }
+#else /*#ifdef HAVE_GETNAMEINFO*/
+ struct in6_addr ia;
+ memcpy(ia.s6_addr, data, 16);
+ DEBUGF(5,("Starting gethostbyaddr(%s,16,AF_INET6)",
+  format_address(16, data)));
+ he = gethostbyaddr((const char *) &ia, 16, AF_INET6);
+ if (! he) {
+    error_num = map_netdb_error(h_errno);
+    DEBUGF(5,("gethostbyaddr error %d", h_errno));
+ } else {
+    DEBUGF(5,("gethostbyaddr OK"));
+ }
+#endif /* #ifdef HAVE_GETNAMEINFO */
+    } break; /* case PROTO_IPV6: { */
+#endif /* #ifdef HAVE_IN6 */
+    
+    case PROTO_IPV4: { /* switch(proto) { */
  struct in_addr ia;
  memcpy(&ia.s_addr, data, 4); /* Alignment required... */
+ DEBUGF(5,("Starting gethostbyaddr(%s,4,AF_INET)",
+  format_address(4, data)));
  he = gethostbyaddr((const char *) &ia, 4, AF_INET);
- error_num = map_netdb_error(h_errno);
-    }
-    if (!he) {
- data_size = build_error_reply(serial, error_num,
-      &reply, &reply_size);
-    } else {
+ if (! he) {
+    error_num = map_netdb_error(h_errno);
+    DEBUGF(5,("gethostbyaddr error %d", h_errno));
+ } else {
+    DEBUGF(5,("gethostbyaddr OK"));
+ }
+    } break;
+    
+    default:
+ error_num = ERRCODE_NOTSUP;
+    } /* switch(proto) { */
+    
+    if (he) {
  data_size = build_reply(serial, he, &reply, &reply_size);
-#if defined(HAVE_GETIPNODEBYADDR) && !defined(WIN32) /* IP V6 support */
+#ifdef HAVE_GETIPNODEBYADDR
  if (free_he) {
     freehostent(he);
  }
 #endif
+#ifdef HAVE_GETNAMEINFO
+    } else if (sa) {
+ struct addrinfo res;
+ memset(&res, 0, sizeof(res));
+ res.ai_canonname = name;
+ res.ai_addr = sa;
+ res.ai_next = NULL;
+ data_size = build_reply_ai(serial, 16, &res,
+   &reply, &reply_size);
+ free(sa);
+#endif
+    } else {
+ data_size = build_error_reply(serial, error_num,
+      &reply, &reply_size);
     }
-    break;
+    break; /* case OP_GETHOSTBYADR: */
+
  default:
     data_size = build_error_reply(serial, ERRCODE_NOTSUP,
   &reply, &reply_size);
     break;
- }
+ } /* switch (op) { */
+
 #ifdef WIN32
  m = REALLOC(m, sizeof(QueItem) - 1 + data_size - PACKET_BYTES);
  m->next = NULL;
@@ -1720,7 +1862,8 @@
 #else
  write(1, reply, data_size); /* No signals expected */
 #endif
-    }
+    } /* for (;;) */
+
 #ifdef WIN32
  fail:
     if (m != NULL) {
@@ -1766,6 +1909,41 @@
     }
 }
 
+#if defined(HAVE_GETADDRINFO) || defined(HAVE_GETNAMEINFO)
+static int map_netdb_error_ai(int netdb_code)
+{
+    switch(netdb_code) {
+#ifdef EAI_ADDRFAMILY
+    case EAI_ADDRFAMILY:
+ return ERRCODE_NETDB_INTERNAL;
+#endif
+    case EAI_AGAIN:
+ return ERRCODE_TRY_AGAIN;
+    case EAI_BADFLAGS:
+ return ERRCODE_NETDB_INTERNAL;
+    case EAI_FAIL:
+ return ERRCODE_HOST_NOT_FOUND;
+    case EAI_FAMILY:
+ return ERRCODE_NETDB_INTERNAL;
+    case EAI_MEMORY:
+ return ERRCODE_NETDB_INTERNAL;
+#if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME
+    case EAI_NODATA:
+ return ERRCODE_HOST_NOT_FOUND;
+#endif
+    case EAI_NONAME:
+ return ERRCODE_HOST_NOT_FOUND;
+    case EAI_SERVICE:
+ return ERRCODE_NETDB_INTERNAL;
+    case EAI_SOCKTYPE:
+ return ERRCODE_NETDB_INTERNAL;
+    default:
+ return ERRCODE_NETDB_INTERNAL;
+    }
+}
+#endif /* #if defined(HAVE_GETADDRINFO) || defined(HAVE_GETNAMEINFO) */
+
+
 static char *errcode_to_string(int errcode)
 {
     switch (errcode) {
@@ -1880,6 +2058,81 @@
     return need;
 }
 
+#if defined(HAVE_GETADDRINFO) || defined(HAVE_GETNAMEINFO)
+static size_t build_reply_ai(SerialType serial, int addrlen,
+     struct addrinfo *res0,
+     AddrByte **preply, size_t *preply_size)
+{
+    struct addrinfo *res;
+    int num_strings;
+    int num_addresses;
+    AddrByte *ptr;
+    int need;
+
+    num_addresses = 0;
+    num_strings = 0;
+    need = PACKET_BYTES +
+ 4 /* Serial */ + 1 /* addrlen */ +
+ 4 /* Naddr */ + 4 /* Nnames */;
+
+    for (res = res0; res != NULL; res = res->ai_next) {
+ if (res->ai_addr) {
+    num_addresses++;
+    need += addrlen;
+ }
+ if (res->ai_canonname) {
+    num_strings++;
+    need += strlen(res->ai_canonname) + 1;
+ }
+    }
+
+    if (*preply_size < need) {
+ if (*preply_size == 0) {
+    *preply = ALLOC((*preply_size = need));
+ } else {
+    *preply = REALLOC(*preply,
+      (*preply_size = need));
+ }
+    }
+
+    ptr = *preply;
+    PUT_PACKET_BYTES(ptr,need - PACKET_BYTES);
+    ptr += PACKET_BYTES;
+    put_int32(ptr,serial);
+    ptr +=4;
+    *ptr++ = (AddrByte) addrlen; /* 4 or 16 */
+    put_int32(ptr, num_addresses);
+    ptr += 4;
+    for (res = res0; res != NULL && num_addresses; res = res->ai_next) {
+ if (res->ai_addr == NULL)
+    continue;
+ if (addrlen == 4)
+    memcpy(ptr, &((struct sockaddr_in *)res->ai_addr)->sin_addr, addrlen);
+#ifdef AF_INET6
+ else if (addrlen == 16)
+    memcpy(ptr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, addrlen);
+#endif
+ else
+    memcpy(ptr, res->ai_addr->sa_data, addrlen);
+ ptr += addrlen;
+ num_addresses--;
+    }
+    put_int32(ptr, num_strings);
+    ptr += 4;
+    for (res = res0; res != NULL && num_strings; res = res->ai_next) {
+ if (res->ai_canonname == NULL)
+    continue;
+ strcpy((char *)ptr, res->ai_canonname);
+ ptr += strlen(res->ai_canonname) + 1;
+ num_strings--;
+    }
+    return need;
+}
+
+#endif /* #if defined(HAVE_GETADDRINFO) || defined(HAVE_GETNAMEINFO) */
+
+
+
 /*
  * Encode/decode/read/write
  */
@@ -2225,7 +2478,7 @@
 {
     void *ptr = malloc(size);
     if (!ptr) {
- fatal("Cannot allocate %d bytes of memory.", (int) size);
+ fatal("Cannot allocate %u bytes of memory.", (unsigned) size);
  return NULL; /* lint... */
     }
     return ptr;
@@ -2235,8 +2488,8 @@
 {
     void *ptr = realloc(old, size);
     if (!ptr) {
- fatal("Cannot reallocate %d bytes of memory from 0x%08X.",
-      (int) size, (unsigned) old);
+ fatal("Cannot reallocate %u bytes of memory from %p.",
+      (unsigned) size, old);
  return NULL; /* lint... */
     }
     return ptr;
@@ -2309,7 +2562,8 @@
     if (!q->shutdown) {
  q->shutdown = TRUE;
  if (!SetEvent(q->data_present)) {
-    fprintf(stderr,"Fatal: Unable to signal event in %s:%d, last error: %d\n",
+    fprintf(stderr,
+    "Fatal: Unable to signal event in %s:%d, last error: %d\n",
     __FILE__,__LINE__,GetLastError());
     exit(1); /* Unable to continue at all */
  }


_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: IPv6 name resolver patch for R12B-2

by Matthew Dempsky-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Apr 24, 2008 at 7:17 AM, Raimo Niskanen
<raimo+erlang-questions@...> wrote:
>  I now have a solution running in our daily builds.
>  I attach a patch for R12B-2. Please try it!

Awesome!  I applied it to an R12B-3 snapshot (from yesterday or so)
and it works great on OS X 10.5.2:

matthew@pollux:~/src/otp_src_R12B-3$ ./bin/erl
Erlang (BEAM) emulator version 5.6.3 [source] [smp:2]
[async-threads:0] [kernel-poll:false]

Eshell V5.6.3  (abort with ^G)
1> inet:getaddr("ipv6.google.com", inet6).
{ok,{8193,18528,0,8193,0,0,0,104}}
2> inet:getaddr("www.kame.net", inet6).
{ok,{8193,512,0,32770,515,18431,65189,12421}}
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: IPv6 name resolver patch for R12B-2

by Matthew Dempsky-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Apr 24, 2008 at 1:10 PM, Matthew Dempsky <matthew@...> wrote:
>  Awesome!  I applied it to an R12B-3 snapshot (from yesterday or so)
>  and it works great on OS X 10.5.2:

I just noticed this patch is already included in the latest R12B-3
snapshot.  Just to be clear, the snapshot I used must have been from
before when this patch was merged, because the diff applied cleanly
and without needing to be reversed.
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions

Re: : IPv6 name resolver patch for R12B-2

by Raimo Niskanen-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Apr 24, 2008 at 03:44:37PM -0700, Matthew Dempsky wrote:
> On Thu, Apr 24, 2008 at 1:10 PM, Matthew Dempsky <matthew@...> wrote:
> >  Awesome!  I applied it to an R12B-3 snapshot (from yesterday or so)
> >  and it works great on OS X 10.5.2:
>

Great to hear!

> I just noticed this patch is already included in the latest R12B-3
> snapshot.  Just to be clear, the snapshot I used must have been from
> before when this patch was merged, because the diff applied cleanly
> and without needing to be reversed.

It appears our R12B-3 snapshots are of our nightly build view spec,
that is all patch branches that we developers deem worthy of testing
on all build machines, an not the r12b-3_dev branch (that contain the
patch branches that has passed the nightly build tests) as I though.

Very well. I think I inserted the patch branch for Wednesday
nightbuilds that start around 1900 (CET,DST), so Thursday
morning snapshot (around 0300) and later should
contain the patch.

> _______________________________________________
> erlang-questions mailing list
> erlang-questions@...
> http://www.erlang.org/mailman/listinfo/erlang-questions

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB
_______________________________________________
erlang-questions mailing list
erlang-questions@...
http://www.erlang.org/mailman/listinfo/erlang-questions
< Prev | 1 - 2 | Next >