~ubuntu-branches/ubuntu/maverick/bind9/maverick

« back to all changes in this revision

Viewing changes to lib/dns/name.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones, LaMont Jones, Internet Software Consortium, Inc, localization folks
  • Date: 2008-08-02 14:20:20 UTC
  • mfrom: (1.2.1 upstream) (6.1.24 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080802142020-l1hon9jy8lbbjxmg
[LaMont Jones]

* default to using resolvconf if it is installed
* fix sonames and dependencies.  Closes: #149259, #492418
* Do not build-depend libcap2-dev on non-linux.  Closes: #493392
* drop unused query-loc manpage.  Closes: #492564
* lwresd: Deliver /etc/bind directory.  Closes: #490027
* fix query-source comment in default install

[Internet Software Consortium, Inc]

* 9.5.0-P2.  Closes: #492949

[localization folks]

* l10n: Spanish debconf translation.  Closes: #492425 (Ignacio Mondino)
* l10n: Swedish debconf templates.  Closes: #491369 (Martin Ågren)
* l10n: Japanese debconf translations.  Closes: #492048 (Hideki Yamane
  (Debian-JP))
* l10n: Finnish translation.  Closes: #490630 (Esko Arajärvi)
* l10n: Italian debconf translations.  Closes: #492587 (Alessandro Vietta)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2004, 2005  Internet Systems Consortium, Inc. ("ISC")
 
2
 * Copyright (C) 2004-2008  Internet Systems Consortium, Inc. ("ISC")
3
3
 * Copyright (C) 1998-2003  Internet Software Consortium.
4
4
 *
5
 
 * Permission to use, copy, modify, and distribute this software for any
 
5
 * Permission to use, copy, modify, and/or distribute this software for any
6
6
 * purpose with or without fee is hereby granted, provided that the above
7
7
 * copyright notice and this permission notice appear in all copies.
8
8
 *
15
15
 * PERFORMANCE OF THIS SOFTWARE.
16
16
 */
17
17
 
18
 
/* $Id: name.c,v 1.127.2.7.2.14 2005/10/14 01:38:48 marka Exp $ */
 
18
/* $Id: name.c,v 1.163.128.2 2008/03/31 23:46:42 tbox Exp $ */
 
19
 
 
20
/*! \file */
19
21
 
20
22
#include <config.h>
21
23
 
22
24
#include <ctype.h>
 
25
#include <stdlib.h>
23
26
 
24
27
#include <isc/buffer.h>
25
28
#include <isc/hash.h>
26
29
#include <isc/mem.h>
 
30
#include <isc/once.h>
27
31
#include <isc/print.h>
28
32
#include <isc/string.h>
 
33
#include <isc/thread.h>
29
34
#include <isc/util.h>
30
35
 
31
36
#include <dns/compress.h>
122
127
                set_offsets(name, var, NULL); \
123
128
        }
124
129
 
125
 
/*
 
130
/*%
126
131
 * Note:  If additional attributes are added that should not be set for
127
132
 *        empty names, MAKE_EMPTY() must be changed so it clears them.
128
133
 */
134
139
        name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \
135
140
} while (0);
136
141
 
137
 
/*
 
142
/*%
138
143
 * A name is "bindable" if it can be set to point to a new value, i.e.
139
144
 * name->ndata and name->length may be changed.
140
145
 */
