1 #pragma ident "%Z%%M% %I% %E% SMI"
4 * The contents of this file are subject to the Netscape Public
5 * License Version 1.1 (the "License"); you may not use this file
6 * except in compliance with the License. You may obtain a copy of
7 * the License at http://www.mozilla.org/NPL/
9 * Software distributed under the License is distributed on an "AS
10 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11 * implied. See the License for the specific language governing
12 * rights and limitations under the License.
14 * The Original Code is Mozilla Communicator client code, released
17 * The Initial Developer of the Original Code is Netscape
18 * Communications Corporation. Portions created by Netscape are
19 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
25 * Copyright (c) 1995 Regents of the University of Michigan.
26 * All rights reserved.
29 * nsldapi_getdxbyname - retrieve DX records from the DNS (from
30 * TXT records for now)
45 #endif /* macintosh */
51 #if !defined(macintosh) && !defined(DOS) && !defined( _WINDOWS )
52 #include <sys/types.h>
53 #include <netinet/in.h>
54 #include <arpa/nameser.h>
56 #include <sys/types.h>
57 #include <sys/socket.h>
69 static char ** decode_answer( unsigned char *answer
, int len
);
70 #else /* NEEDPROTOS */
71 static char **decode_answer();
72 #endif /* NEEDPROTOS */
75 extern char *h_errlist
[];
78 #define MAX_TO_SORT 32
82 * nsldapi_getdxbyname - lookup DNS DX records for domain and return an ordered
86 nsldapi_getdxbyname( char *domain
)
88 unsigned char buf
[ PACKETSZ
];
92 LDAPDebug( LDAP_DEBUG_TRACE
, "nsldapi_getdxbyname( %s )\n", domain
, 0, 0 );
94 memset( buf
, 0, sizeof( buf
));
96 /* XXX not MT safe XXX */
97 if (( rc
= res_search( domain
, C_IN
, T_TXT
, buf
, sizeof( buf
))) < 0
98 || ( dxs
= decode_answer( buf
, rc
)) == NULL
) {
100 * punt: return list conisting of the original domain name only
102 if (( dxs
= (char **)NSLDAPI_MALLOC( 2 * sizeof( char * ))) == NULL
||
103 ( dxs
[ 0 ] = nsldapi_strdup( domain
)) == NULL
) {
118 decode_answer( unsigned char *answer
, int len
)
121 char buf
[ 256 ], **dxs
;
122 unsigned char *eom
, *p
;
123 int ancount
, err
, rc
, type
, class, dx_count
, rr_len
;
124 int dx_pref
[ MAX_TO_SORT
];
127 if ( ldap_debug
& LDAP_DEBUG_PACKETS
) {
128 /* __p_query( answer ); */
130 #endif /* LDAP_DEBUG */
133 hp
= (HEADER
*)answer
;
136 if ( ntohs( hp
->qdcount
) != 1 ) {
137 h_errno
= NO_RECOVERY
;
141 ancount
= ntohs( hp
->ancount
);
148 * skip over the query
150 p
= answer
+ HFIXEDSZ
;
151 if (( rc
= dn_expand( answer
, eom
, p
, buf
, sizeof( buf
))) < 0 ) {
152 h_errno
= NO_RECOVERY
;
155 p
+= ( rc
+ QFIXEDSZ
);
158 * pull out the answers we are interested in
161 while ( ancount
> 0 && err
== 0 && p
< eom
) {
162 if (( rc
= dn_expand( answer
, eom
, p
, buf
, sizeof( buf
))) < 0 ) {
166 p
+= rc
; /* skip over name */
167 type
= _getshort( p
);
169 class = _getshort( p
);
171 p
+= INT32SZ
; /* skip over TTL */
172 rr_len
= _getshort( p
);
174 if ( class == C_IN
&& type
== T_TXT
) {
175 int i
, n
, pref
, txt_len
;
179 while ( q
< (char *)p
+ rr_len
&& err
== 0 ) {
180 if ( *q
>= 3 && strncasecmp( q
+ 1, "dx:", 3 ) == 0 ) {
183 while ( isspace( *r
)) {
188 while ( isdigit( *r
)) {
190 pref
+= ( *r
- '0' );
194 if ( dx_count
< MAX_TO_SORT
- 1 ) {
195 dx_pref
[ dx_count
] = pref
;
197 while ( isspace( *r
)) {
201 if ( dx_count
== 0 ) {
202 dxs
= (char **)NSLDAPI_MALLOC( 2 * sizeof( char * ));
204 dxs
= (char **)NSLDAPI_REALLOC( dxs
,
205 ( dx_count
+ 2 ) * sizeof( char * ));
207 if ( dxs
== NULL
|| ( dxs
[ dx_count
] =
208 (char *)NSLDAPI_CALLOC( 1, txt_len
+ 1 ))
213 SAFEMEMCPY( dxs
[ dx_count
], r
, txt_len
);
214 dxs
[ ++dx_count
] = NULL
;
216 q
+= ( *q
+ 1 ); /* move past last TXT record */
223 if ( dx_count
== 0 ) {
227 * sort records based on associated preference value
229 int i
, j
, sort_count
, tmp_pref
;
232 sort_count
= ( dx_count
< MAX_TO_SORT
) ? dx_count
: MAX_TO_SORT
;
233 for ( i
= 0; i
< sort_count
; ++i
) {
234 for ( j
= i
+ 1; j
< sort_count
; ++j
) {
235 if ( dx_pref
[ i
] > dx_pref
[ j
] ) {
236 tmp_pref
= dx_pref
[ i
];
237 dx_pref
[ i
] = dx_pref
[ j
];
238 dx_pref
[ j
] = tmp_pref
;
252 #endif /* LDAP_DNS */