Re: Add MDNS lookup for libc.

2011-04-19 Thread Christiano F. Haesbaert
Keeping this up.

On 19 March 2011 22:35, Christiano F. Haesbaert 
wrote:
> Whoops, I made some last time changes which broke big-endian systems,
spotted by
> Mattew.
>
> Index: net/getaddrinfo.c
> ===
> RCS file: /cvs/src/lib/libc/net/getaddrinfo.c,v
> retrieving revision 1.71
> diff -d -u -p -w -r1.71 getaddrinfo.c
> --- net/getaddrinfo.c   18 Nov 2009 07:43:22 -  1.71
> +++ net/getaddrinfo.c   20 Mar 2011 01:32:16 -
> @@ -235,6 +235,8 @@ static int res_searchN(const char *, str
>  static int res_querydomainN(const char *, const char *, struct res_target
*);
>  static struct addrinfo *_dns_getaddrinfo(const char *, const struct
addrinfo *,
>const struct __res_state *);
> +static struct addrinfo *_mcast_getaddrinfo(const char *,
> +const struct addrinfo *, const struct __res_state *);
>
>
>  /* XXX macros that make external reference is BAD. */
> @@ -523,6 +525,9 @@ explore_fqdn(const struct addrinfo *pai,
>case 'f':
>result = _files_getaddrinfo(hostname, pai);
>break;
> +   case 'm':
> +   result = _mcast_getaddrinfo(hostname, pai, _resp);
> +   break;
>}
>}
>_THREAD_PRIVATE_MUTEX_UNLOCK(_explore_mutex);
> @@ -1209,6 +1214,99 @@ _dns_getaddrinfo(const char *name, const
>free(buf);
>free(buf2);
>return NULL;
> +   }
> +   ai = getanswer(buf, q.n, q.name, q.qtype, pai);
> +   if (ai) {
> +   cur->ai_next = ai;
> +   while (cur && cur->ai_next)
> +   cur = cur->ai_next;
> +   }
> +   if (q.next) {
> +   ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
> +   if (ai)
> +   cur->ai_next = ai;
> +   }
> +   free(buf);
> +   free(buf2);
> +   return sentinel.ai_next;
> +}
> +
> +static struct addrinfo *
> +_mcast_getaddrinfo(const char *name, const struct addrinfo *pai,
> +const struct __res_state *_resp)
> +{
> +   struct addrinfo *ai;
> +   querybuf *buf, *buf2;
> +   struct addrinfo sentinel, *cur;
> +   struct res_target q, q2;
> +
> +   memset(&q, 0, sizeof(q));
> +   memset(&q2, 0, sizeof(q2));
> +   memset(&sentinel, 0, sizeof(sentinel));
> +   cur = &sentinel;
> +
> +   buf = malloc(sizeof(*buf));
> +   if (buf == NULL) {
> +   h_errno = NETDB_INTERNAL;
> +   return NULL;
> +   }
> +   buf2 = malloc(sizeof(*buf2));
> +   if (buf2 == NULL) {
> +   free(buf);
> +   h_errno = NETDB_INTERNAL;
> +   return NULL;
> +   }
> +
> +   switch (pai->ai_family) {
> +   case AF_UNSPEC:
> +   /* respect user supplied order */
> +   q.qclass = C_IN;
> +   q.qtype = (_resp->family[0] == AF_INET6) ? T_ : T_A;
> +   q.answer = buf->buf;
> +   q.anslen = sizeof(buf->buf);
> +   q.next = &q2;
> +
> +   if (_resp->family[1] == -1) {
> +   /* stop here if only one family was given */
> +   q.next = NULL;
> +   break;
> +   }
> +
> +   q2.qclass = C_IN;
> +   q2.qtype = (_resp->family[1] == AF_INET6) ? T_ : T_A;
> +   q2.answer = buf2->buf;
> +   q2.anslen = sizeof(buf2->buf);
> +   break;
> +   case AF_INET:
> +   q.qclass = C_IN;
> +   q.qtype = T_A;
> +   q.answer = buf->buf;
> +   q.anslen = sizeof(buf->buf);
> +   break;
> +   case AF_INET6:
> +   q.qclass = C_IN;
> +   q.qtype = T_;
> +   q.answer = buf->buf;
> +   q.anslen = sizeof(buf->buf);
> +   break;
> +   default:
> +   free(buf);
> +   free(buf2);
> +   return NULL;
> +   }
> +   if ((q.n = res_search_mcast(name,
> +   q.qclass, q.qtype, q.answer, q.anslen)) < 0) {
> +   free(buf);
> +   free(buf2);
> +   return (NULL);
> +   }
> +   if (q.next != NULL) {
> +   if ((q2.n = res_search_mcast(name,
> +   q2.qclass, q2.qtype, q2.answer, q2.anslen)) < 0) {
> +   free(buf);
> +   free(buf2);
> +   return (NULL);
> +   }
>}
>ai = getanswer(buf, q.n, q.name, q.qtype, pai);
>if (ai) {
> Index: net/gethostnamadr.c
> ===
> RCS file: /cvs/src/lib/libc/net/gethostnamadr.c,v
> retrieving revision 1.73
> diff -d -u -p -w -r1.73 gethostnamadr.c
> --- net/gethostnamadr.c 18 Nov 2009 07:43:22 -  1.73
> +++ net/get

Re: Add MDNS lookup for libc.

2011-03-23 Thread kamaldeep srangal
Thanks a lot.

Please never mind i have question, as you have implemented your own version,
can you use name "mdns" , does not its apple's property ? :)



On Wed, Mar 23, 2011 at 3:54 PM, Stuart Henderson wrote:

> On 2011/03/23 09:50, hUNT wrote:
> > Cool!!!
> >
> > U did a great job!!! I was looking for
> > exactly same.:)
> > which bonjour version u have used ?
> > Can i access your source code (openmdns)?
> > Keep up the good work!!!
>
> https://github.com/haesbaert/mdnsd



Re: Add MDNS lookup for libc.

2011-03-23 Thread Christiano F. Haesbaert
On Wed, Mar 23, 2011 at 04:34:22PM +0530, kamaldeep srangal wrote:
> Thanks a lot.
> 
> Please never mind i have question, as you have implemented your own version,
> can you use name "mdns" , does not its apple's property ? :)
> 

Yes, mdns is a protocol draft at this time, www.multicastdns.org. So it doesn't
"belong" to anyone.  Bonjour is an apple product which implements mdns and
dns-sd.

> ppp
> 
> On Wed, Mar 23, 2011 at 3:54 PM, Stuart Henderson wrote:
> 
> > On 2011/03/23 09:50, hUNT wrote:
> > > Cool!!!
> > >
> > > U did a great job!!! I was looking for

Thanks :-). I'm glad you liked it.