142
147
        ((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \
143
148
         == 0)
144
149
 
145
 
/*
 
150
/*%
146
151
 * Note that the name data must be a char array, not a string
147
152
 * literal, to avoid compiler warnings about discarding
148
153
 * the const attribute of a string.
150
155
static unsigned char root_ndata[] = { '\0' };
151
156
static unsigned char root_offsets[] = { 0 };
152
157
 
153
 
static dns_name_t root = 
 
158
static dns_name_t root =
154
159
{
155
160
        DNS_NAME_MAGIC,
156
161
        root_ndata, 1, 1,
182
187
unsigned int
183
188
dns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive);
184
189
 
 
190
/*
 
191
 * dns_name_t to text post-conversion procedure.
 
192
 */
 
193
#ifdef ISC_PLATFORM_USETHREADS
 
194
static int thread_key_initialized = 0;
 
195
static isc_mutex_t thread_key_mutex;
 
196
static isc_mem_t *thread_key_mctx = NULL;
 
197
static isc_thread_key_t totext_filter_proc_key;
 
198
static isc_once_t once = ISC_ONCE_INIT;
 
199
#else
 
200
static dns_name_totextfilter_t totext_filter_proc = NULL;
 
201
#endif
 
202
 
185
203
static void
186
204
set_offsets(const dns_name_t *name, unsigned char *offsets,
187
205
            dns_name_t *set_name);
280
298
        REQUIRE(name->labels > 0);
281
299
        REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
282
300
 
283
 
        /* 
 
301
        /*
284
302
         * Root label.
285
303
         */
286
304
        if (name->length == 1)
294
312
                if (!domainchar(ch))
295
313
                        return (ISC_FALSE);
296
314
        }
297
 
        
 
315
 
298
316
        if (ndata == name->ndata + name->length)
299
317
                return (ISC_FALSE);
300
318
 
329
347
        REQUIRE(VALID_NAME(name));
330
348
        REQUIRE(name->labels > 0);
331
349
        REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
332
 
        
333
 
        /* 
 
350
 
 
351
        /*
334
352
         * Root label.
335
353
         */
336
354
        if (name->length == 1)
385
403
        return (ISC_FALSE);
386
404
}
387
405
 
 
406
isc_boolean_t
 
407
dns_name_internalwildcard(const dns_name_t *name) {
 
408
        unsigned char *ndata;
 
409
        unsigned int count;
 
410
        unsigned int label;
 
411
 
 
412
        /*
 
413
         * Does 'name' contain a internal wildcard?
 
414
         */
 
415
 
 
416
        REQUIRE(VALID_NAME(name));
 
417
        REQUIRE(name->labels > 0);
 
418
 
 
419
        /*
 
420
         * Skip first label.
 
421
         */
 
422
        ndata = name->ndata;
 
423
        count = *ndata++;
 
424
        INSIST(count <= 63);
 
425
        ndata += count;
 
426
        label = 1;
 
427
        /*
 
428
         * Check all but the last of the remaining labels.
 
429
         */
 
430
        while (label + 1 < name->labels) {
 
431
                count = *ndata++;
 
432
                INSIST(count <= 63);
 
433
                if (count == 1 && *ndata == '*')
 
434
                        return (ISC_TRUE);
 
435
                ndata += count;
 
436
                label++;
 
437
        }
 
438
        return (ISC_FALSE);
 
439
}
 
440
 
388
441
static inline unsigned int
389
442
name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
390
443
        unsigned int length;
664
717
        return (ISC_TRUE);
665
718
}
666
719
 
 
720
isc_boolean_t
 
721
dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) {
 
722
 
 
723
        /*
 
724
         * Are 'name1' and 'name2' equal?
 
725
         *
 
726
         * Note: It makes no sense for one of the names to be relative and the
 
727
         * other absolute.  If both names are relative, then to be meaningfully
 
728
         * compared the caller must ensure that they are both relative to the
 
729
         * same domain.
 
730
         */
 
731
 
 
732
        REQUIRE(VALID_NAME(name1));
 
733
        REQUIRE(VALID_NAME(name2));
 
734
        /*
 
735
         * Either name1 is absolute and name2 is absolute, or neither is.
 
736
         */
 
737
        REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
 
738
                (name2->attributes & DNS_NAMEATTR_ABSOLUTE));
 
739
 
 
740
        if (name1->length != name2->length)
 
741
                return (ISC_FALSE);
 
742
 
 
743
        if (memcmp(name1->ndata, name2->ndata, name1->length) != 0)
 
744
                return (ISC_FALSE);
 
745
 
 
746
        return (ISC_TRUE);
 
747
}
 
748
 
