Hi!

<Preface>
You can use Google Talk with Bitlbee, because it supports jabber, but on
OpenBSD with one condition: you must specify the server name for the
account (eg.: 'account set server xmpp.l.google.com', because bitlbee's
SRV DNS queries don't work on OpenBSD [1].  Basically Bitlbee uses the
ominous ns_*() functions for SRV type DNS lookups, and those are missing
from our libc. So now, when Bitlbee tries to fire up a GTalk account, it
can not query the SRV record(s) for _xmpp-client._tcp.gmail.com, and
falls back to querying A records for gmail.com (given that the account
id is username(at)gmail.com) and fails to connect.
</Preface>

I've cooked up a diff to only use the res_*() and dn_*() functions
instead of ns_*(). On the upside, this is even usable on eg. Linux and
FreeBSD, not just OpenBSD...

So, I'm looking for some testers and hopefully some reviews, and if it
is usable, I want to send this upstream.
I could only try it out on i386.

This is not supposed to alter any other behaviour of Bitlbee, other than
SRV type DNS lookups, so after you've connected, you should be safe ;)


Thanks,
Daniel



[1]: http://bugs.bitlbee.org/bitlbee/ticket/421


----------------------8<----------------------
Index: Makefile
===================================================================
RCS file: /cvs/ports/net/bitlbee/Makefile,v
retrieving revision 1.48
diff -p -u -r1.48 Makefile
--- Makefile    9 Feb 2013 14:49:51 -0000       1.48
+++ Makefile    6 Mar 2013 18:56:00 -0000
@@ -4,6 +4,7 @@ COMMENT=                IRC proxy to connect to AIM, I
 
 DISTNAME=              bitlbee-3.2
 CATEGORIES=            net
+REVISION=              1
 
 HOMEPAGE=              http://bitlbee.org/
 
Index: patches/patch-configure
===================================================================
RCS file: patches/patch-configure
diff -N patches/patch-configure
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-configure     6 Mar 2013 18:56:00 -0000
@@ -0,0 +1,27 @@
+$OpenBSD$
+--- configure.orig     Mon Jan  7 00:41:11 2013
++++ configure  Wed Mar  6 16:23:10 2013
+@@ -362,6 +362,23 @@ detect_resolv_dynamic()
+       FreeBSD )
+               # In FreeBSD res_* routines are present in libc.so
+               LIBRESOLV=;;
++      OpenBSD )
++              # In OpenBSD res_* routines are present in libc.so,
++              # and there are no ns_*() functions, thus the special
++              # RESOLV_TESTCODE.
++              LIBRESOLV=
++              RESOLV_TESTCODE='
++#include <netinet/in.h>
++#include <arpa/nameser.h>
++#include <resolv.h> 
++
++int main()
++{
++      res_query( NULL, 0, 0, NULL, 0 );
++      dn_expand( NULL, NULL, NULL, NULL, 0 );
++}
++'
++;;
+       * )
+               LIBRESOLV=-lresolv;;
+       esac
Index: patches/patch-lib_misc_c
===================================================================
RCS file: patches/patch-lib_misc_c
diff -N patches/patch-lib_misc_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-lib_misc_c    6 Mar 2013 18:56:00 -0000
@@ -0,0 +1,115 @@
+$OpenBSD$
+--- lib/misc.c.orig    Mon Jan  7 00:41:11 2013
++++ lib/misc.c Wed Mar  6 19:13:27 2013
+@@ -44,7 +44,10 @@
+ #ifdef HAVE_RESOLV_A
+ #include <arpa/nameser.h>
+ #include <resolv.h>
++#if defined (__OpenBSD__)
++#include <netinet/in.h>
+ #endif
++#endif
+ 
+ #include "md5.h"
+ #include "ssl_client.h"
+@@ -522,19 +525,90 @@ struct ns_srv_reply **srv_lookup( char *service, char 
+       char name[1024];
+       unsigned char querybuf[1024];
+       const unsigned char *buf;
++      int i, n, len, size;
++#if defined (__OpenBSD__)
++      char                    uncomp[MAXDNAME];
++      int                     complen = -1;
++      unsigned int            qdcount = 0, ancount = 0;
++
++      const unsigned char     *comp = NULL;
++      unsigned char           *end = NULL;
++      HEADER                  *head = NULL;
++
++      int                     ns_c_in = C_IN, ns_t_srv = T_SRV;
++      int                     prio = -1, weight = -1, port = -1;
++#else
+       ns_msg nsh;
+       ns_rr rr;
+-      int i, n, len, size;
++#endif
++
+       
+       g_snprintf( name, sizeof( name ), "_%s._%s.%s", service, protocol, 
domain );
+       
+       if( ( size = res_query( name, ns_c_in, ns_t_srv, querybuf, sizeof( 
querybuf ) ) ) <= 0 )
+               return NULL;
+       
++      n = 0;
++
++#if defined (__OpenBSD__)
++      head = (HEADER *)querybuf;
++      comp = querybuf + HFIXEDSZ;
++      end = querybuf + size;
++
++      ancount = ntohs(head->ancount);
++
++      /* Skip over the Query part */
++      for (qdcount = ntohs(head->qdcount); qdcount--; comp += size + QFIXEDSZ)
++              if ((size = dn_skipname(comp, end)) < 0)
++                      return NULL;
++
++
++      /* Get the answers */
++      while (ancount > 0  &&  comp < end) {
++              /* Skip the owner name, to which this resource record pertains. 
*/
++              complen = dn_expand(querybuf, end, comp, uncomp, 
sizeof(uncomp));
++              if (complen < 0)
++                      return NULL;
++
++              comp += complen;
++
++
++              /* Get the useful answers. */
++              /* GETSHORT(type, comp); */
++              comp += INT16SZ;
++              /* GETSHORT(class, comp); */
++              comp += INT16SZ;
++              /* GETLONG(ttl, comp); */
++              comp += INT32SZ;
++              /* GETSHORT(complen, comp); */
++              comp += INT16SZ;
++
++              GETSHORT(prio , comp);
++              GETSHORT(weight , comp);
++              GETSHORT(port , comp);
++              complen = dn_expand(querybuf, end, comp, uncomp, 
sizeof(uncomp));
++              if (complen < 0)
++                      return NULL;
++
++              comp += complen;
++
++              reply = g_malloc( sizeof( struct ns_srv_reply ) + 
strlen(uncomp) + 1 );
++
++              reply->prio = prio;
++              reply->weight = weight;
++              reply->port = port;
++              strlcpy( reply->name, uncomp, strlen(uncomp) + 1 );
++
++              n++;
++              replies = g_renew( struct ns_srv_reply *, replies, n + 1 );
++              replies[n-1] = reply;
++
++              ancount--;
++      }
++#else
+       if( ns_initparse( querybuf, size, &nsh ) != 0 )
+               return NULL;
+       
+-      n = 0;
+       while( ns_parserr( &nsh, ns_s_an, n, &rr ) == 0 )
+       {
+               size = ns_rr_rdlen( rr );
+@@ -567,6 +641,7 @@ struct ns_srv_reply **srv_lookup( char *service, char 
+               replies = g_renew( struct ns_srv_reply *, replies, n + 1 );
+               replies[n-1] = reply;
+       }
++#endif
+       if( replies )
+               replies[n] = NULL;
+ #endif
----------------------8<----------------------

-- 
LÉVAI Dániel
PGP key ID = 0x83B63A8F
Key fingerprint = DBEC C66B A47A DFA2 792D  650C C69B BE4C 83B6 3A8F

Reply via email to