-- 
Christiano Farina HAESBAERT
Do NOT send me html mail.



Re: Add MDNS lookup for libc.

2011-03-23 Thread Stuart Henderson
On 2011/03/23 09:50, hUNT wrote:
> Cool!!!
> 
> U did a great job!!! I was looking for 
> exactly same.:)
> which bonjour version u have used ? 
> Can i access your source code (openmdns)?
> Keep up the good work!!!

https://github.com/haesbaert/mdnsd



Re: Add MDNS lookup for libc.

2011-03-23 Thread hUNT
Cool!!!

U did a great job!!! I was looking for 
exactly same.:)
which bonjour version u have used ? 
Can i access your source code (openmdns)?
Keep up the good work!!!



Re: Add MDNS lookup for libc.

2011-03-19 Thread Christiano F. Haesbaert
Whoops, I made some last time changes which broke big-endian systems, spotted by
Mattew.

Index: net/getaddrinfo.c
===
RCS file: /cvs/src/lib/libc/net/getaddrinfo.c,v
retrieving revision 1.71
diff -d -u -p -w -r1.71 getaddrinfo.c
--- net/getaddrinfo.c   18 Nov 2009 07:43:22 -  1.71
+++ net/getaddrinfo.c   20 Mar 2011 01:32:16 -
@@ -235,6 +235,8 @@ static int res_searchN(const char *, str
 static int res_querydomainN(const char *, const char *, struct res_target *);
 static struct addrinfo *_dns_getaddrinfo(const char *, const struct addrinfo *,
const struct __res_state *);
+static struct addrinfo *_mcast_getaddrinfo(const char *,
+const struct addrinfo *, const struct __res_state *);
 
 
 /* XXX macros that make external reference is BAD. */
@@ -523,6 +525,9 @@ explore_fqdn(const struct addrinfo *pai,
case 'f':
result = _files_getaddrinfo(hostname, pai);
break;
+   case 'm':
+   result = _mcast_getaddrinfo(hostname, pai, _resp);
+   break;
}
}
_THREAD_PRIVATE_MUTEX_UNLOCK(_explore_mutex);
@@ -1209,6 +1214,99 @@ _dns_getaddrinfo(const char *name, const
free(buf);
free(buf2);
return NULL;
+   }
+   ai = getanswer(buf, q.n, q.name, q.qtype, pai);
+   if (ai) {
+   cur->ai_next = ai;
+   while (cur && cur->ai_next)
+   cur = cur->ai_next;
+   }
+   if (q.next) {
+   ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
+   if (ai)
+   cur->ai_next = ai;
+   }
+   free(buf);
+   free(buf2);
+   return sentinel.ai_next;
+}
+
+static struct addrinfo *
+_mcast_getaddrinfo(const char *name, const struct addrinfo *pai,
+const struct __res_state *_resp)
+{
+   struct addrinfo *ai;
+   querybuf *buf, *buf2;
+   struct addrinfo sentinel, *cur;
+   struct res_target q, q2;
+
+   memset(&q, 0, sizeof(q));
+   memset(&q2, 0, sizeof(q2));
+   memset(&sentinel, 0, sizeof(sentinel));
+   cur = &sentinel;
+
+   buf = malloc(sizeof(*buf));
+   if (buf == NULL) {
+   h_errno = NETDB_INTERNAL;
+   return NULL;
+   }
+   buf2 = malloc(sizeof(*buf2));
+   if (buf2 == NULL) {
+   free(buf);
+   h_errno = NETDB_INTERNAL;
+   return NULL;
+   }
+
+   switch (pai->ai_family) {
+   case AF_UNSPEC:
+   /* respect user supplied order */
+   q.qclass = C_IN;
+   q.qtype = (_resp->family[0] == AF_INET6) ? T_ : T_A;
+   q.answer = buf->buf;
+   q.anslen = sizeof(buf->buf);
+   q.next = &q2;
+
+   if (_resp->family[1] == -1) {
+   /* stop here if only one family was given */
+   q.next = NULL;
+   break;
+   }
+
+   q2.qclass = C_IN;
+   q2.qtype = (_resp->family[1] == AF_INET6) ? T_ : T_A;
+   q2.answer = buf2->buf;
+   q2.anslen = sizeof(buf2->buf);
+   break;
+   case AF_INET:
+   q.qclass = C_IN;
+   q.qtype = T_A;
+   q.answer = buf->buf;
+   q.anslen = sizeof(buf->buf);
+   break;
+   case AF_INET6:
+   q.qclass = C_IN;
+   q.qtype = T_;
+   q.answer = buf->buf;
+   q.anslen = sizeof(buf->buf);
+   break;
+   default:
+   free(buf);
+   free(buf2);
+   return NULL;
+   }
+   if ((q.n = res_search_mcast(name,
+   q.qclass, q.qtype, q.answer, q.anslen)) < 0) {
+   free(buf);
+   free(buf2);
+   return (NULL);
+   }
+   if (q.next != NULL) {
+   if ((q2.n = res_search_mcast(name,
+   q2.qclass, q2.qtype, q2.answer, q2.anslen)) < 0) {
+   free(buf);
+   free(buf2);
+   return (NULL);
+   }
}
ai = getanswer(buf, q.n, q.name, q.qtype, pai);
if (ai) {
Index: net/gethostnamadr.c
===
RCS file: /cvs/src/lib/libc/net/gethostnamadr.c,v
retrieving revision 1.73
diff -d -u -p -w -r1.73 gethostnamadr.c
--- net/gethostnamadr.c 18 Nov 2009 07:43:22 -  1.73
+++ net/gethostnamadr.c 20 Mar 2011 01:32:16 -
@@ -606,6 +606,7 @@ gethostbyname2(const char *name, int af)
 
hp = (struct hostent *)NULL;
for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
+   size_t nlen;
switch (lookups[i]) {
 #ifdef YP
case 'y':
@@ -615,9 +616

Re: Add MDNS lookup for libc.

2011-03-19 Thread Christiano F. Haesbaert
On Tue, Mar 15, 2011 at 01:06:21AM -0300, Christiano F. Haesbaert wrote:
> Hi,
> 
> The following adds legacy MDNS lookups to libc.
> 
> It adds the keyword 'mdns' to 'lookup' in /etc/resolv.conf, only names in the
> .local (MDNS domain) are looked up.
> 
> A legacy lookup is how MDNS calls a simple unicast lookup sent to the mcast 
> addr
> 224.0.0.251, the MDNS responder is responsible for identifying the legacy 
> query
> and answering it via unicast, like a normal unicast domain server would do.
> 
> In order to *answer* the queries you need a proper MDNS daemon running, 
> OpenMDNS
> is now in ports and works fine. You could also run avahi or bonjour, but 
> please
> try OpenMDNS instead :-). http://www.haesbaert.org/openmdns
> 
> This approach is different from linux+avahi and netbsd+bonjour, in which they
> route the queries to the daemon in order to use standard MDNS queries.
> 
> I've been using this in i386 and sparc64 for about a week, support for both
> getaddrinfo(3) and gethostbyname(3), AF_INET and AF_INET6, no support for
> reverse lookups yet.
> 
> I'm still unfamiliar with the libc resolv code, so if I'm doing something 
> wrong
> please correct me, I've tried to keep the code apart from the rest of the
> resolver. 
> 
> Index: net/getaddrinfo.c
> ===
> RCS file: /cvs/src/lib/libc/net/getaddrinfo.c,v
> retrieving revision 1.71
> diff -d -u -p -w -r1.71 getaddrinfo.c
> --- net/getaddrinfo.c 18 Nov 2009 07:43:22 -  1.71
> +++ net/getaddrinfo.c 15 Mar 2011 00:56:20 -
> @@ -235,6 +235,8 @@ static int res_searchN(const char *, str
>  static int res_querydomainN(const char *, const char *, struct res_target *);
>  static struct addrinfo *_dns_getaddrinfo(const char *, const struct addrinfo 
> *,
>   const struct __res_state *);
> +static struct addrinfo *_mcast_getaddrinfo(const char *,
> +const struct addrinfo *, const struct __res_state *);
>  
>  
>  /* XXX macros that make external reference is BAD. */
> @@ -523,6 +525,9 @@ explore_fqdn(const struct addrinfo *pai,
>   case 'f':
>   result = _files_getaddrinfo(hostname, pai);
>   break;
> + case 'm':
> + result = _mcast_getaddrinfo(hostname, pai, _resp);
> + break;
>   }
>   }
>   _THREAD_PRIVATE_MUTEX_UNLOCK(_explore_mutex);
> @@ -1209,6 +1214,99 @@ _dns_getaddrinfo(const char *name, const
>   free(buf);
>   free(buf2);
>   return NULL;
> + }
> + ai = getanswer(buf, q.n, q.name, q.qtype, pai);
> + if (ai) {
> + cur->ai_next = ai;
> + while (cur && cur->ai_next)
> + cur = cur->ai_next;
> + }
> + if (q.next) {
> + ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
> + if (ai)
> + cur->ai_next = ai;
> + }
> + free(buf);
> + free(buf2);
> + return sentinel.ai_next;
> +}
> +
> +static struct addrinfo *
> +_mcast_getaddrinfo(const char *name, const struct addrinfo *pai,
> +const struct __res_state *_resp)
> +{
> + struct addrinfo *ai;
> + querybuf *buf, *buf2;
> + struct addrinfo sentinel, *cur;
> + struct res_target q, q2;
> +
> + memset(&q, 0, sizeof(q));
> + memset(&q2, 0, sizeof(q2));
> + memset(&sentinel, 0, sizeof(sentinel));
> + cur = &sentinel;
> +
> + buf = malloc(sizeof(*buf));
> + if (buf == NULL) {
> + h_errno = NETDB_INTERNAL;
> + return NULL;
> + }
> + buf2 = malloc(sizeof(*buf2));
> + if (buf2 == NULL) {
> + free(buf);
> + h_errno = NETDB_INTERNAL;
> + return NULL;
> + }
> +
> + switch (pai->ai_family) {
> + case AF_UNSPEC:
> + /* respect user supplied order */
> + q.qclass = C_IN;
> + q.qtype = (_resp->family[0] == AF_INET6) ? T_ : T_A;
> + q.answer = buf->buf;
> + q.anslen = sizeof(buf->buf);
> + q.next = &q2;
> +
> + if (_resp->family[1] == -1) {
> + /* stop here if only one family was given */
> + q.next = NULL;
> + break;
> + }
> +
> + q2.qclass = C_IN;
> + q2.qtype = (_resp->family[1] == AF_INET6) ? T_ : T_A;
> + q2.answer = buf2->buf;
> + q2.anslen = sizeof(buf2->buf);
> + break;
> + case AF_INET:
> + q.qclass = C_IN;
> + q.qtype = T_A;
> + q.answer = buf->buf;
> + q.anslen = sizeof(buf->buf);
> + break;
> + case AF_INET6:
> + q.qclass = C_IN;
> + q.qtype = T_;
> + q.answer = buf->buf;
> + q.anslen = sizeof(buf->buf);
> + break;
> + default:
> + free(buf);
> + 

Re: Add MDNS lookup for libc.

2011-03-15 Thread Christiano F. Haesbaert
This is all documented in Section 6.7 "Legacy Unicast Responses" of
http://files.multicastdns.org/draft-cheshire-dnsext-multicastdns.txt

-- 
Christiano Farina HAESBAERT
Do NOT send me html mail.



Add MDNS lookup for libc.

2011-03-14 Thread Christiano F. Haesbaert
Hi,

The following adds legacy MDNS lookups to libc.

It adds the keyword 'mdns' to 'lookup' in /etc/resolv.conf, only names in the
.local (MDNS domain) are looked up.

A legacy lookup is how MDNS calls a simple unicast lookup sent to the mcast addr
224.0.0.251, the MDNS responder is responsible for identifying the legacy query
and answering it via unicast, like a normal unicast domain server would do.

In order to *answer* the queries you need a proper MDNS daemon running, OpenMDNS
is now in ports and works fine. You could also run avahi or bonjour, but please
try OpenMDNS instead :-). http://www.haesbaert.org/openmdns

This approach is different from linux+avahi and netbsd+bonjour, in which they
route the queries to the daemon in order to use standard MDNS queries.

I've been using this in i386 and sparc64 for about a week, support for both
getaddrinfo(3) and gethostbyname(3), AF_INET and AF_INET6, no support for
reverse lookups yet.

I'm still unfamiliar with the libc resolv code, so if I'm doing something wrong
please correct me, I've tried to keep the code apart from the rest of the
resolver. 

Index: net/getaddrinfo.c
===
RCS file: /cvs/src/lib/libc/net/getaddrinfo.c,v
retrieving revision 1.71
diff -d -u -p -w -r1.71 getaddrinfo.c
--- net/getaddrinfo.c   18 Nov 2009 07:43:22 -  1.71
+++ net/getaddrinfo.c   15 Mar 2011 00:56:20 -
@@ -235,6 +235,8 @@ static int res_searchN(const char *, str
 static int res_querydomainN(const char *, const char *, struct res_target *);
 static struct addrinfo *_dns_getaddrinfo(const char *, const struct addrinfo *,
const struct __res_state *);
+static struct addrinfo *_mcast_getaddrinfo(const char *,
+const struct addrinfo *, const struct __res_state *);
 
 
 /* XXX macros that make external reference is BAD. */
@@ -523,6 +525,9 @@ explore_fqdn(const struct addrinfo *pai,
case 'f':
result = _files_getaddrinfo(hostname, pai);
break;
+   case 'm':
+   result = _mcast_getaddrinfo(hostname, pai, _resp);
+   break;
}
}
_THREAD_PRIVATE_MUTEX_UNLOCK(_explore_mutex);
@@ -1209,6 +1214,99 @@ _dns_getaddrinfo(const char *name, const
free(buf);
free(buf2);
return NULL;
+   }
+   ai = getanswer(buf, q.n, q.name, q.qtype, pai);
+   if (ai) {
+   cur->ai_next = ai;
+   while (cur && cur->ai_next)
+   cur = cur->ai_next;
+   }
+   if (q.next) {
+   ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
+   if (ai)
+   cur->ai_next = ai;
+   }
+   free(buf);
+   free(buf2);
+   return sentinel.ai_next;
+}
+
+static struct addrinfo *
+_mcast_getaddrinfo(const char *name, const struct addrinfo *pai,
+const struct __res_state *_resp)
+{
+   struct addrinfo *ai;
+   querybuf *buf, *buf2;
+   struct addrinfo sentinel, *cur;
+   struct res_target q, q2;
+
+   memset(&q, 0, sizeof(q));
+   memset(&q2, 0, sizeof(q2));
+   memset(&sentinel, 0, sizeof(sentinel));
+   cur = &sentinel;
+
+   buf = malloc(sizeof(*buf));
+   if (buf == NULL) {
+   h_errno = NETDB_INTERNAL;
+   return NULL;
+   }
+   buf2 = malloc(sizeof(*buf2));
+   if (buf2 == NULL) {
+   free(buf);
+   h_errno = NETDB_INTERNAL;
+   return NULL;
+   }
+
+   switch (pai->ai_family) {
+   case AF_UNSPEC:
+   /* respect user supplied order */
+   q.qclass = C_IN;
+   q.qtype = (_resp->family[0] == AF_INET6) ? T_ : T_A;
+   q.answer = buf->buf;
+   q.anslen = sizeof(buf->buf);
+   q.next = &q2;
+
+   if (_resp->family[1] == -1) {
+   /* stop here if only one family was given */
+   q.next = NULL;
+   break;
+   }
+
+   q2.qclass = C_IN;
+   q2.qtype = (_resp->family[1] == AF_INET6) ? T_ : T_A;
+   q2.answer = buf2->buf;
+   q2.anslen = sizeof(buf2->buf);
+   break;
+   case AF_INET:
+   q.qclass = C_IN;
+   q.qtype = T_A;
+   q.answer = buf->buf;
+   q.anslen = sizeof(buf->buf);
+   break;
+   case AF_INET6:
+   q.qclass = C_IN;
+   q.qtype = T_;
+   q.answer = buf->buf;
+   q.anslen = sizeof(buf->buf);
+   break;
+   default:
+   free(buf);
+   free(buf2);
+   return NULL;
+   }
+   if ((q.n = res_search_mcast(name,
+   q.qclass, q.qtype, q.answer, q.anslen)) < 0) {
+   free(buf);
+