667
749
int
668
750
dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) {
669
751
        unsigned int l1, l2, l, count1, count2, count;
836
918
 
837
919
        target->ndata = &source->ndata[firstoffset];
838
920
        target->length = endoffset - firstoffset;
839
 
        
 
921
 
840
922
        if (first + n == source->labels && n > 0 &&
841
923
            (source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
842
924
                target->attributes |= DNS_NAMEATTR_ABSOLUTE;
856
938
}
857
939
 
858
940
void
859
 
dns_name_clone(dns_name_t *source, dns_name_t *target) {
 
941
dns_name_clone(const dns_name_t *source, dns_name_t *target) {
860
942
 
861
943
        /*
862
944
         * Make 'target' refer to the same name as 'source'.
909
991
                name->length = len;
910
992
        } else {
911
993
                name->ndata = r->base;
912
 
                name->length = (r->length <= DNS_NAME_MAXWIRE) ? 
 
994
                name->length = (r->length <= DNS_NAME_MAXWIRE) ?
913
995
                        r->length : DNS_NAME_MAXWIRE;
914
996
        }
915
997
 
967
1049
        REQUIRE(ISC_BUFFER_VALID(source));
968
1050
        REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
969
1051
                (target == NULL && ISC_BUFFER_VALID(name->buffer)));
970
 
        
 
1052
 
971
1053
        downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0);
972
1054
 
973
1055
        if (target == NULL && name->buffer != NULL) {
1189
1271
        return (ISC_R_SUCCESS);
1190
1272
}
1191
1273
 
 
1274
#ifdef ISC_PLATFORM_USETHREADS
 
1275
static void
 
1276
free_specific(void *arg) {
 
1277
        dns_name_totextfilter_t *mem = arg;
 
1278
        isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
 
1279
        /* Stop use being called again. */
 
1280
        (void)isc_thread_key_setspecific(totext_filter_proc_key, NULL);
 
1281
}
 
1282
 
 
1283
static void
 
1284
thread_key_mutex_init(void) {
 
1285
        RUNTIME_CHECK(isc_mutex_init(&thread_key_mutex) == ISC_R_SUCCESS);
 
1286
}
 
1287
 
 
1288
static isc_result_t
 
1289
totext_filter_proc_key_init(void) {
 
1290
        isc_result_t result;
 
1291
 
 
1292
        /*
 
1293
         * We need the call to isc_once_do() to support profiled mutex
 
1294
         * otherwise thread_key_mutex could be initialized at compile time.
 
1295
         */
 
1296
        result = isc_once_do(&once, thread_key_mutex_init);
 
1297
        if (result != ISC_R_SUCCESS)
 
1298
                return (result);
 
1299
 
 
1300
        if (!thread_key_initialized) {
 
1301
                LOCK(&thread_key_mutex);
 
1302
                if (thread_key_mctx == NULL)
 
1303
                        result = isc_mem_create2(0, 0, &thread_key_mctx, 0);
 
1304
                if (result != ISC_R_SUCCESS)
 
1305
                        goto unlock;
 
1306
                isc_mem_setname(thread_key_mctx, "threadkey", NULL);
 
1307
                isc_mem_setdestroycheck(thread_key_mctx, ISC_FALSE);
 
1308
 
 
1309
                if (!thread_key_initialized &&
 
1310
                     isc_thread_key_create(&totext_filter_proc_key,
 
1311
                                           free_specific) != 0) {
 
1312
                        result = ISC_R_FAILURE;
 
1313
                        isc_mem_detach(&thread_key_mctx);
 
1314
                } else
 
1315
                        thread_key_initialized = 1;
 
1316
 unlock:
 
1317
                UNLOCK(&thread_key_mutex);
 
1318
        }
 
1319
        return (result);
 
1320
}
 
1321
#endif
 
1322
 
1192
1323
isc_result_t
1193
1324
dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
1194
1325
                isc_buffer_t *target)
1200
1331
        unsigned int trem, count;
1201
1332
        unsigned int labels;
1202
1333
        isc_boolean_t saw_root = ISC_FALSE;
 
1334
        unsigned int oused = target->used;
 
1335
#ifdef ISC_PLATFORM_USETHREADS
 
1336
        dns_name_totextfilter_t *mem;
 
1337
        dns_name_totextfilter_t totext_filter_proc = NULL;
 
1338
        isc_result_t result;
 
1339
#endif
1203
1340
 
1204
1341
        /*
1205
1342
         * This function assumes the name is in proper uncompressed
1208
1345
        REQUIRE(VALID_NAME(name));
1209
1346
        REQUIRE(ISC_BUFFER_VALID(target));
1210
1347
 
 
1348
#ifdef ISC_PLATFORM_USETHREADS
 
1349
        result = totext_filter_proc_key_init();
 
1350
        if (result != ISC_R_SUCCESS)
 
1351
                return (result);
 
1352
#endif
1211
1353
        ndata = name->ndata;
1212
1354
        nlen = name->length;
1213
1355
        labels = name->labels;
1339
1481
 
1340
1482
        isc_buffer_add(target, tlen - trem);
1341
1483
 
 
1484
#ifdef ISC_PLATFORM_USETHREADS
 
1485
        mem = isc_thread_key_getspecific(totext_filter_proc_key);
 
1486
        if (mem != NULL)
 
1487
                totext_filter_proc = *mem;
 
1488
#endif
 
1489
        if (totext_filter_proc != NULL)
 
1490
                return ((*totext_filter_proc)(target, oused, saw_root));
 
1491
 
1342
1492
        return (ISC_R_SUCCESS);
1343
1493
}
1344
1494
 
1573
1723
{
1574
1724
        unsigned char *cdata, *ndata;
1575
1725
        unsigned int cused; /* Bytes of compressed name data used */
1576
 
        unsigned int hops,  nused, labels, n, nmax;
 
1726
        unsigned int nused, labels, n, nmax;
1577
1727
        unsigned int current, new_current, biggest_pointer;
1578
1728
        isc_boolean_t done;
1579
1729
        fw_state state = fw_start;
1581
1731
        unsigned char *offsets;
1582
1732
        dns_offsets_t odata;
1583
1733
        isc_boolean_t downcase;
 
1734
        isc_boolean_t seen_pointer;
1584
1735
 
1585
1736
        /*
1586
1737
         * Copy the possibly-compressed name at source into target,
1587
 
         * decompressing it.
 
1738
         * decompressing it.  Loop prevention is performed by checking
 
1739
         * the new pointer against biggest_pointer.
1588
1740
         */
1589
1741
 
1590
1742
        REQUIRE(VALID_NAME(name));
1618
1770
         * Set up.
1619
1771
         */
1620
1772
        labels = 0;
1621
 
        hops = 0;
1622
1773
        done = ISC_FALSE;
1623
1774
 
1624
1775
        ndata = isc_buffer_used(target);
1625
1776
        nused = 0;
 
1777
        seen_pointer = ISC_FALSE;
1626
1778
 
1627
1779
        /*
1628
1780
         * Find the maximum number of uncompressed target name
1648
1800
        while (current < source->active && !done) {
1649
1801
                c = *cdata++;
1650
1802
                current++;
1651
 
                if (hops == 0)
 
1803
                if (!seen_pointer)
1652
1804
                        cused++;
1653
1805
 
1654
1806
                switch (state) {
1704
1856
                                return (DNS_R_BADPOINTER);
1705
1857
                        biggest_pointer = new_current;
1706
1858
                        current = new_current;
1707
 
                        cdata = (unsigned char *)source->base +
1708
 
                                current;
1709
 
                        hops++;
1710
 
                        if (hops > DNS_POINTER_MAXHOPS)
1711
 
                                return (DNS_R_TOOMANYHOPS);
 
1859
                        cdata = (unsigned char *)source->base + current;
 
1860
                        seen_pointer = ISC_TRUE;
1712
1861
                        state = fw_start;
1713
1862
                        break;
1714
1863
                default:
1744
1893
                 * big enough buffer.
1745
1894
                 */
1746
1895
                return (ISC_R_NOSPACE);
1747
 
 
1748
1896
}
1749
1897
 
1750
1898
isc_result_t
1751
 
dns_name_towire(dns_name_t *name, dns_compress_t *cctx, isc_buffer_t *target) {
 
1899
dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
 
1900
                isc_buffer_t *target)
 
1901
{
1752
1902
        unsigned int methods;
1753
1903
        isc_uint16_t offset;
1754
1904
        dns_name_t gp;  /* Global compression prefix */
1781
1931
 
1782
1932
        methods = dns_compress_getmethods(cctx);
1783
1933
 
1784
 
        if ((methods & DNS_COMPRESS_GLOBAL14) != 0)
 
1934
        if ((name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 &&
 
1935
            (methods & DNS_COMPRESS_GLOBAL14) != 0)
1785
1936
                gf = dns_compress_findglobal(cctx, name, &gp, &go);
1786
1937
        else
1787
1938
                gf = ISC_FALSE;
1962
2113
}
1963
2114
 
1964
2115
isc_result_t
1965
 
dns_name_dup(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) {
 
2116
dns_name_dup(const dns_name_t *source, isc_mem_t *mctx,
 
2117
             dns_name_t *target)
 
2118
{
1966
2119
        /*
1967
2120
         * Make 'target' a dynamically allocated copy of 'source'.
1968
2121
         */
2120
2273
        return (ISC_R_SUCCESS);
2121
2274
}
2122
2275
 
 
2276
isc_result_t
 
2277
dns_name_settotextfilter(dns_name_totextfilter_t proc) {
 
2278
#ifdef ISC_PLATFORM_USETHREADS
 
2279
        isc_result_t result;
 
2280
        dns_name_totextfilter_t *mem;
 
2281
        int res;
 
2282
 
 
2283
        result = totext_filter_proc_key_init();
 
2284
        if (result != ISC_R_SUCCESS)
 
2285
                return (result);
 
2286
 
 
2287
        /*
 
2288
         * If we already have been here set / clear as appropriate.
 
2289
         * Otherwise allocate memory.
 
2290
         */
 
2291
        mem = isc_thread_key_getspecific(totext_filter_proc_key);
 
2292
        if (mem != NULL && proc != NULL) {
 
2293
                *mem = proc;
 
2294
                return (ISC_R_SUCCESS);
 
2295
        }
 
2296
        if (proc == NULL) {
 
2297
                isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
 
2298
                res = isc_thread_key_setspecific(totext_filter_proc_key, NULL);
 
2299
                if (res != 0)
 
2300
                        result = ISC_R_UNEXPECTED;
 
2301
                return (result);
 
2302
        }
 
2303
 
 
2304
        mem = isc_mem_get(thread_key_mctx, sizeof(*mem));
 
2305
        if (mem == NULL)
 
2306
                return (ISC_R_NOMEMORY);
 
2307
        *mem = proc;
 
2308
        if (isc_thread_key_setspecific(totext_filter_proc_key, mem) != 0) {
 
2309
                isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
 
2310
                result = ISC_R_UNEXPECTED;
 
2311
        }
 
2312
        return (result);
 
2313
#else
 
2314
        totext_filter_proc = proc;
 
2315
        return (ISC_R_SUCCESS);
 
2316
#endif
 
2317
}
 
2318
 
2123
2319
void
2124
2320
dns_name_format(dns_name_t *name, char *cp, unsigned int size) {
2125
2321
        isc_result_t result;
2194
2390
        return (ISC_R_SUCCESS);
2195
2391
}
2196
2392
 
 
2393
void
 
2394
dns_name_destroy(void) {
 
2395
#ifdef ISC_PLATFORM_USETHREADS
 
2396
        RUNTIME_CHECK(isc_once_do(&once, thread_key_mutex_init)
 
2397
                                  == ISC_R_SUCCESS);
 
2398
 
 
2399
        LOCK(&thread_key_mutex);
 
2400
        if (thread_key_initialized) {
 
2401
                isc_mem_detach(&thread_key_mctx);
 
2402
                isc_thread_key_delete(totext_filter_proc_key);
 
2403
                thread_key_initialized = 0;
 
2404
        }
 
2405
        UNLOCK(&thread_key_mutex);
 
2406
 
 
2407
#endif
 
2408
}