1998-12-12 20:48:14 +00:00
|
|
|
/*
|
2018-02-23 09:53:12 +01:00
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
2000-08-01 01:33:37 +00:00
|
|
|
*
|
2016-06-27 14:56:38 +10:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
2018-02-23 09:53:12 +01:00
|
|
|
*
|
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
|
|
* information regarding copyright ownership.
|
1998-12-12 20:48:14 +00:00
|
|
|
*/
|
1998-12-12 19:25:20 +00:00
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
|
|
|
|
/*! \file */
|
2000-06-22 22:00:42 +00:00
|
|
|
|
1998-12-12 19:25:20 +00:00
|
|
|
#include <config.h>
|
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
#include <ctype.h>
|
2018-03-28 14:19:37 +02:00
|
|
|
#include <inttypes.h>
|
2018-04-17 08:29:14 -07:00
|
|
|
#include <stdbool.h>
|
2005-09-10 01:02:08 +00:00
|
|
|
#include <stdlib.h>
|
1998-12-04 02:27:01 +00:00
|
|
|
|
2000-04-04 20:10:29 +00:00
|
|
|
#include <isc/buffer.h>
|
2003-07-25 02:22:26 +00:00
|
|
|
#include <isc/hash.h>
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <isc/mem.h>
|
2005-09-09 06:17:03 +00:00
|
|
|
#include <isc/once.h>
|
2000-04-12 19:07:12 +00:00
|
|
|
#include <isc/print.h>
|
2015-12-09 19:07:20 +05:30
|
|
|
#include <isc/random.h>
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <isc/string.h>
|
2005-09-09 06:17:03 +00:00
|
|
|
#include <isc/thread.h>
|
2000-04-28 01:12:23 +00:00
|
|
|
#include <isc/util.h>
|
1998-12-04 02:27:01 +00:00
|
|
|
|
1999-01-06 20:04:41 +00:00
|
|
|
#include <dns/compress.h>
|
2009-03-11 07:02:34 +00:00
|
|
|
#include <dns/fixedname.h>
|
2001-01-03 00:05:15 +00:00
|
|
|
#include <dns/name.h>
|
|
|
|
#include <dns/result.h>
|
1998-12-04 02:27:01 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
#define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC)
|
1998-12-04 02:27:01 +00:00
|
|
|
|
|
|
|
typedef enum {
|
1999-01-06 05:41:20 +00:00
|
|
|
ft_init = 0,
|
|
|
|
ft_start,
|
|
|
|
ft_ordinary,
|
|
|
|
ft_initialescape,
|
|
|
|
ft_escape,
|
|
|
|
ft_escdecimal,
|
1999-01-27 23:39:40 +00:00
|
|
|
ft_at
|
1999-01-06 05:41:20 +00:00
|
|
|
} ft_state;
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
fw_start = 0,
|
|
|
|
fw_ordinary,
|
2000-03-23 05:18:46 +00:00
|
|
|
fw_newcurrent
|
1999-01-06 05:41:20 +00:00
|
|
|
} fw_state;
|
1998-12-04 02:27:01 +00:00
|
|
|
|
|
|
|
static char digitvalue[256] = {
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
|
|
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
|
|
|
|
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
|
|
|
|
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
|
|
|
|
};
|
|
|
|
|
|
|
|
static unsigned char maptolower[] = {
|
|
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
|
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
|
|
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
|
|
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
|
|
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
|
|
|
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
|
|
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
|
|
|
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
|
|
|
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
|
|
|
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
|
|
|
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
|
|
|
0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
|
|
|
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
|
|
|
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
|
|
|
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
|
|
|
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
|
|
|
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
|
|
|
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
|
|
|
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
|
|
|
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
|
|
|
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
|
|
|
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
|
|
|
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
|
|
|
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
|
|
|
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
|
|
|
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
|
|
|
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
|
|
|
|
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
|
|
|
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
|
|
|
|
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
|
|
|
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
|
|
|
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
|
|
|
};
|
|
|
|
|
1998-12-05 01:42:30 +00:00
|
|
|
#define CONVERTTOASCII(c)
|
|
|
|
#define CONVERTFROMASCII(c)
|
|
|
|
|
2016-08-29 18:52:49 +05:30
|
|
|
#define INIT_OFFSETS(name, var, default_offsets) \
|
|
|
|
if ((name)->offsets != NULL) \
|
|
|
|
var = (name)->offsets; \
|
1999-01-09 00:33:15 +00:00
|
|
|
else \
|
2016-08-29 18:52:49 +05:30
|
|
|
var = (default_offsets);
|
1999-01-09 00:33:15 +00:00
|
|
|
|
2016-08-29 18:52:49 +05:30
|
|
|
#define SETUP_OFFSETS(name, var, default_offsets) \
|
|
|
|
if ((name)->offsets != NULL) \
|
|
|
|
var = (name)->offsets; \
|
1999-01-09 00:33:15 +00:00
|
|
|
else { \
|
2016-08-29 18:52:49 +05:30
|
|
|
var = (default_offsets); \
|
2000-06-01 18:26:56 +00:00
|
|
|
set_offsets(name, var, NULL); \
|
1999-01-09 00:33:15 +00:00
|
|
|
}
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
1999-08-12 20:26:45 +00:00
|
|
|
* Note: If additional attributes are added that should not be set for
|
|
|
|
* empty names, MAKE_EMPTY() must be changed so it clears them.
|
|
|
|
*/
|
|
|
|
#define MAKE_EMPTY(name) \
|
|
|
|
do { \
|
|
|
|
name->ndata = NULL; \
|
|
|
|
name->length = 0; \
|
|
|
|
name->labels = 0; \
|
|
|
|
name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \
|
|
|
|
} while (0);
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
1999-08-19 23:26:16 +00:00
|
|
|
* A name is "bindable" if it can be set to point to a new value, i.e.
|
|
|
|
* name->ndata and name->length may be changed.
|
|
|
|
*/
|
|
|
|
#define BINDABLE(name) \
|
|
|
|
((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \
|
|
|
|
== 0)
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
2001-01-11 21:07:21 +00:00
|
|
|
* Note that the name data must be a char array, not a string
|
|
|
|
* literal, to avoid compiler warnings about discarding
|
|
|
|
* the const attribute of a string.
|
2000-06-01 18:26:56 +00:00
|
|
|
*/
|
2017-11-13 16:58:12 +11:00
|
|
|
static unsigned char root_ndata[] = { "" };
|
2001-01-11 21:07:21 +00:00
|
|
|
static unsigned char root_offsets[] = { 0 };
|
|
|
|
|
2017-11-13 16:58:12 +11:00
|
|
|
static dns_name_t root = DNS_NAME_INITABSOLUTE(root_ndata, root_offsets);
|
2016-12-30 15:45:08 +11:00
|
|
|
LIBDNS_EXTERNAL_DATA const dns_name_t *dns_rootname = &root;
|
2001-01-11 21:07:21 +00:00
|
|
|
|
2017-11-13 16:58:12 +11:00
|
|
|
static unsigned char wild_ndata[] = { "\001*" };
|
2001-01-11 21:07:21 +00:00
|
|
|
static unsigned char wild_offsets[] = { 0 };
|
|
|
|
|
2017-11-13 16:58:12 +11:00
|
|
|
static dns_name_t const wild =
|
|
|
|
DNS_NAME_INITNONABSOLUTE(wild_ndata, wild_offsets);
|
1999-08-12 07:48:16 +00:00
|
|
|
|
2016-12-30 15:45:08 +11:00
|
|
|
LIBDNS_EXTERNAL_DATA const dns_name_t *dns_wildcardname = &wild;
|
1999-08-12 07:48:16 +00:00
|
|
|
|
2005-09-09 06:17:03 +00:00
|
|
|
/*
|
|
|
|
* dns_name_t to text post-conversion procedure.
|
|
|
|
*/
|
2005-09-18 07:16:24 +00:00
|
|
|
static int thread_key_initialized = 0;
|
|
|
|
static isc_mutex_t thread_key_mutex;
|
|
|
|
static isc_mem_t *thread_key_mctx = NULL;
|
2005-09-09 06:17:03 +00:00
|
|
|
static isc_thread_key_t totext_filter_proc_key;
|
2005-09-10 00:31:25 +00:00
|
|
|
static isc_once_t once = ISC_ONCE_INIT;
|
2005-09-09 06:17:03 +00:00
|
|
|
|
2000-06-01 18:26:56 +00:00
|
|
|
static void
|
|
|
|
set_offsets(const dns_name_t *name, unsigned char *offsets,
|
|
|
|
dns_name_t *set_name);
|
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
void
|
1999-01-09 00:33:15 +00:00
|
|
|
dns_name_init(dns_name_t *name, unsigned char *offsets) {
|
1998-12-04 02:27:01 +00:00
|
|
|
/*
|
1999-08-12 20:26:45 +00:00
|
|
|
* Initialize 'name'.
|
1998-12-04 02:27:01 +00:00
|
|
|
*/
|
2001-01-03 00:05:15 +00:00
|
|
|
DNS_NAME_INIT(name, offsets);
|
1999-01-06 05:41:20 +00:00
|
|
|
}
|
|
|
|
|
2000-07-14 19:12:54 +00:00
|
|
|
void
|
|
|
|
dns_name_reset(dns_name_t *name) {
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
REQUIRE(BINDABLE(name));
|
|
|
|
|
2001-01-03 00:05:15 +00:00
|
|
|
DNS_NAME_RESET(name);
|
2000-07-14 19:12:54 +00:00
|
|
|
}
|
|
|
|
|
1999-01-06 05:41:20 +00:00
|
|
|
void
|
|
|
|
dns_name_invalidate(dns_name_t *name) {
|
|
|
|
/*
|
|
|
|
* Make 'name' invalid.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
|
|
|
|
name->magic = 0;
|
1998-12-04 02:27:01 +00:00
|
|
|
name->ndata = NULL;
|
|
|
|
name->length = 0;
|
|
|
|
name->labels = 0;
|
1999-02-06 01:26:00 +00:00
|
|
|
name->attributes = 0;
|
1999-01-09 00:33:15 +00:00
|
|
|
name->offsets = NULL;
|
1999-03-08 18:55:28 +00:00
|
|
|
name->buffer = NULL;
|
1999-01-09 00:33:15 +00:00
|
|
|
ISC_LINK_INIT(name, link);
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2013-05-07 13:54:58 -07:00
|
|
|
dns_name_isvalid(const dns_name_t *name) {
|
|
|
|
unsigned char *ndata, *offsets;
|
|
|
|
unsigned int offset, count, length, nlabels;
|
|
|
|
|
|
|
|
if (!VALID_NAME(name))
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2013-05-07 13:54:58 -07:00
|
|
|
|
|
|
|
if (name->length > 255U || name->labels > 127U)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2013-05-07 13:54:58 -07:00
|
|
|
|
|
|
|
ndata = name->ndata;
|
|
|
|
length = name->length;
|
|
|
|
offsets = name->offsets;
|
|
|
|
offset = 0;
|
|
|
|
nlabels = 0;
|
|
|
|
|
|
|
|
while (offset != length) {
|
|
|
|
count = *ndata;
|
|
|
|
if (count > 63U)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2013-05-07 13:54:58 -07:00
|
|
|
if (offsets != NULL && offsets[nlabels] != offset)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2013-05-07 13:54:58 -07:00
|
|
|
|
|
|
|
nlabels++;
|
|
|
|
offset += count + 1;
|
|
|
|
ndata += count + 1;
|
|
|
|
if (offset > length)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2013-05-07 13:54:58 -07:00
|
|
|
|
|
|
|
if (count == 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nlabels != name->labels || offset != name->length)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2013-05-07 13:54:58 -07:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
2013-05-07 13:54:58 -07:00
|
|
|
}
|
|
|
|
|
1999-03-08 18:55:28 +00:00
|
|
|
void
|
|
|
|
dns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) {
|
|
|
|
/*
|
2000-06-06 17:47:54 +00:00
|
|
|
* Dedicate a buffer for use with 'name'.
|
1999-03-08 18:55:28 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
REQUIRE((buffer != NULL && name->buffer == NULL) ||
|
1999-07-28 02:20:22 +00:00
|
|
|
(buffer == NULL));
|
1999-03-08 18:55:28 +00:00
|
|
|
|
|
|
|
name->buffer = buffer;
|
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2000-06-01 18:26:56 +00:00
|
|
|
dns_name_hasbuffer(const dns_name_t *name) {
|
1999-03-08 18:55:28 +00:00
|
|
|
/*
|
|
|
|
* Does 'name' have a dedicated buffer?
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
|
|
|
|
if (name->buffer != NULL)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
1999-03-08 18:55:28 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
1999-03-08 18:55:28 +00:00
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2000-06-01 18:26:56 +00:00
|
|
|
dns_name_isabsolute(const dns_name_t *name) {
|
1999-01-09 00:33:15 +00:00
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
/*
|
|
|
|
* Does 'name' end in the root label?
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
|
1999-02-06 01:26:00 +00:00
|
|
|
if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
|
|
|
return (false);
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
|
2004-02-27 20:41:51 +00:00
|
|
|
#define hyphenchar(c) ((c) == 0x2d)
|
|
|
|
#define asterchar(c) ((c) == 0x2a)
|
|
|
|
#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
|
|
|
|
|| ((c) >= 0x61 && (c) <= 0x7a))
|
|
|
|
#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
|
|
|
|
#define borderchar(c) (alphachar(c) || digitchar(c))
|
|
|
|
#define middlechar(c) (borderchar(c) || hyphenchar(c))
|
|
|
|
#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2004-02-27 20:41:51 +00:00
|
|
|
dns_name_ismailbox(const dns_name_t *name) {
|
|
|
|
unsigned char *ndata, ch;
|
|
|
|
unsigned int n;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool first;
|
2004-02-27 20:41:51 +00:00
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
REQUIRE(name->labels > 0);
|
|
|
|
REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
|
|
|
|
|
2008-04-01 23:47:10 +00:00
|
|
|
/*
|
2004-02-27 20:41:51 +00:00
|
|
|
* Root label.
|
|
|
|
*/
|
|
|
|
if (name->length == 1)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
2004-02-27 20:41:51 +00:00
|
|
|
|
|
|
|
ndata = name->ndata;
|
|
|
|
n = *ndata++;
|
2004-04-19 21:47:43 +00:00
|
|
|
INSIST(n <= 63);
|
2004-02-27 20:41:51 +00:00
|
|
|
while (n--) {
|
|
|
|
ch = *ndata++;
|
|
|
|
if (!domainchar(ch))
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2004-02-27 20:41:51 +00:00
|
|
|
}
|
2008-04-01 23:47:10 +00:00
|
|
|
|
2004-02-27 20:41:51 +00:00
|
|
|
if (ndata == name->ndata + name->length)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2004-02-27 20:41:51 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* RFC292/RFC1123 hostname.
|
|
|
|
*/
|
|
|
|
while (ndata < (name->ndata + name->length)) {
|
|
|
|
n = *ndata++;
|
2004-04-19 21:47:43 +00:00
|
|
|
INSIST(n <= 63);
|
2018-04-17 08:29:14 -07:00
|
|
|
first = true;
|
2004-02-27 20:41:51 +00:00
|
|
|
while (n--) {
|
|
|
|
ch = *ndata++;
|
|
|
|
if (first || n == 0) {
|
|
|
|
if (!borderchar(ch))
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2004-02-27 20:41:51 +00:00
|
|
|
} else {
|
|
|
|
if (!middlechar(ch))
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2004-02-27 20:41:51 +00:00
|
|
|
}
|
2018-04-17 08:29:14 -07:00
|
|
|
first = false;
|
2004-02-27 20:41:51 +00:00
|
|
|
}
|
|
|
|
}
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
2004-02-27 20:41:51 +00:00
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
|
|
|
dns_name_ishostname(const dns_name_t *name, bool wildcard) {
|
2004-02-27 20:41:51 +00:00
|
|
|
unsigned char *ndata, ch;
|
|
|
|
unsigned int n;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool first;
|
2004-02-27 20:41:51 +00:00
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
REQUIRE(name->labels > 0);
|
|
|
|
REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
|
2008-04-01 23:47:10 +00:00
|
|
|
|
|
|
|
/*
|
2004-02-27 20:41:51 +00:00
|
|
|
* Root label.
|
|
|
|
*/
|
|
|
|
if (name->length == 1)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
2004-02-27 20:41:51 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Skip wildcard if this is a ownername.
|
|
|
|
*/
|
|
|
|
ndata = name->ndata;
|
|
|
|
if (wildcard && ndata[0] == 1 && ndata[1] == '*')
|
|
|
|
ndata += 2;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* RFC292/RFC1123 hostname.
|
|
|
|
*/
|
|
|
|
while (ndata < (name->ndata + name->length)) {
|
|
|
|
n = *ndata++;
|
2004-04-19 21:47:43 +00:00
|
|
|
INSIST(n <= 63);
|
2018-04-17 08:29:14 -07:00
|
|
|
first = true;
|
2004-02-27 20:41:51 +00:00
|
|
|
while (n--) {
|
|
|
|
ch = *ndata++;
|
|
|
|
if (first || n == 0) {
|
|
|
|
if (!borderchar(ch))
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2004-02-27 20:41:51 +00:00
|
|
|
} else {
|
|
|
|
if (!middlechar(ch))
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2004-02-27 20:41:51 +00:00
|
|
|
}
|
2018-04-17 08:29:14 -07:00
|
|
|
first = false;
|
2004-02-27 20:41:51 +00:00
|
|
|
}
|
|
|
|
}
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
2004-02-27 20:41:51 +00:00
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2000-06-01 18:26:56 +00:00
|
|
|
dns_name_iswildcard(const dns_name_t *name) {
|
1999-08-12 01:29:03 +00:00
|
|
|
unsigned char *ndata;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Is 'name' a wildcard name?
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
REQUIRE(name->labels > 0);
|
|
|
|
|
|
|
|
if (name->length >= 2) {
|
|
|
|
ndata = name->ndata;
|
|
|
|
if (ndata[0] == 1 && ndata[1] == '*')
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
1999-08-12 01:29:03 +00:00
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
1999-08-12 01:29:03 +00:00
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2005-01-09 23:40:04 +00:00
|
|
|
dns_name_internalwildcard(const dns_name_t *name) {
|
|
|
|
unsigned char *ndata;
|
|
|
|
unsigned int count;
|
|
|
|
unsigned int label;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Does 'name' contain a internal wildcard?
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
REQUIRE(name->labels > 0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Skip first label.
|
|
|
|
*/
|
|
|
|
ndata = name->ndata;
|
|
|
|
count = *ndata++;
|
|
|
|
INSIST(count <= 63);
|
|
|
|
ndata += count;
|
|
|
|
label = 1;
|
|
|
|
/*
|
|
|
|
* Check all but the last of the remaining labels.
|
|
|
|
*/
|
|
|
|
while (label + 1 < name->labels) {
|
|
|
|
count = *ndata++;
|
|
|
|
INSIST(count <= 63);
|
|
|
|
if (count == 1 && *ndata == '*')
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
2005-01-09 23:40:04 +00:00
|
|
|
ndata += count;
|
|
|
|
label++;
|
|
|
|
}
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2005-01-09 23:40:04 +00:00
|
|
|
}
|
|
|
|
|
2001-12-04 01:32:44 +00:00
|
|
|
unsigned int
|
2018-04-17 08:29:14 -07:00
|
|
|
dns_name_hash(const dns_name_t *name, bool case_sensitive) {
|
2015-12-09 19:07:20 +05:30
|
|
|
unsigned int length;
|
|
|
|
|
2001-12-04 01:32:44 +00:00
|
|
|
/*
|
|
|
|
* Provide a hash value for 'name'.
|
|
|
|
*/
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
|
|
|
|
if (name->labels == 0)
|
|
|
|
return (0);
|
|
|
|
|
2015-12-09 19:07:20 +05:30
|
|
|
length = name->length;
|
|
|
|
if (length > 16)
|
|
|
|
length = 16;
|
|
|
|
|
|
|
|
return (isc_hash_function_reverse(name->ndata, length,
|
|
|
|
case_sensitive, NULL));
|
2001-12-04 01:32:44 +00:00
|
|
|
}
|
|
|
|
|
2003-07-25 02:22:26 +00:00
|
|
|
unsigned int
|
2018-04-17 08:29:14 -07:00
|
|
|
dns_name_fullhash(const dns_name_t *name, bool case_sensitive) {
|
2003-07-25 02:22:26 +00:00
|
|
|
/*
|
|
|
|
* Provide a hash value for 'name'.
|
|
|
|
*/
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
|
|
|
|
if (name->labels == 0)
|
|
|
|
return (0);
|
|
|
|
|
2015-12-09 19:07:20 +05:30
|
|
|
return (isc_hash_function_reverse(name->ndata, name->length,
|
|
|
|
case_sensitive, NULL));
|
2003-07-25 02:22:26 +00:00
|
|
|
}
|
|
|
|
|
1999-02-16 08:18:44 +00:00
|
|
|
dns_namereln_t
|
2000-06-01 18:26:56 +00:00
|
|
|
dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
|
2003-10-25 00:31:12 +00:00
|
|
|
int *orderp, unsigned int *nlabelsp)
|
1999-02-16 08:18:44 +00:00
|
|
|
{
|
2002-08-27 04:53:43 +00:00
|
|
|
unsigned int l1, l2, l, count1, count2, count, nlabels;
|
2000-04-26 23:22:53 +00:00
|
|
|
int cdiff, ldiff, chdiff;
|
1998-12-04 02:27:01 +00:00
|
|
|
unsigned char *label1, *label2;
|
1999-01-09 00:33:15 +00:00
|
|
|
unsigned char *offsets1, *offsets2;
|
|
|
|
dns_offsets_t odata1, odata2;
|
1999-02-16 08:18:44 +00:00
|
|
|
dns_namereln_t namereln = dns_namereln_none;
|
1998-12-04 02:27:01 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine the relative ordering under the DNSSEC order relation of
|
1999-02-16 08:18:44 +00:00
|
|
|
* 'name1' and 'name2', and also determine the hierarchical
|
|
|
|
* relationship of the names.
|
|
|
|
*
|
|
|
|
* Note: It makes no sense for one of the names to be relative and the
|
|
|
|
* other absolute. If both names are relative, then to be meaningfully
|
|
|
|
* compared the caller must ensure that they are both relative to the
|
|
|
|
* same domain.
|
1998-12-04 02:27:01 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name1));
|
|
|
|
REQUIRE(VALID_NAME(name2));
|
1999-02-16 08:18:44 +00:00
|
|
|
REQUIRE(orderp != NULL);
|
|
|
|
REQUIRE(nlabelsp != NULL);
|
|
|
|
/*
|
|
|
|
* Either name1 is absolute and name2 is absolute, or neither is.
|
|
|
|
*/
|
1999-05-18 22:05:40 +00:00
|
|
|
REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
|
|
|
|
(name2->attributes & DNS_NAMEATTR_ABSOLUTE));
|
1998-12-04 02:27:01 +00:00
|
|
|
|
2016-02-01 08:59:49 +05:30
|
|
|
if (ISC_UNLIKELY(name1 == name2)) {
|
2013-06-18 18:14:28 -07:00
|
|
|
*orderp = 0;
|
2014-09-27 11:41:44 +10:00
|
|
|
*nlabelsp = name1->labels;
|
2013-06-18 18:14:28 -07:00
|
|
|
return (dns_namereln_equal);
|
|
|
|
}
|
|
|
|
|
1999-01-09 00:33:15 +00:00
|
|
|
SETUP_OFFSETS(name1, offsets1, odata1);
|
|
|
|
SETUP_OFFSETS(name2, offsets2, odata2);
|
|
|
|
|
1999-02-16 08:18:44 +00:00
|
|
|
nlabels = 0;
|
1998-12-04 02:27:01 +00:00
|
|
|
l1 = name1->labels;
|
|
|
|
l2 = name2->labels;
|
2012-10-06 14:20:45 +10:00
|
|
|
if (l2 > l1) {
|
1998-12-04 02:27:01 +00:00
|
|
|
l = l1;
|
2012-10-06 14:20:45 +10:00
|
|
|
ldiff = 0 - (l2 - l1);
|
|
|
|
} else {
|
1998-12-04 02:27:01 +00:00
|
|
|
l = l2;
|
2012-10-06 14:20:45 +10:00
|
|
|
ldiff = l1 - l2;
|
|
|
|
}
|
1998-12-04 02:27:01 +00:00
|
|
|
|
2015-12-09 19:07:20 +05:30
|
|
|
offsets1 += l1;
|
|
|
|
offsets2 += l2;
|
|
|
|
|
2016-02-01 08:59:49 +05:30
|
|
|
while (ISC_LIKELY(l > 0)) {
|
1998-12-04 02:27:01 +00:00
|
|
|
l--;
|
2015-12-09 19:07:20 +05:30
|
|
|
offsets1--;
|
|
|
|
offsets2--;
|
|
|
|
label1 = &name1->ndata[*offsets1];
|
|
|
|
label2 = &name2->ndata[*offsets2];
|
1998-12-04 02:27:01 +00:00
|
|
|
count1 = *label1++;
|
|
|
|
count2 = *label2++;
|
|
|
|
|
2002-08-27 04:53:43 +00:00
|
|
|
/*
|
|
|
|
* We dropped bitstring labels, and we don't support any
|
|
|
|
* other extended label types.
|
|
|
|
*/
|
|
|
|
INSIST(count1 <= 63 && count2 <= 63);
|
|
|
|
|
|
|
|
cdiff = (int)count1 - (int)count2;
|
|
|
|
if (cdiff < 0)
|
|
|
|
count = count1;
|
|
|
|
else
|
|
|
|
count = count2;
|
|
|
|
|
2015-12-09 08:54:04 -08:00
|
|
|
/* Loop unrolled for performance */
|
2016-02-01 08:59:49 +05:30
|
|
|
while (ISC_LIKELY(count > 3)) {
|
2015-12-09 19:07:20 +05:30
|
|
|
chdiff = (int)maptolower[label1[0]] -
|
|
|
|
(int)maptolower[label2[0]];
|
|
|
|
if (chdiff != 0) {
|
|
|
|
*orderp = chdiff;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
chdiff = (int)maptolower[label1[1]] -
|
|
|
|
(int)maptolower[label2[1]];
|
|
|
|
if (chdiff != 0) {
|
|
|
|
*orderp = chdiff;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
chdiff = (int)maptolower[label1[2]] -
|
|
|
|
(int)maptolower[label2[2]];
|
|
|
|
if (chdiff != 0) {
|
|
|
|
*orderp = chdiff;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
chdiff = (int)maptolower[label1[3]] -
|
|
|
|
(int)maptolower[label2[3]];
|
|
|
|
if (chdiff != 0) {
|
|
|
|
*orderp = chdiff;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
count -= 4;
|
|
|
|
label1 += 4;
|
|
|
|
label2 += 4;
|
|
|
|
}
|
2016-02-01 08:59:49 +05:30
|
|
|
while (ISC_LIKELY(count-- > 0)) {
|
2015-12-09 08:54:04 -08:00
|
|
|
chdiff = (int)maptolower[*label1++] -
|
|
|
|
(int)maptolower[*label2++];
|
2002-08-27 04:53:43 +00:00
|
|
|
if (chdiff != 0) {
|
|
|
|
*orderp = chdiff;
|
1999-02-16 08:18:44 +00:00
|
|
|
goto done;
|
|
|
|
}
|
2002-08-27 04:53:43 +00:00
|
|
|
}
|
|
|
|
if (cdiff != 0) {
|
|
|
|
*orderp = cdiff;
|
1999-02-16 08:18:44 +00:00
|
|
|
goto done;
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
2002-08-27 04:53:43 +00:00
|
|
|
nlabels++;
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
|
1999-02-16 08:18:44 +00:00
|
|
|
*orderp = ldiff;
|
|
|
|
if (ldiff < 0)
|
|
|
|
namereln = dns_namereln_contains;
|
|
|
|
else if (ldiff > 0)
|
|
|
|
namereln = dns_namereln_subdomain;
|
|
|
|
else
|
|
|
|
namereln = dns_namereln_equal;
|
2015-12-09 19:07:20 +05:30
|
|
|
*nlabelsp = nlabels;
|
|
|
|
return (namereln);
|
1999-02-16 08:18:44 +00:00
|
|
|
|
|
|
|
done:
|
|
|
|
*nlabelsp = nlabels;
|
2015-12-09 19:07:20 +05:30
|
|
|
if (nlabels > 0)
|
1999-02-16 08:18:44 +00:00
|
|
|
namereln = dns_namereln_commonancestor;
|
|
|
|
|
|
|
|
return (namereln);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2000-06-01 18:26:56 +00:00
|
|
|
dns_name_compare(const dns_name_t *name1, const dns_name_t *name2) {
|
1999-02-16 08:18:44 +00:00
|
|
|
int order;
|
2003-10-25 00:31:12 +00:00
|
|
|
unsigned int nlabels;
|
1999-02-16 08:18:44 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine the relative ordering under the DNSSEC order relation of
|
|
|
|
* 'name1' and 'name2'.
|
|
|
|
*
|
|
|
|
* Note: It makes no sense for one of the names to be relative and the
|
|
|
|
* other absolute. If both names are relative, then to be meaningfully
|
|
|
|
* compared the caller must ensure that they are both relative to the
|
|
|
|
* same domain.
|
|
|
|
*/
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2003-10-25 00:31:12 +00:00
|
|
|
(void)dns_name_fullcompare(name1, name2, &order, &nlabels);
|
1999-02-16 08:18:44 +00:00
|
|
|
|
|
|
|
return (order);
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2000-06-01 18:26:56 +00:00
|
|
|
dns_name_equal(const dns_name_t *name1, const dns_name_t *name2) {
|
1999-05-18 22:05:40 +00:00
|
|
|
unsigned int l, count;
|
|
|
|
unsigned char c;
|
|
|
|
unsigned char *label1, *label2;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Are 'name1' and 'name2' equal?
|
|
|
|
*
|
|
|
|
* Note: It makes no sense for one of the names to be relative and the
|
|
|
|
* other absolute. If both names are relative, then to be meaningfully
|
|
|
|
* compared the caller must ensure that they are both relative to the
|
|
|
|
* same domain.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name1));
|
|
|
|
REQUIRE(VALID_NAME(name2));
|
|
|
|
/*
|
|
|
|
* Either name1 is absolute and name2 is absolute, or neither is.
|
|
|
|
*/
|
|
|
|
REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
|
|
|
|
(name2->attributes & DNS_NAMEATTR_ABSOLUTE));
|
|
|
|
|
2016-02-01 08:59:49 +05:30
|
|
|
if (ISC_UNLIKELY(name1 == name2))
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
2013-06-18 18:14:28 -07:00
|
|
|
|
1999-05-18 22:05:40 +00:00
|
|
|
if (name1->length != name2->length)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
1999-05-18 22:05:40 +00:00
|
|
|
|
|
|
|
l = name1->labels;
|
|
|
|
|
|
|
|
if (l != name2->labels)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
1999-05-18 22:05:40 +00:00
|
|
|
|
|
|
|
label1 = name1->ndata;
|
|
|
|
label2 = name2->ndata;
|
2016-02-01 08:59:49 +05:30
|
|
|
while (ISC_LIKELY(l-- > 0)) {
|
1999-05-18 22:05:40 +00:00
|
|
|
count = *label1++;
|
|
|
|
if (count != *label2++)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2002-08-27 04:53:43 +00:00
|
|
|
|
|
|
|
INSIST(count <= 63); /* no bitstring support */
|
|
|
|
|
2015-12-09 08:54:04 -08:00
|
|
|
/* Loop unrolled for performance */
|
2016-02-01 08:59:49 +05:30
|
|
|
while (ISC_LIKELY(count > 3)) {
|
2015-12-09 23:45:23 +00:00
|
|
|
c = maptolower[label1[0]];
|
2015-12-09 19:07:20 +05:30
|
|
|
if (c != maptolower[label2[0]])
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2015-12-09 23:45:23 +00:00
|
|
|
c = maptolower[label1[1]];
|
2015-12-09 19:07:20 +05:30
|
|
|
if (c != maptolower[label2[1]])
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2015-12-09 23:45:23 +00:00
|
|
|
c = maptolower[label1[2]];
|
2015-12-09 19:07:20 +05:30
|
|
|
if (c != maptolower[label2[2]])
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2015-12-09 23:45:23 +00:00
|
|
|
c = maptolower[label1[3]];
|
2015-12-09 19:07:20 +05:30
|
|
|
if (c != maptolower[label2[3]])
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2015-12-09 19:07:20 +05:30
|
|
|
count -= 4;
|
|
|
|
label1 += 4;
|
|
|
|
label2 += 4;
|
|
|
|
}
|
2016-02-01 08:59:49 +05:30
|
|
|
while (ISC_LIKELY(count-- > 0)) {
|
2002-08-27 04:53:43 +00:00
|
|
|
c = maptolower[*label1++];
|
|
|
|
if (c != maptolower[*label2++])
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
1999-05-18 22:05:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
1999-05-18 22:05:40 +00:00
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2005-03-04 02:56:21 +00:00
|
|
|
dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) {
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Are 'name1' and 'name2' equal?
|
|
|
|
*
|
|
|
|
* Note: It makes no sense for one of the names to be relative and the
|
|
|
|
* other absolute. If both names are relative, then to be meaningfully
|
|
|
|
* compared the caller must ensure that they are both relative to the
|
|
|
|
* same domain.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name1));
|
|
|
|
REQUIRE(VALID_NAME(name2));
|
|
|
|
/*
|
|
|
|
* Either name1 is absolute and name2 is absolute, or neither is.
|
|
|
|
*/
|
|
|
|
REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
|
|
|
|
(name2->attributes & DNS_NAMEATTR_ABSOLUTE));
|
|
|
|
|
|
|
|
if (name1->length != name2->length)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2005-03-04 02:56:21 +00:00
|
|
|
|
|
|
|
if (memcmp(name1->ndata, name2->ndata, name1->length) != 0)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2005-03-04 02:56:21 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
2005-03-04 02:56:21 +00:00
|
|
|
}
|
|
|
|
|
1999-02-15 05:44:22 +00:00
|
|
|
int
|
2000-06-01 18:26:56 +00:00
|
|
|
dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) {
|
1999-02-15 05:44:22 +00:00
|
|
|
unsigned int l1, l2, l, count1, count2, count;
|
|
|
|
unsigned char c1, c2;
|
|
|
|
unsigned char *label1, *label2;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Compare two absolute names as rdata.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name1));
|
|
|
|
REQUIRE(name1->labels > 0);
|
|
|
|
REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
|
|
|
|
REQUIRE(VALID_NAME(name2));
|
|
|
|
REQUIRE(name2->labels > 0);
|
|
|
|
REQUIRE((name2->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
|
|
|
|
|
|
|
|
l1 = name1->labels;
|
|
|
|
l2 = name2->labels;
|
|
|
|
|
|
|
|
l = (l1 < l2) ? l1 : l2;
|
|
|
|
|
|
|
|
label1 = name1->ndata;
|
|
|
|
label2 = name2->ndata;
|
|
|
|
while (l > 0) {
|
|
|
|
l--;
|
|
|
|
count1 = *label1++;
|
|
|
|
count2 = *label2++;
|
2002-08-27 04:53:43 +00:00
|
|
|
|
|
|
|
/* no bitstring support */
|
|
|
|
INSIST(count1 <= 63 && count2 <= 63);
|
|
|
|
|
|
|
|
if (count1 != count2)
|
|
|
|
return ((count1 < count2) ? -1 : 1);
|
|
|
|
count = count1;
|
|
|
|
while (count > 0) {
|
|
|
|
count--;
|
|
|
|
c1 = maptolower[*label1++];
|
|
|
|
c2 = maptolower[*label2++];
|
|
|
|
if (c1 < c2)
|
|
|
|
return (-1);
|
|
|
|
else if (c1 > c2)
|
|
|
|
return (1);
|
1999-02-15 05:44:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-03-20 19:33:20 +00:00
|
|
|
/*
|
|
|
|
* If one name had more labels than the other, their common
|
|
|
|
* prefix must have been different because the shorter name
|
|
|
|
* ended with the root label and the longer one can't have
|
|
|
|
* a root label in the middle of it. Therefore, if we get
|
|
|
|
* to this point, the lengths must be equal.
|
|
|
|
*/
|
1999-02-15 05:44:22 +00:00
|
|
|
INSIST(l1 == l2);
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2000-06-01 18:26:56 +00:00
|
|
|
dns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2) {
|
1999-02-16 08:18:44 +00:00
|
|
|
int order;
|
2003-10-25 00:31:12 +00:00
|
|
|
unsigned int nlabels;
|
1999-02-16 08:18:44 +00:00
|
|
|
dns_namereln_t namereln;
|
1998-12-04 02:27:01 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Is 'name1' a subdomain of 'name2'?
|
|
|
|
*
|
|
|
|
* Note: It makes no sense for one of the names to be relative and the
|
|
|
|
* other absolute. If both names are relative, then to be meaningfully
|
|
|
|
* compared the caller must ensure that they are both relative to the
|
|
|
|
* same domain.
|
|
|
|
*/
|
|
|
|
|
2003-10-25 00:31:12 +00:00
|
|
|
namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
|
1999-02-16 08:18:44 +00:00
|
|
|
if (namereln == dns_namereln_subdomain ||
|
|
|
|
namereln == dns_namereln_equal)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
1998-12-04 02:27:01 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2000-06-01 18:26:56 +00:00
|
|
|
dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) {
|
2000-02-02 20:44:22 +00:00
|
|
|
int order;
|
2003-10-25 00:31:12 +00:00
|
|
|
unsigned int nlabels, labels;
|
2000-02-02 20:11:55 +00:00
|
|
|
dns_name_t tname;
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
2000-03-29 18:49:36 +00:00
|
|
|
REQUIRE(name->labels > 0);
|
2000-02-02 20:11:55 +00:00
|
|
|
REQUIRE(VALID_NAME(wname));
|
2000-03-29 18:49:36 +00:00
|
|
|
labels = wname->labels;
|
|
|
|
REQUIRE(labels > 0);
|
2000-02-02 20:11:55 +00:00
|
|
|
REQUIRE(dns_name_iswildcard(wname));
|
|
|
|
|
2012-12-01 21:32:31 +11:00
|
|
|
#if defined(__clang__) && \
|
2012-12-03 07:58:01 +11:00
|
|
|
( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
|
2012-12-01 21:32:31 +11:00
|
|
|
memset(&tname, 0, sizeof(tname));
|
|
|
|
#endif
|
2001-01-03 00:05:15 +00:00
|
|
|
DNS_NAME_INIT(&tname, NULL);
|
2000-02-02 20:11:55 +00:00
|
|
|
dns_name_getlabelsequence(wname, 1, labels - 1, &tname);
|
2003-10-25 00:31:12 +00:00
|
|
|
if (dns_name_fullcompare(name, &tname, &order, &nlabels) ==
|
2000-02-02 20:44:22 +00:00
|
|
|
dns_namereln_subdomain)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
|
|
|
return (false);
|
2000-02-02 20:11:55 +00:00
|
|
|
}
|
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
unsigned int
|
2000-06-01 18:26:56 +00:00
|
|
|
dns_name_countlabels(const dns_name_t *name) {
|
1998-12-04 02:27:01 +00:00
|
|
|
/*
|
|
|
|
* How many labels does 'name' have?
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
|
|
|
|
ENSURE(name->labels <= 128);
|
|
|
|
|
|
|
|
return (name->labels);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2000-06-01 18:26:56 +00:00
|
|
|
dns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label) {
|
1999-01-09 00:33:15 +00:00
|
|
|
unsigned char *offsets;
|
|
|
|
dns_offsets_t odata;
|
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
/*
|
|
|
|
* Make 'label' refer to the 'n'th least significant label of 'name'.
|
|
|
|
*/
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
REQUIRE(VALID_NAME(name));
|
1999-01-06 05:41:20 +00:00
|
|
|
REQUIRE(name->labels > 0);
|
1998-12-04 02:27:01 +00:00
|
|
|
REQUIRE(n < name->labels);
|
|
|
|
REQUIRE(label != NULL);
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-01-09 00:33:15 +00:00
|
|
|
SETUP_OFFSETS(name, offsets, odata);
|
|
|
|
|
|
|
|
label->base = &name->ndata[offsets[n]];
|
1998-12-04 02:27:01 +00:00
|
|
|
if (n == name->labels - 1)
|
1999-01-09 00:33:15 +00:00
|
|
|
label->length = name->length - offsets[n];
|
1998-12-04 02:27:01 +00:00
|
|
|
else
|
1999-01-09 00:33:15 +00:00
|
|
|
label->length = offsets[n + 1] - offsets[n];
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2000-06-01 18:26:56 +00:00
|
|
|
dns_name_getlabelsequence(const dns_name_t *source,
|
1998-12-04 02:27:01 +00:00
|
|
|
unsigned int first, unsigned int n,
|
1998-12-13 23:45:21 +00:00
|
|
|
dns_name_t *target)
|
1998-12-04 02:27:01 +00:00
|
|
|
{
|
2017-04-22 08:25:10 +05:30
|
|
|
unsigned char *p, l;
|
2000-08-22 00:46:54 +00:00
|
|
|
unsigned int firstoffset, endoffset;
|
2017-04-22 08:25:10 +05:30
|
|
|
unsigned int i;
|
1999-01-09 00:33:15 +00:00
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
/*
|
|
|
|
* Make 'target' refer to the 'n' labels including and following
|
|
|
|
* 'first' in 'source'.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(source));
|
1999-04-09 01:27:54 +00:00
|
|
|
REQUIRE(VALID_NAME(target));
|
2000-08-22 00:46:54 +00:00
|
|
|
REQUIRE(first <= source->labels);
|
2010-05-12 05:40:32 +00:00
|
|
|
REQUIRE(n <= source->labels - first); /* note first+n could overflow */
|
1999-08-19 23:26:16 +00:00
|
|
|
REQUIRE(BINDABLE(target));
|
1998-12-04 02:27:01 +00:00
|
|
|
|
2017-04-22 08:25:10 +05:30
|
|
|
p = source->ndata;
|
|
|
|
if (ISC_UNLIKELY(first == source->labels)) {
|
2000-08-22 00:46:54 +00:00
|
|
|
firstoffset = source->length;
|
2017-04-22 08:25:10 +05:30
|
|
|
} else {
|
|
|
|
for (i = 0; i < first; i++) {
|
|
|
|
l = *p;
|
|
|
|
p += l + 1;
|
|
|
|
}
|
2017-09-07 12:57:55 +10:00
|
|
|
firstoffset = (unsigned int)(p - source->ndata);
|
2017-04-22 08:25:10 +05:30
|
|
|
}
|
2000-08-22 00:46:54 +00:00
|
|
|
|
2017-04-22 08:25:10 +05:30
|
|
|
if (ISC_LIKELY(first + n == source->labels))
|
2000-08-22 00:46:54 +00:00
|
|
|
endoffset = source->length;
|
2017-04-22 08:25:10 +05:30
|
|
|
else {
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
l = *p;
|
|
|
|
p += l + 1;
|
|
|
|
}
|
2017-09-07 12:57:55 +10:00
|
|
|
endoffset = (unsigned int)(p - source->ndata);
|
2017-04-22 08:25:10 +05:30
|
|
|
}
|
2000-08-22 00:46:54 +00:00
|
|
|
|
|
|
|
target->ndata = &source->ndata[firstoffset];
|
|
|
|
target->length = endoffset - firstoffset;
|
2008-04-01 23:47:10 +00:00
|
|
|
|
2000-08-22 00:46:54 +00:00
|
|
|
if (first + n == source->labels && n > 0 &&
|
|
|
|
(source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
|
|
|
|
target->attributes |= DNS_NAMEATTR_ABSOLUTE;
|
|
|
|
else
|
1999-02-06 01:26:00 +00:00
|
|
|
target->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
|
2000-08-22 00:46:54 +00:00
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
target->labels = n;
|
|
|
|
|
2000-04-26 23:22:53 +00:00
|
|
|
/*
|
|
|
|
* If source and target are the same, and we're making target
|
|
|
|
* a prefix of source, the offsets table is correct already
|
|
|
|
* so we don't need to call set_offsets().
|
|
|
|
*/
|
|
|
|
if (target->offsets != NULL &&
|
|
|
|
(target != source || first != 0))
|
2000-06-01 18:26:56 +00:00
|
|
|
set_offsets(target, target->offsets, NULL);
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
|
1999-04-24 02:03:07 +00:00
|
|
|
void
|
2006-02-28 02:39:52 +00:00
|
|
|
dns_name_clone(const dns_name_t *source, dns_name_t *target) {
|
1999-04-24 02:03:07 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Make 'target' refer to the same name as 'source'.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(source));
|
|
|
|
REQUIRE(VALID_NAME(target));
|
1999-08-19 23:26:16 +00:00
|
|
|
REQUIRE(BINDABLE(target));
|
1999-04-24 02:03:07 +00:00
|
|
|
|
|
|
|
target->ndata = source->ndata;
|
|
|
|
target->length = source->length;
|
|
|
|
target->labels = source->labels;
|
1999-10-12 20:38:30 +00:00
|
|
|
target->attributes = source->attributes &
|
2000-06-01 18:26:56 +00:00
|
|
|
(unsigned int)~(DNS_NAMEATTR_READONLY | DNS_NAMEATTR_DYNAMIC |
|
|
|
|
DNS_NAMEATTR_DYNOFFSETS);
|
1999-04-24 02:03:07 +00:00
|
|
|
if (target->offsets != NULL && source->labels > 0) {
|
|
|
|
if (source->offsets != NULL)
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(target->offsets, source->offsets,
|
|
|
|
source->labels);
|
1999-04-24 02:03:07 +00:00
|
|
|
else
|
2000-06-01 18:26:56 +00:00
|
|
|
set_offsets(target, target->offsets, NULL);
|
1999-04-24 02:03:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
void
|
2002-03-14 00:36:07 +00:00
|
|
|
dns_name_fromregion(dns_name_t *name, const isc_region_t *r) {
|
1999-01-09 00:33:15 +00:00
|
|
|
unsigned char *offsets;
|
|
|
|
dns_offsets_t odata;
|
1999-04-28 03:03:56 +00:00
|
|
|
unsigned int len;
|
|
|
|
isc_region_t r2;
|
1999-01-09 00:33:15 +00:00
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
/*
|
|
|
|
* Make 'name' refer to region 'r'.
|
|
|
|
*/
|
|
|
|
|
1999-01-09 00:33:15 +00:00
|
|
|
REQUIRE(VALID_NAME(name));
|
1998-12-04 02:27:01 +00:00
|
|
|
REQUIRE(r != NULL);
|
1999-08-19 23:26:16 +00:00
|
|
|
REQUIRE(BINDABLE(name));
|
1998-12-04 02:27:01 +00:00
|
|
|
|
1999-01-09 00:33:15 +00:00
|
|
|
INIT_OFFSETS(name, offsets, odata);
|
|
|
|
|
1999-04-28 03:03:56 +00:00
|
|
|
if (name->buffer != NULL) {
|
|
|
|
isc_buffer_clear(name->buffer);
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_availableregion(name->buffer, &r2);
|
1999-04-28 03:03:56 +00:00
|
|
|
len = (r->length < r2.length) ? r->length : r2.length;
|
2000-10-11 17:44:18 +00:00
|
|
|
if (len > DNS_NAME_MAXWIRE)
|
|
|
|
len = DNS_NAME_MAXWIRE;
|
2017-12-06 21:00:14 +11:00
|
|
|
if (len != 0)
|
|
|
|
memmove(r2.base, r->base, len);
|
1999-04-28 03:03:56 +00:00
|
|
|
name->ndata = r2.base;
|
|
|
|
name->length = len;
|
|
|
|
} else {
|
|
|
|
name->ndata = r->base;
|
2008-04-01 23:47:10 +00:00
|
|
|
name->length = (r->length <= DNS_NAME_MAXWIRE) ?
|
2000-10-11 17:44:18 +00:00
|
|
|
r->length : DNS_NAME_MAXWIRE;
|
1999-04-28 03:03:56 +00:00
|
|
|
}
|
1998-12-04 02:27:01 +00:00
|
|
|
|
|
|
|
if (r->length > 0)
|
2000-06-01 18:26:56 +00:00
|
|
|
set_offsets(name, offsets, name);
|
1999-02-23 02:25:41 +00:00
|
|
|
else {
|
1998-12-04 02:27:01 +00:00
|
|
|
name->labels = 0;
|
1999-02-23 02:25:41 +00:00
|
|
|
name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
|
|
|
|
}
|
1999-04-28 03:03:56 +00:00
|
|
|
|
|
|
|
if (name->buffer != NULL)
|
|
|
|
isc_buffer_add(name->buffer, name->length);
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_name_toregion(const dns_name_t *name, isc_region_t *r) {
|
1998-12-04 02:27:01 +00:00
|
|
|
/*
|
|
|
|
* Make 'r' refer to 'name'.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
REQUIRE(r != NULL);
|
|
|
|
|
2001-01-04 20:00:57 +00:00
|
|
|
DNS_NAME_TOREGION(name, r);
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
1999-01-06 05:41:20 +00:00
|
|
|
dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
|
2011-01-13 01:59:28 +00:00
|
|
|
const dns_name_t *origin, unsigned int options,
|
1999-01-06 05:41:20 +00:00
|
|
|
isc_buffer_t *target)
|
1998-12-04 02:27:01 +00:00
|
|
|
{
|
2011-03-11 06:11:27 +00:00
|
|
|
unsigned char *ndata, *label = NULL;
|
1998-12-04 02:27:01 +00:00
|
|
|
char *tdata;
|
|
|
|
char c;
|
2005-10-14 01:18:47 +00:00
|
|
|
ft_state state;
|
2011-03-11 06:11:27 +00:00
|
|
|
unsigned int value = 0, count = 0;
|
|
|
|
unsigned int n1 = 0, n2 = 0;
|
|
|
|
unsigned int tlen, nrem, nused, digits = 0, labels, tused;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool done;
|
1999-01-09 00:33:15 +00:00
|
|
|
unsigned char *offsets;
|
|
|
|
dns_offsets_t odata;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool downcase;
|
1998-12-04 02:27:01 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Convert the textual representation of a DNS name at source
|
|
|
|
* into uncompressed wire form stored in target.
|
|
|
|
*
|
|
|
|
* Notes:
|
|
|
|
* Relative domain names will have 'origin' appended to them
|
|
|
|
* unless 'origin' is NULL, in which case relative domain names
|
|
|
|
* will remain relative.
|
|
|
|
*/
|
|
|
|
|
1999-01-09 00:33:15 +00:00
|
|
|
REQUIRE(VALID_NAME(name));
|
2000-05-25 23:57:25 +00:00
|
|
|
REQUIRE(ISC_BUFFER_VALID(source));
|
|
|
|
REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
|
2002-05-29 00:27:53 +00:00
|
|
|
(target == NULL && ISC_BUFFER_VALID(name->buffer)));
|
2008-04-01 23:47:10 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
downcase = (options & DNS_NAME_DOWNCASE);
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
|
1999-03-08 18:55:28 +00:00
|
|
|
if (target == NULL && name->buffer != NULL) {
|
|
|
|
target = name->buffer;
|
|
|
|
isc_buffer_clear(target);
|
|
|
|
}
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
|
1999-08-19 23:26:16 +00:00
|
|
|
REQUIRE(BINDABLE(name));
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-01-09 00:33:15 +00:00
|
|
|
INIT_OFFSETS(name, offsets, odata);
|
1999-02-06 01:26:00 +00:00
|
|
|
offsets[0] = 0;
|
1999-01-09 00:33:15 +00:00
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
/*
|
1999-08-12 20:26:45 +00:00
|
|
|
* Make 'name' empty in case of failure.
|
1998-12-04 02:27:01 +00:00
|
|
|
*/
|
1999-08-12 20:26:45 +00:00
|
|
|
MAKE_EMPTY(name);
|
1998-12-04 02:27:01 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Set up the state machine.
|
|
|
|
*/
|
1999-01-06 05:41:20 +00:00
|
|
|
tdata = (char *)source->base + source->current;
|
2000-05-25 23:57:25 +00:00
|
|
|
tlen = isc_buffer_remaininglength(source);
|
1999-01-06 05:41:20 +00:00
|
|
|
tused = 0;
|
2000-05-25 23:57:25 +00:00
|
|
|
ndata = isc_buffer_used(target);
|
|
|
|
nrem = isc_buffer_availablelength(target);
|
1998-12-04 02:27:01 +00:00
|
|
|
if (nrem > 255)
|
|
|
|
nrem = 255;
|
1999-01-13 19:17:22 +00:00
|
|
|
nused = 0;
|
1998-12-04 02:27:01 +00:00
|
|
|
labels = 0;
|
2018-04-17 08:29:14 -07:00
|
|
|
done = false;
|
1999-01-06 05:41:20 +00:00
|
|
|
state = ft_init;
|
1998-12-04 02:27:01 +00:00
|
|
|
|
|
|
|
while (nrem > 0 && tlen > 0 && !done) {
|
|
|
|
c = *tdata++;
|
|
|
|
tlen--;
|
1999-01-06 05:41:20 +00:00
|
|
|
tused++;
|
1998-12-04 02:27:01 +00:00
|
|
|
|
|
|
|
switch (state) {
|
1999-01-06 05:41:20 +00:00
|
|
|
case ft_init:
|
1998-12-04 02:27:01 +00:00
|
|
|
/*
|
|
|
|
* Is this the root name?
|
|
|
|
*/
|
|
|
|
if (c == '.') {
|
|
|
|
if (tlen != 0)
|
|
|
|
return (DNS_R_EMPTYLABEL);
|
|
|
|
labels++;
|
|
|
|
*ndata++ = 0;
|
|
|
|
nrem--;
|
1999-01-13 19:17:22 +00:00
|
|
|
nused++;
|
2018-04-17 08:29:14 -07:00
|
|
|
done = true;
|
1998-12-04 02:27:01 +00:00
|
|
|
break;
|
|
|
|
}
|
1999-02-06 01:26:00 +00:00
|
|
|
if (c == '@' && tlen == 0) {
|
|
|
|
state = ft_at;
|
|
|
|
break;
|
1999-01-27 23:39:40 +00:00
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
/* FALLTHROUGH */
|
1999-01-06 05:41:20 +00:00
|
|
|
case ft_start:
|
1998-12-04 02:27:01 +00:00
|
|
|
label = ndata;
|
|
|
|
ndata++;
|
|
|
|
nrem--;
|
1999-01-13 19:17:22 +00:00
|
|
|
nused++;
|
1998-12-04 02:27:01 +00:00
|
|
|
count = 0;
|
|
|
|
if (c == '\\') {
|
1999-01-06 05:41:20 +00:00
|
|
|
state = ft_initialescape;
|
1998-12-04 02:27:01 +00:00
|
|
|
break;
|
|
|
|
}
|
1999-01-06 05:41:20 +00:00
|
|
|
state = ft_ordinary;
|
2002-08-02 00:25:15 +00:00
|
|
|
if (nrem == 0)
|
|
|
|
return (ISC_R_NOSPACE);
|
1998-12-04 02:27:01 +00:00
|
|
|
/* FALLTHROUGH */
|
1999-01-06 05:41:20 +00:00
|
|
|
case ft_ordinary:
|
1998-12-04 02:27:01 +00:00
|
|
|
if (c == '.') {
|
|
|
|
if (count == 0)
|
|
|
|
return (DNS_R_EMPTYLABEL);
|
|
|
|
*label = count;
|
|
|
|
labels++;
|
1999-02-06 01:26:00 +00:00
|
|
|
INSIST(labels <= 127);
|
|
|
|
offsets[labels] = nused;
|
1998-12-04 02:27:01 +00:00
|
|
|
if (tlen == 0) {
|
|
|
|
labels++;
|
|
|
|
*ndata++ = 0;
|
|
|
|
nrem--;
|
1999-01-13 19:17:22 +00:00
|
|
|
nused++;
|
2018-04-17 08:29:14 -07:00
|
|
|
done = true;
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
1999-01-06 05:41:20 +00:00
|
|
|
state = ft_start;
|
1998-12-04 02:27:01 +00:00
|
|
|
} else if (c == '\\') {
|
1999-01-06 05:41:20 +00:00
|
|
|
state = ft_escape;
|
1998-12-04 02:27:01 +00:00
|
|
|
} else {
|
|
|
|
if (count >= 63)
|
|
|
|
return (DNS_R_LABELTOOLONG);
|
|
|
|
count++;
|
1998-12-05 01:42:30 +00:00
|
|
|
CONVERTTOASCII(c);
|
1998-12-04 02:27:01 +00:00
|
|
|
if (downcase)
|
2014-04-11 13:25:49 +02:00
|
|
|
c = maptolower[c & 0xff];
|
1998-12-04 02:27:01 +00:00
|
|
|
*ndata++ = c;
|
|
|
|
nrem--;
|
1999-01-13 19:17:22 +00:00
|
|
|
nused++;
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
break;
|
1999-01-06 05:41:20 +00:00
|
|
|
case ft_initialescape:
|
1998-12-04 02:27:01 +00:00
|
|
|
if (c == '[') {
|
2002-08-27 04:53:43 +00:00
|
|
|
/*
|
|
|
|
* This looks like a bitstring label, which
|
|
|
|
* was deprecated. Intentionally drop it.
|
|
|
|
*/
|
|
|
|
return (DNS_R_BADLABELTYPE);
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
1999-01-06 05:41:20 +00:00
|
|
|
state = ft_escape;
|
2011-03-11 06:11:27 +00:00
|
|
|
POST(state);
|
1998-12-04 02:27:01 +00:00
|
|
|
/* FALLTHROUGH */
|
1999-01-06 05:41:20 +00:00
|
|
|
case ft_escape:
|
1999-10-29 02:38:37 +00:00
|
|
|
if (!isdigit(c & 0xff)) {
|
1998-12-04 02:27:01 +00:00
|
|
|
if (count >= 63)
|
|
|
|
return (DNS_R_LABELTOOLONG);
|
|
|
|
count++;
|
1998-12-05 01:42:30 +00:00
|
|
|
CONVERTTOASCII(c);
|
1998-12-04 02:27:01 +00:00
|
|
|
if (downcase)
|
2014-04-11 13:25:49 +02:00
|
|
|
c = maptolower[c & 0xff];
|
1998-12-04 02:27:01 +00:00
|
|
|
*ndata++ = c;
|
|
|
|
nrem--;
|
1999-01-13 19:17:22 +00:00
|
|
|
nused++;
|
1999-01-06 05:41:20 +00:00
|
|
|
state = ft_ordinary;
|
1998-12-04 02:27:01 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
digits = 0;
|
|
|
|
value = 0;
|
1999-01-06 05:41:20 +00:00
|
|
|
state = ft_escdecimal;
|
1998-12-04 02:27:01 +00:00
|
|
|
/* FALLTHROUGH */
|
1999-01-06 05:41:20 +00:00
|
|
|
case ft_escdecimal:
|
1999-10-29 02:38:37 +00:00
|
|
|
if (!isdigit(c & 0xff))
|
1998-12-04 02:27:01 +00:00
|
|
|
return (DNS_R_BADESCAPE);
|
|
|
|
value *= 10;
|
2014-04-11 13:25:49 +02:00
|
|
|
value += digitvalue[c & 0xff];
|
1998-12-04 02:27:01 +00:00
|
|
|
digits++;
|
|
|
|
if (digits == 3) {
|
|
|
|
if (value > 255)
|
|
|
|
return (DNS_R_BADESCAPE);
|
|
|
|
if (count >= 63)
|
|
|
|
return (DNS_R_LABELTOOLONG);
|
|
|
|
count++;
|
|
|
|
if (downcase)
|
|
|
|
value = maptolower[value];
|
|
|
|
*ndata++ = value;
|
|
|
|
nrem--;
|
1999-01-13 19:17:22 +00:00
|
|
|
nused++;
|
1999-01-06 05:41:20 +00:00
|
|
|
state = ft_ordinary;
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
1999-01-06 05:41:20 +00:00
|
|
|
FATAL_ERROR(__FILE__, __LINE__,
|
|
|
|
"Unexpected state %d", state);
|
|
|
|
/* Does not return. */
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
}
|
1999-01-06 05:41:20 +00:00
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
if (!done) {
|
|
|
|
if (nrem == 0)
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
1999-01-06 05:41:20 +00:00
|
|
|
INSIST(tlen == 0);
|
2002-08-27 04:53:43 +00:00
|
|
|
if (state != ft_ordinary && state != ft_at)
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_UNEXPECTEDEND);
|
1999-01-06 05:41:20 +00:00
|
|
|
if (state == ft_ordinary) {
|
|
|
|
INSIST(count != 0);
|
1998-12-04 02:27:01 +00:00
|
|
|
*label = count;
|
|
|
|
labels++;
|
1999-02-06 01:26:00 +00:00
|
|
|
INSIST(labels <= 127);
|
|
|
|
offsets[labels] = nused;
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
1999-01-06 05:41:20 +00:00
|
|
|
if (origin != NULL) {
|
1998-12-04 02:27:01 +00:00
|
|
|
if (nrem < origin->length)
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
1998-12-04 02:27:01 +00:00
|
|
|
label = origin->ndata;
|
|
|
|
n1 = origin->length;
|
|
|
|
nrem -= n1;
|
2011-03-11 06:11:27 +00:00
|
|
|
POST(nrem);
|
1998-12-04 02:27:01 +00:00
|
|
|
while (n1 > 0) {
|
1999-02-06 01:26:00 +00:00
|
|
|
n2 = *label++;
|
2002-08-27 04:53:43 +00:00
|
|
|
INSIST(n2 <= 63); /* no bitstring support */
|
|
|
|
*ndata++ = n2;
|
|
|
|
n1 -= n2 + 1;
|
|
|
|
nused += n2 + 1;
|
|
|
|
while (n2 > 0) {
|
|
|
|
c = *label++;
|
|
|
|
if (downcase)
|
2014-04-11 13:25:49 +02:00
|
|
|
c = maptolower[c & 0xff];
|
2002-08-27 04:53:43 +00:00
|
|
|
*ndata++ = c;
|
|
|
|
n2--;
|
1999-02-06 01:26:00 +00:00
|
|
|
}
|
|
|
|
labels++;
|
|
|
|
if (n1 > 0) {
|
|
|
|
INSIST(labels <= 127);
|
|
|
|
offsets[labels] = nused;
|
|
|
|
}
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
1999-02-06 01:26:00 +00:00
|
|
|
if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
|
|
|
|
name->attributes |= DNS_NAMEATTR_ABSOLUTE;
|
2000-08-01 01:33:37 +00:00
|
|
|
}
|
1999-02-06 01:26:00 +00:00
|
|
|
} else
|
|
|
|
name->attributes |= DNS_NAMEATTR_ABSOLUTE;
|
1998-12-04 02:27:01 +00:00
|
|
|
|
1999-01-06 05:41:20 +00:00
|
|
|
name->ndata = (unsigned char *)target->base + target->used;
|
1998-12-04 02:27:01 +00:00
|
|
|
name->labels = labels;
|
1999-01-13 19:17:22 +00:00
|
|
|
name->length = nused;
|
1998-12-04 02:27:01 +00:00
|
|
|
|
1999-01-06 05:41:20 +00:00
|
|
|
isc_buffer_forward(source, tused);
|
|
|
|
isc_buffer_add(target, name->length);
|
|
|
|
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
|
2005-09-10 00:31:25 +00:00
|
|
|
static void
|
2005-09-18 07:16:24 +00:00
|
|
|
free_specific(void *arg) {
|
|
|
|
dns_name_totextfilter_t *mem = arg;
|
|
|
|
isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
|
|
|
|
/* Stop use being called again. */
|
|
|
|
(void)isc_thread_key_setspecific(totext_filter_proc_key, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
thread_key_mutex_init(void) {
|
|
|
|
RUNTIME_CHECK(isc_mutex_init(&thread_key_mutex) == ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2005-09-10 00:31:25 +00:00
|
|
|
totext_filter_proc_key_init(void) {
|
2005-09-18 07:16:24 +00:00
|
|
|
isc_result_t result;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We need the call to isc_once_do() to support profiled mutex
|
|
|
|
* otherwise thread_key_mutex could be initialized at compile time.
|
|
|
|
*/
|
|
|
|
result = isc_once_do(&once, thread_key_mutex_init);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
return (result);
|
|
|
|
|
2006-12-04 01:54:53 +00:00
|
|
|
if (!thread_key_initialized) {
|
2005-09-18 07:16:24 +00:00
|
|
|
LOCK(&thread_key_mutex);
|
|
|
|
if (thread_key_mctx == NULL)
|
2018-10-03 19:04:46 -07:00
|
|
|
result = isc_mem_create(0, 0, &thread_key_mctx);
|
2005-09-18 07:16:24 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto unlock;
|
2008-03-31 05:00:30 +00:00
|
|
|
isc_mem_setname(thread_key_mctx, "threadkey", NULL);
|
2018-04-17 08:29:14 -07:00
|
|
|
isc_mem_setdestroycheck(thread_key_mctx, false);
|
2008-04-01 23:47:10 +00:00
|
|
|
|
2005-09-18 07:16:24 +00:00
|
|
|
if (!thread_key_initialized &&
|
|
|
|
isc_thread_key_create(&totext_filter_proc_key,
|
2006-12-04 01:54:53 +00:00
|
|
|
free_specific) != 0) {
|
2005-09-18 07:16:24 +00:00
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
isc_mem_detach(&thread_key_mctx);
|
|
|
|
} else
|
|
|
|
thread_key_initialized = 1;
|
|
|
|
unlock:
|
|
|
|
UNLOCK(&thread_key_mutex);
|
2006-12-04 01:54:53 +00:00
|
|
|
}
|
2005-09-18 07:16:24 +00:00
|
|
|
return (result);
|
2005-09-10 00:31:25 +00:00
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
2018-04-17 08:29:14 -07:00
|
|
|
dns_name_totext(const dns_name_t *name, bool omit_final_dot,
|
1999-01-06 05:41:20 +00:00
|
|
|
isc_buffer_t *target)
|
2010-07-09 05:13:15 +00:00
|
|
|
{
|
|
|
|
unsigned int options = DNS_NAME_MASTERFILE;
|
|
|
|
|
|
|
|
if (omit_final_dot)
|
|
|
|
options |= DNS_NAME_OMITFINALDOT;
|
|
|
|
return (dns_name_totext2(name, options, target));
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
2015-02-27 15:08:38 +11:00
|
|
|
dns_name_toprincipal(const dns_name_t *name, isc_buffer_t *target) {
|
2010-07-09 05:13:15 +00:00
|
|
|
return (dns_name_totext2(name, DNS_NAME_OMITFINALDOT, target));
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
2015-02-27 15:08:38 +11:00
|
|
|
dns_name_totext2(const dns_name_t *name, unsigned int options,
|
2015-03-01 23:45:20 +00:00
|
|
|
isc_buffer_t *target)
|
1998-12-04 02:27:01 +00:00
|
|
|
{
|
|
|
|
unsigned char *ndata;
|
|
|
|
char *tdata;
|
|
|
|
unsigned int nlen, tlen;
|
|
|
|
unsigned char c;
|
|
|
|
unsigned int trem, count;
|
|
|
|
unsigned int labels;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool saw_root = false;
|
2005-09-09 06:17:03 +00:00
|
|
|
unsigned int oused = target->used;
|
2005-09-10 01:02:08 +00:00
|
|
|
dns_name_totextfilter_t *mem;
|
|
|
|
dns_name_totextfilter_t totext_filter_proc = NULL;
|
2005-09-10 00:31:25 +00:00
|
|
|
isc_result_t result;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool omit_final_dot = (options & DNS_NAME_OMITFINALDOT);
|
1998-12-04 02:27:01 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This function assumes the name is in proper uncompressed
|
|
|
|
* wire format.
|
|
|
|
*/
|
1999-01-06 05:41:20 +00:00
|
|
|
REQUIRE(VALID_NAME(name));
|
2000-08-16 22:18:20 +00:00
|
|
|
REQUIRE(ISC_BUFFER_VALID(target));
|
1998-12-04 02:27:01 +00:00
|
|
|
|
2005-09-18 07:16:24 +00:00
|
|
|
result = totext_filter_proc_key_init();
|
2005-09-10 00:31:25 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
return (result);
|
1998-12-04 02:27:01 +00:00
|
|
|
ndata = name->ndata;
|
|
|
|
nlen = name->length;
|
|
|
|
labels = name->labels;
|
2000-08-16 22:18:20 +00:00
|
|
|
tdata = isc_buffer_used(target);
|
|
|
|
tlen = isc_buffer_availablelength(target);
|
1998-12-04 02:27:01 +00:00
|
|
|
|
|
|
|
trem = tlen;
|
|
|
|
|
2000-07-31 23:09:49 +00:00
|
|
|
if (labels == 0 && nlen == 0) {
|
|
|
|
/*
|
|
|
|
* Special handling for an empty name.
|
|
|
|
*/
|
|
|
|
if (trem == 0)
|
|
|
|
return (ISC_R_NOSPACE);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The names of these booleans are misleading in this case.
|
|
|
|
* This empty name is not necessarily from the root node of
|
|
|
|
* the DNS root zone, nor is a final dot going to be included.
|
|
|
|
* They need to be set this way, though, to keep the "@"
|
|
|
|
* from being trounced.
|
|
|
|
*/
|
2018-04-17 08:29:14 -07:00
|
|
|
saw_root = true;
|
|
|
|
omit_final_dot = false;
|
2000-07-31 23:09:49 +00:00
|
|
|
*tdata++ = '@';
|
|
|
|
trem--;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Skip the while() loop.
|
|
|
|
*/
|
1998-12-04 02:27:01 +00:00
|
|
|
nlen = 0;
|
2000-07-31 23:09:49 +00:00
|
|
|
} else if (nlen == 1 && labels == 1 && *ndata == '\0') {
|
|
|
|
/*
|
|
|
|
* Special handling for the root label.
|
|
|
|
*/
|
1998-12-04 02:27:01 +00:00
|
|
|
if (trem == 0)
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2000-07-31 23:09:49 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
saw_root = true;
|
|
|
|
omit_final_dot = false;
|
1998-12-04 02:27:01 +00:00
|
|
|
*tdata++ = '.';
|
|
|
|
trem--;
|
2000-07-31 23:09:49 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Skip the while() loop.
|
|
|
|
*/
|
|
|
|
nlen = 0;
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
2000-07-31 23:09:49 +00:00
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
while (labels > 0 && nlen > 0 && trem > 0) {
|
|
|
|
labels--;
|
|
|
|
count = *ndata++;
|
|
|
|
nlen--;
|
|
|
|
if (count == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
saw_root = true;
|
1998-12-04 02:27:01 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (count < 64) {
|
|
|
|
INSIST(nlen >= count);
|
|
|
|
while (count > 0) {
|
|
|
|
c = *ndata;
|
|
|
|
switch (c) {
|
2010-07-09 05:13:15 +00:00
|
|
|
/* Special modifiers in zone files. */
|
|
|
|
case 0x40: /* '@' */
|
|
|
|
case 0x24: /* '$' */
|
|
|
|
if ((options & DNS_NAME_MASTERFILE) == 0)
|
|
|
|
goto no_escape;
|
2012-10-23 22:04:06 -07:00
|
|
|
/* FALLTHROUGH */
|
1998-12-04 02:27:01 +00:00
|
|
|
case 0x22: /* '"' */
|
2001-04-19 18:39:42 +00:00
|
|
|
case 0x28: /* '(' */
|
|
|
|
case 0x29: /* ')' */
|
1998-12-04 02:27:01 +00:00
|
|
|
case 0x2E: /* '.' */
|
|
|
|
case 0x3B: /* ';' */
|
|
|
|
case 0x5C: /* '\\' */
|
|
|
|
if (trem < 2)
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
1998-12-04 02:27:01 +00:00
|
|
|
*tdata++ = '\\';
|
1999-05-05 16:51:05 +00:00
|
|
|
CONVERTFROMASCII(c);
|
1998-12-04 02:27:01 +00:00
|
|
|
*tdata++ = c;
|
|
|
|
ndata++;
|
|
|
|
trem -= 2;
|
|
|
|
nlen--;
|
|
|
|
break;
|
2010-07-09 05:13:15 +00:00
|
|
|
no_escape:
|
1998-12-04 02:27:01 +00:00
|
|
|
default:
|
|
|
|
if (c > 0x20 && c < 0x7f) {
|
|
|
|
if (trem == 0)
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
1999-05-05 16:51:05 +00:00
|
|
|
CONVERTFROMASCII(c);
|
1998-12-04 02:27:01 +00:00
|
|
|
*tdata++ = c;
|
|
|
|
ndata++;
|
|
|
|
trem--;
|
|
|
|
nlen--;
|
|
|
|
} else {
|
|
|
|
if (trem < 4)
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2005-07-20 01:46:49 +00:00
|
|
|
*tdata++ = 0x5c;
|
|
|
|
*tdata++ = 0x30 +
|
|
|
|
((c / 100) % 10);
|
|
|
|
*tdata++ = 0x30 +
|
|
|
|
((c / 10) % 10);
|
|
|
|
*tdata++ = 0x30 + (c % 10);
|
1998-12-04 02:27:01 +00:00
|
|
|
trem -= 4;
|
|
|
|
ndata++;
|
|
|
|
nlen--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
count--;
|
|
|
|
}
|
2003-10-17 03:46:46 +00:00
|
|
|
} else {
|
1999-01-06 05:41:20 +00:00
|
|
|
FATAL_ERROR(__FILE__, __LINE__,
|
|
|
|
"Unexpected label type %02x", count);
|
2000-07-31 23:09:49 +00:00
|
|
|
/* NOTREACHED */
|
1999-01-06 05:41:20 +00:00
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
/*
|
|
|
|
* The following assumes names are absolute. If not, we
|
|
|
|
* fix things up later. Note that this means that in some
|
|
|
|
* cases one more byte of text buffer is required than is
|
|
|
|
* needed in the final output.
|
|
|
|
*/
|
|
|
|
if (trem == 0)
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
1998-12-04 02:27:01 +00:00
|
|
|
*tdata++ = '.';
|
|
|
|
trem--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nlen != 0 && trem == 0)
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2000-07-31 23:09:49 +00:00
|
|
|
|
2016-05-26 21:23:19 +02:00
|
|
|
if (!saw_root || omit_final_dot) {
|
1998-12-04 02:27:01 +00:00
|
|
|
trem++;
|
2016-05-26 21:23:19 +02:00
|
|
|
tdata--;
|
|
|
|
}
|
|
|
|
if (trem > 0) {
|
|
|
|
*tdata = 0;
|
|
|
|
}
|
1999-01-06 05:41:20 +00:00
|
|
|
isc_buffer_add(target, tlen - trem);
|
1998-12-04 02:27:01 +00:00
|
|
|
|
2005-09-18 07:16:24 +00:00
|
|
|
mem = isc_thread_key_getspecific(totext_filter_proc_key);
|
2006-01-10 02:59:56 +00:00
|
|
|
if (mem != NULL)
|
2005-09-10 01:02:08 +00:00
|
|
|
totext_filter_proc = *mem;
|
2005-09-09 06:17:03 +00:00
|
|
|
if (totext_filter_proc != NULL)
|
2018-07-10 14:34:35 +02:00
|
|
|
return ((*totext_filter_proc)(target, oused));
|
2005-09-09 06:17:03 +00:00
|
|
|
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
|
2001-03-27 22:57:48 +00:00
|
|
|
isc_result_t
|
2018-04-17 08:29:14 -07:00
|
|
|
dns_name_tofilenametext(const dns_name_t *name, bool omit_final_dot,
|
2001-03-27 22:57:48 +00:00
|
|
|
isc_buffer_t *target)
|
|
|
|
{
|
|
|
|
unsigned char *ndata;
|
|
|
|
char *tdata;
|
|
|
|
unsigned int nlen, tlen;
|
|
|
|
unsigned char c;
|
|
|
|
unsigned int trem, count;
|
|
|
|
unsigned int labels;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This function assumes the name is in proper uncompressed
|
|
|
|
* wire format.
|
|
|
|
*/
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
REQUIRE((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
|
|
|
|
REQUIRE(ISC_BUFFER_VALID(target));
|
|
|
|
|
|
|
|
ndata = name->ndata;
|
|
|
|
nlen = name->length;
|
|
|
|
labels = name->labels;
|
|
|
|
tdata = isc_buffer_used(target);
|
|
|
|
tlen = isc_buffer_availablelength(target);
|
|
|
|
|
|
|
|
trem = tlen;
|
|
|
|
|
|
|
|
if (nlen == 1 && labels == 1 && *ndata == '\0') {
|
|
|
|
/*
|
|
|
|
* Special handling for the root label.
|
|
|
|
*/
|
|
|
|
if (trem == 0)
|
|
|
|
return (ISC_R_NOSPACE);
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
omit_final_dot = false;
|
2001-03-27 22:57:48 +00:00
|
|
|
*tdata++ = '.';
|
|
|
|
trem--;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Skip the while() loop.
|
|
|
|
*/
|
|
|
|
nlen = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (labels > 0 && nlen > 0 && trem > 0) {
|
|
|
|
labels--;
|
|
|
|
count = *ndata++;
|
|
|
|
nlen--;
|
|
|
|
if (count == 0)
|
|
|
|
break;
|
|
|
|
if (count < 64) {
|
|
|
|
INSIST(nlen >= count);
|
|
|
|
while (count > 0) {
|
|
|
|
c = *ndata;
|
|
|
|
if ((c >= 0x30 && c <= 0x39) || /* digit */
|
|
|
|
(c >= 0x41 && c <= 0x5A) || /* uppercase */
|
|
|
|
(c >= 0x61 && c <= 0x7A) || /* lowercase */
|
|
|
|
c == 0x2D || /* hyphen */
|
|
|
|
c == 0x5F) /* underscore */
|
|
|
|
{
|
|
|
|
if (trem == 0)
|
|
|
|
return (ISC_R_NOSPACE);
|
2001-03-27 23:43:15 +00:00
|
|
|
/* downcase */
|
|
|
|
if (c >= 0x41 && c <= 0x5A)
|
|
|
|
c += 0x20;
|
2001-03-27 22:57:48 +00:00
|
|
|
CONVERTFROMASCII(c);
|
|
|
|
*tdata++ = c;
|
|
|
|
ndata++;
|
|
|
|
trem--;
|
|
|
|
nlen--;
|
|
|
|
} else {
|
2017-09-13 21:18:26 -07:00
|
|
|
if (trem < 4)
|
2001-03-27 22:57:48 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2017-09-13 00:14:37 -07:00
|
|
|
snprintf(tdata, trem, "%%%02X", c);
|
2001-03-27 22:57:48 +00:00
|
|
|
tdata += 3;
|
|
|
|
trem -= 3;
|
|
|
|
ndata++;
|
|
|
|
nlen--;
|
|
|
|
}
|
|
|
|
count--;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
FATAL_ERROR(__FILE__, __LINE__,
|
|
|
|
"Unexpected label type %02x", count);
|
|
|
|
/* NOTREACHED */
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The following assumes names are absolute. If not, we
|
|
|
|
* fix things up later. Note that this means that in some
|
|
|
|
* cases one more byte of text buffer is required than is
|
|
|
|
* needed in the final output.
|
|
|
|
*/
|
|
|
|
if (trem == 0)
|
|
|
|
return (ISC_R_NOSPACE);
|
|
|
|
*tdata++ = '.';
|
|
|
|
trem--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nlen != 0 && trem == 0)
|
|
|
|
return (ISC_R_NOSPACE);
|
|
|
|
|
|
|
|
if (omit_final_dot)
|
|
|
|
trem++;
|
|
|
|
|
|
|
|
isc_buffer_add(target, tlen - trem);
|
|
|
|
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
1999-08-26 21:07:38 +00:00
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_name_downcase(const dns_name_t *source, dns_name_t *name,
|
|
|
|
isc_buffer_t *target)
|
|
|
|
{
|
1999-08-26 21:07:38 +00:00
|
|
|
unsigned char *sndata, *ndata;
|
2002-08-27 04:53:43 +00:00
|
|
|
unsigned int nlen, count, labels;
|
1999-08-26 21:07:38 +00:00
|
|
|
isc_buffer_t buffer;
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-08-26 21:07:38 +00:00
|
|
|
/*
|
|
|
|
* Downcase 'source'.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(source));
|
1999-08-20 17:01:06 +00:00
|
|
|
REQUIRE(VALID_NAME(name));
|
1999-08-26 21:07:38 +00:00
|
|
|
if (source == name) {
|
|
|
|
REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_init(&buffer, source->ndata, source->length);
|
1999-08-26 21:07:38 +00:00
|
|
|
target = &buffer;
|
|
|
|
ndata = source->ndata;
|
|
|
|
} else {
|
|
|
|
REQUIRE(BINDABLE(name));
|
2002-05-29 00:27:53 +00:00
|
|
|
REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
|
|
|
|
(target == NULL && ISC_BUFFER_VALID(name->buffer)));
|
2002-05-28 03:39:46 +00:00
|
|
|
if (target == NULL) {
|
1999-08-26 21:07:38 +00:00
|
|
|
target = name->buffer;
|
|
|
|
isc_buffer_clear(name->buffer);
|
|
|
|
}
|
|
|
|
ndata = (unsigned char *)target->base + target->used;
|
|
|
|
name->ndata = ndata;
|
|
|
|
}
|
1999-08-20 17:01:06 +00:00
|
|
|
|
1999-08-26 21:07:38 +00:00
|
|
|
sndata = source->ndata;
|
|
|
|
nlen = source->length;
|
|
|
|
labels = source->labels;
|
|
|
|
|
|
|
|
if (nlen > (target->length - target->used)) {
|
|
|
|
MAKE_EMPTY(name);
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
1999-08-26 21:07:38 +00:00
|
|
|
}
|
1999-08-20 17:01:06 +00:00
|
|
|
|
|
|
|
while (labels > 0 && nlen > 0) {
|
|
|
|
labels--;
|
1999-08-26 21:07:38 +00:00
|
|
|
count = *sndata++;
|
|
|
|
*ndata++ = count;
|
1999-08-20 17:01:06 +00:00
|
|
|
nlen--;
|
|
|
|
if (count < 64) {
|
|
|
|
INSIST(nlen >= count);
|
|
|
|
while (count > 0) {
|
1999-08-26 21:07:38 +00:00
|
|
|
*ndata++ = maptolower[(*sndata++)];
|
1999-08-20 17:01:06 +00:00
|
|
|
nlen--;
|
|
|
|
count--;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
FATAL_ERROR(__FILE__, __LINE__,
|
|
|
|
"Unexpected label type %02x", count);
|
|
|
|
/* Does not return. */
|
|
|
|
}
|
|
|
|
}
|
1999-08-26 21:07:38 +00:00
|
|
|
|
|
|
|
if (source != name) {
|
|
|
|
name->labels = source->labels;
|
|
|
|
name->length = source->length;
|
|
|
|
if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
|
|
|
|
name->attributes = DNS_NAMEATTR_ABSOLUTE;
|
|
|
|
else
|
|
|
|
name->attributes = 0;
|
|
|
|
if (name->labels > 0 && name->offsets != NULL)
|
2000-06-01 18:26:56 +00:00
|
|
|
set_offsets(name, name->offsets, NULL);
|
1999-08-26 21:07:38 +00:00
|
|
|
}
|
|
|
|
|
2000-03-23 17:56:24 +00:00
|
|
|
isc_buffer_add(target, name->length);
|
|
|
|
|
1999-08-26 21:07:38 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
1999-08-20 17:01:06 +00:00
|
|
|
}
|
|
|
|
|
1998-12-04 02:27:01 +00:00
|
|
|
static void
|
2000-06-01 18:26:56 +00:00
|
|
|
set_offsets(const dns_name_t *name, unsigned char *offsets,
|
|
|
|
dns_name_t *set_name)
|
|
|
|
{
|
2002-08-27 04:53:43 +00:00
|
|
|
unsigned int offset, count, length, nlabels;
|
1998-12-04 02:27:01 +00:00
|
|
|
unsigned char *ndata;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool absolute;
|
1998-12-04 02:27:01 +00:00
|
|
|
|
|
|
|
ndata = name->ndata;
|
2000-04-26 23:22:53 +00:00
|
|
|
length = name->length;
|
1998-12-04 02:27:01 +00:00
|
|
|
offset = 0;
|
|
|
|
nlabels = 0;
|
2018-04-17 08:29:14 -07:00
|
|
|
absolute = false;
|
2017-04-22 08:25:10 +05:30
|
|
|
while (ISC_LIKELY(offset != length)) {
|
1998-12-04 02:27:01 +00:00
|
|
|
INSIST(nlabels < 128);
|
1999-01-09 00:33:15 +00:00
|
|
|
offsets[nlabels++] = offset;
|
2017-04-22 08:25:10 +05:30
|
|
|
count = *ndata;
|
2002-08-27 04:53:43 +00:00
|
|
|
INSIST(count <= 63);
|
2017-04-22 08:25:10 +05:30
|
|
|
offset += count + 1;
|
|
|
|
ndata += count + 1;
|
2002-08-27 04:53:43 +00:00
|
|
|
INSIST(offset <= length);
|
2017-04-22 08:25:10 +05:30
|
|
|
if (ISC_UNLIKELY(count == 0)) {
|
2018-04-17 08:29:14 -07:00
|
|
|
absolute = true;
|
2002-08-27 04:53:43 +00:00
|
|
|
break;
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
}
|
2000-06-01 18:26:56 +00:00
|
|
|
if (set_name != NULL) {
|
|
|
|
INSIST(set_name == name);
|
|
|
|
|
|
|
|
set_name->labels = nlabels;
|
|
|
|
set_name->length = offset;
|
1999-02-06 01:26:00 +00:00
|
|
|
if (absolute)
|
2000-06-01 18:26:56 +00:00
|
|
|
set_name->attributes |= DNS_NAMEATTR_ABSOLUTE;
|
1999-02-06 01:26:00 +00:00
|
|
|
else
|
2000-06-01 18:26:56 +00:00
|
|
|
set_name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
|
1999-02-06 01:26:00 +00:00
|
|
|
}
|
1998-12-04 02:27:01 +00:00
|
|
|
INSIST(nlabels == name->labels);
|
1999-01-09 01:17:09 +00:00
|
|
|
INSIST(offset == name->length);
|
1998-12-04 02:27:01 +00:00
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
1999-01-06 05:41:20 +00:00
|
|
|
dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
|
2004-02-27 20:41:51 +00:00
|
|
|
dns_decompress_t *dctx, unsigned int options,
|
1999-01-06 05:41:20 +00:00
|
|
|
isc_buffer_t *target)
|
|
|
|
{
|
|
|
|
unsigned char *cdata, *ndata;
|
2000-06-09 22:01:55 +00:00
|
|
|
unsigned int cused; /* Bytes of compressed name data used */
|
2006-12-07 06:57:46 +00:00
|
|
|
unsigned int nused, labels, n, nmax;
|
2000-03-23 05:18:46 +00:00
|
|
|
unsigned int current, new_current, biggest_pointer;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool done;
|
1999-01-06 05:41:20 +00:00
|
|
|
fw_state state = fw_start;
|
|
|
|
unsigned int c;
|
1999-01-09 00:33:15 +00:00
|
|
|
unsigned char *offsets;
|
|
|
|
dns_offsets_t odata;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool downcase;
|
|
|
|
bool seen_pointer;
|
1999-01-06 05:41:20 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copy the possibly-compressed name at source into target,
|
2006-12-07 06:57:46 +00:00
|
|
|
* decompressing it. Loop prevention is performed by checking
|
|
|
|
* the new pointer against biggest_pointer.
|
1999-01-06 05:41:20 +00:00
|
|
|
*/
|
|
|
|
|
1999-01-09 00:33:15 +00:00
|
|
|
REQUIRE(VALID_NAME(name));
|
2002-05-29 00:27:53 +00:00
|
|
|
REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
|
|
|
|
(target == NULL && ISC_BUFFER_VALID(name->buffer)));
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
downcase = (options & DNS_NAME_DOWNCASE);
|
2004-02-27 20:41:51 +00:00
|
|
|
|
1999-03-08 18:55:28 +00:00
|
|
|
if (target == NULL && name->buffer != NULL) {
|
|
|
|
target = name->buffer;
|
|
|
|
isc_buffer_clear(target);
|
|
|
|
}
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
|
1999-01-06 20:04:41 +00:00
|
|
|
REQUIRE(dctx != NULL);
|
1999-08-19 23:26:16 +00:00
|
|
|
REQUIRE(BINDABLE(name));
|
1999-01-06 05:41:20 +00:00
|
|
|
|
1999-01-09 00:33:15 +00:00
|
|
|
INIT_OFFSETS(name, offsets, odata);
|
|
|
|
|
1999-01-06 05:41:20 +00:00
|
|
|
/*
|
1999-08-12 20:26:45 +00:00
|
|
|
* Make 'name' empty in case of failure.
|
1999-01-06 05:41:20 +00:00
|
|
|
*/
|
1999-08-12 20:26:45 +00:00
|
|
|
MAKE_EMPTY(name);
|
1999-01-06 05:41:20 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize things to make the compiler happy; they're not required.
|
|
|
|
*/
|
|
|
|
n = 0;
|
|
|
|
new_current = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set up.
|
|
|
|
*/
|
|
|
|
labels = 0;
|
2018-04-17 08:29:14 -07:00
|
|
|
done = false;
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2000-06-09 22:01:55 +00:00
|
|
|
ndata = isc_buffer_used(target);
|
1999-01-13 19:17:22 +00:00
|
|
|
nused = 0;
|
2018-04-17 08:29:14 -07:00
|
|
|
seen_pointer = false;
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2000-06-09 22:01:55 +00:00
|
|
|
/*
|
|
|
|
* Find the maximum number of uncompressed target name
|
|
|
|
* bytes we are willing to generate. This is the smaller
|
|
|
|
* of the available target buffer length and the
|
|
|
|
* maximum legal domain name length (255).
|
|
|
|
*/
|
|
|
|
nmax = isc_buffer_availablelength(target);
|
2000-10-11 17:44:18 +00:00
|
|
|
if (nmax > DNS_NAME_MAXWIRE)
|
|
|
|
nmax = DNS_NAME_MAXWIRE;
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2000-06-09 22:01:55 +00:00
|
|
|
cdata = isc_buffer_current(source);
|
1999-01-06 05:41:20 +00:00
|
|
|
cused = 0;
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-01-06 05:41:20 +00:00
|
|
|
current = source->current;
|
|
|
|
biggest_pointer = current;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Note: The following code is not optimized for speed, but
|
|
|
|
* rather for correctness. Speed will be addressed in the future.
|
|
|
|
*/
|
|
|
|
|
1999-02-15 23:59:36 +00:00
|
|
|
while (current < source->active && !done) {
|
1999-01-06 05:41:20 +00:00
|
|
|
c = *cdata++;
|
|
|
|
current++;
|
2006-12-07 06:57:46 +00:00
|
|
|
if (!seen_pointer)
|
1999-01-06 05:41:20 +00:00
|
|
|
cused++;
|
|
|
|
|
|
|
|
switch (state) {
|
|
|
|
case fw_start:
|
|
|
|
if (c < 64) {
|
2001-02-13 00:07:25 +00:00
|
|
|
offsets[labels] = nused;
|
1999-01-06 05:41:20 +00:00
|
|
|
labels++;
|
2000-06-09 22:01:55 +00:00
|
|
|
if (nused + c + 1 > nmax)
|
|
|
|
goto full;
|
1999-01-13 19:17:22 +00:00
|
|
|
nused += c + 1;
|
1999-01-06 05:41:20 +00:00
|
|
|
*ndata++ = c;
|
|
|
|
if (c == 0)
|
2018-04-17 08:29:14 -07:00
|
|
|
done = true;
|
1999-01-06 05:41:20 +00:00
|
|
|
n = c;
|
|
|
|
state = fw_ordinary;
|
1999-02-24 06:31:35 +00:00
|
|
|
} else if (c >= 128 && c < 192) {
|
|
|
|
/*
|
|
|
|
* 14 bit local compression pointer.
|
2000-03-23 05:18:46 +00:00
|
|
|
* Local compression is no longer an
|
|
|
|
* IETF draft.
|
1999-02-24 06:31:35 +00:00
|
|
|
*/
|
2000-03-23 05:18:46 +00:00
|
|
|
return (DNS_R_BADLABELTYPE);
|
1999-01-06 05:41:20 +00:00
|
|
|
} else if (c >= 192) {
|
1999-01-06 20:04:41 +00:00
|
|
|
/*
|
|
|
|
* Ordinary 14-bit pointer.
|
|
|
|
*/
|
|
|
|
if ((dctx->allowed & DNS_COMPRESS_GLOBAL14) ==
|
|
|
|
0)
|
|
|
|
return (DNS_R_DISALLOWED);
|
1999-01-06 05:41:20 +00:00
|
|
|
new_current = c & 0x3F;
|
|
|
|
state = fw_newcurrent;
|
|
|
|
} else
|
|
|
|
return (DNS_R_BADLABELTYPE);
|
|
|
|
break;
|
|
|
|
case fw_ordinary:
|
|
|
|
if (downcase)
|
|
|
|
c = maptolower[c];
|
|
|
|
*ndata++ = c;
|
|
|
|
n--;
|
|
|
|
if (n == 0)
|
|
|
|
state = fw_start;
|
|
|
|
break;
|
|
|
|
case fw_newcurrent:
|
|
|
|
new_current *= 256;
|
|
|
|
new_current += c;
|
1999-02-24 06:31:35 +00:00
|
|
|
if (new_current >= biggest_pointer)
|
|
|
|
return (DNS_R_BADPOINTER);
|
|
|
|
biggest_pointer = new_current;
|
|
|
|
current = new_current;
|
2006-12-07 06:57:46 +00:00
|
|
|
cdata = (unsigned char *)source->base + current;
|
2018-04-17 08:29:14 -07:00
|
|
|
seen_pointer = true;
|
1999-02-24 06:31:35 +00:00
|
|
|
state = fw_start;
|
1999-01-06 05:41:20 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
FATAL_ERROR(__FILE__, __LINE__,
|
|
|
|
"Unknown state %d", state);
|
|
|
|
/* Does not return. */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!done)
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_UNEXPECTEDEND);
|
1999-01-06 05:41:20 +00:00
|
|
|
|
|
|
|
name->ndata = (unsigned char *)target->base + target->used;
|
|
|
|
name->labels = labels;
|
1999-01-13 19:17:22 +00:00
|
|
|
name->length = nused;
|
1999-02-06 01:26:00 +00:00
|
|
|
name->attributes |= DNS_NAMEATTR_ABSOLUTE;
|
1999-01-06 05:41:20 +00:00
|
|
|
|
|
|
|
isc_buffer_forward(source, cused);
|
|
|
|
isc_buffer_add(target, name->length);
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
2000-06-09 22:01:55 +00:00
|
|
|
|
|
|
|
full:
|
2000-10-11 17:44:18 +00:00
|
|
|
if (nmax == DNS_NAME_MAXWIRE)
|
2000-06-09 22:01:55 +00:00
|
|
|
/*
|
|
|
|
* The name did not fit even though we had a buffer
|
|
|
|
* big enough to fit a maximum-length name.
|
|
|
|
*/
|
2000-07-13 18:10:18 +00:00
|
|
|
return (DNS_R_NAMETOOLONG);
|
2000-06-09 22:01:55 +00:00
|
|
|
else
|
|
|
|
/*
|
|
|
|
* The name might fit if only the caller could give us a
|
|
|
|
* big enough buffer.
|
|
|
|
*/
|
|
|
|
return (ISC_R_NOSPACE);
|
1999-01-06 05:41:20 +00:00
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
2006-02-28 02:39:52 +00:00
|
|
|
dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
|
|
|
|
isc_buffer_t *target)
|
2017-09-13 09:24:34 +10:00
|
|
|
{
|
|
|
|
return (dns_name_towire2(name, cctx, target, NULL));
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
dns_name_towire2(const dns_name_t *name, dns_compress_t *cctx,
|
2018-03-28 14:19:37 +02:00
|
|
|
isc_buffer_t *target, uint16_t *comp_offsetp)
|
2006-02-28 02:39:52 +00:00
|
|
|
{
|
1999-02-22 07:24:05 +00:00
|
|
|
unsigned int methods;
|
2018-03-28 14:19:37 +02:00
|
|
|
uint16_t offset;
|
2001-01-07 22:01:59 +00:00
|
|
|
dns_name_t gp; /* Global compression prefix */
|
2018-04-17 08:29:14 -07:00
|
|
|
bool gf; /* Global compression target found */
|
2018-03-28 14:19:37 +02:00
|
|
|
uint16_t go; /* Global compression offset */
|
2001-02-12 05:22:34 +00:00
|
|
|
dns_offsets_t clo;
|
2000-04-26 23:22:53 +00:00
|
|
|
dns_name_t clname;
|
1999-02-22 07:24:05 +00:00
|
|
|
|
1999-01-06 05:41:20 +00:00
|
|
|
/*
|
|
|
|
* Convert 'name' into wire format, compressing it as specified by the
|
|
|
|
* compression context 'cctx', and storing the result in 'target'.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
REQUIRE(cctx != NULL);
|
2002-05-29 00:27:53 +00:00
|
|
|
REQUIRE(ISC_BUFFER_VALID(target));
|
1999-01-06 05:41:20 +00:00
|
|
|
|
2017-09-13 09:24:34 +10:00
|
|
|
/*
|
|
|
|
* If this exact name was already rendered before, and the
|
|
|
|
* offset of the previously rendered name is passed to us, write
|
|
|
|
* a compression pointer directly.
|
|
|
|
*/
|
|
|
|
methods = dns_compress_getmethods(cctx);
|
|
|
|
if (comp_offsetp != NULL && *comp_offsetp < 0x4000 &&
|
|
|
|
(name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 &&
|
|
|
|
(methods & DNS_COMPRESS_GLOBAL14) != 0) {
|
|
|
|
if (ISC_UNLIKELY(target->length - target->used < 2))
|
|
|
|
return (ISC_R_NOSPACE);
|
|
|
|
offset = *comp_offsetp;
|
|
|
|
offset |= 0xc000;
|
|
|
|
isc_buffer_putuint16(target, offset);
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2000-04-26 23:22:53 +00:00
|
|
|
/*
|
|
|
|
* If 'name' doesn't have an offsets table, make a clone which
|
|
|
|
* has one.
|
|
|
|
*/
|
|
|
|
if (name->offsets == NULL) {
|
2012-12-01 21:32:31 +11:00
|
|
|
#if defined(__clang__) && \
|
2012-12-03 07:58:01 +11:00
|
|
|
( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
|
2012-12-01 21:32:31 +11:00
|
|
|
memset(&clname, 0, sizeof(clname));
|
|
|
|
#endif
|
2001-01-03 00:05:15 +00:00
|
|
|
DNS_NAME_INIT(&clname, clo);
|
2000-04-26 23:22:53 +00:00
|
|
|
dns_name_clone(name, &clname);
|
|
|
|
name = &clname;
|
|
|
|
}
|
2001-02-12 05:22:34 +00:00
|
|
|
DNS_NAME_INIT(&gp, NULL);
|
1999-02-22 07:24:05 +00:00
|
|
|
|
|
|
|
offset = target->used; /*XXX*/
|
|
|
|
|
2006-12-04 01:54:53 +00:00
|
|
|
if ((name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 &&
|
|
|
|
(methods & DNS_COMPRESS_GLOBAL14) != 0)
|
2001-02-12 18:07:52 +00:00
|
|
|
gf = dns_compress_findglobal(cctx, name, &gp, &go);
|
1999-02-22 07:24:05 +00:00
|
|
|
else
|
2018-04-17 08:29:14 -07:00
|
|
|
gf = false;
|
1999-02-22 07:24:05 +00:00
|
|
|
|
2000-12-28 00:43:12 +00:00
|
|
|
/*
|
|
|
|
* If the offset is too high for 14 bit global compression, we're
|
|
|
|
* out of luck.
|
|
|
|
*/
|
2017-09-13 09:24:34 +10:00
|
|
|
if (gf && ISC_UNLIKELY(go >= 0x4000))
|
2018-04-17 08:29:14 -07:00
|
|
|
gf = false;
|
2000-12-28 00:43:12 +00:00
|
|
|
|
1999-04-28 03:03:56 +00:00
|
|
|
/*
|
|
|
|
* Will the compression pointer reduce the message size?
|
|
|
|
*/
|
2000-12-28 00:43:12 +00:00
|
|
|
if (gf && (gp.length + 2) >= name->length)
|
2018-04-17 08:29:14 -07:00
|
|
|
gf = false;
|
1999-04-28 03:03:56 +00:00
|
|
|
|
1999-02-22 07:24:05 +00:00
|
|
|
if (gf) {
|
2017-09-13 09:24:34 +10:00
|
|
|
if (ISC_UNLIKELY(target->length - target->used < gp.length))
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2017-12-06 21:00:14 +11:00
|
|
|
if (gp.length != 0) {
|
|
|
|
unsigned char *base = target->base;
|
|
|
|
(void)memmove(base + target->used, gp.ndata,
|
|
|
|
(size_t)gp.length);
|
|
|
|
}
|
1999-02-22 07:24:05 +00:00
|
|
|
isc_buffer_add(target, gp.length);
|
2017-09-13 09:24:34 +10:00
|
|
|
if (ISC_UNLIKELY(target->length - target->used < 2))
|
2000-12-28 00:43:12 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2017-09-13 09:24:34 +10:00
|
|
|
isc_buffer_putuint16(target, go | 0xc000);
|
|
|
|
if (gp.length != 0) {
|
2001-01-04 19:25:59 +00:00
|
|
|
dns_compress_add(cctx, name, &gp, offset);
|
2017-09-13 09:24:34 +10:00
|
|
|
if (comp_offsetp != NULL)
|
|
|
|
*comp_offsetp = offset;
|
|
|
|
} else if (comp_offsetp != NULL) {
|
|
|
|
*comp_offsetp = go;
|
|
|
|
}
|
1999-02-22 07:24:05 +00:00
|
|
|
} else {
|
2017-09-13 09:24:34 +10:00
|
|
|
if (ISC_UNLIKELY(target->length - target->used < name->length))
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2017-12-06 21:00:14 +11:00
|
|
|
if (name->length != 0) {
|
|
|
|
unsigned char *base = target->base;
|
|
|
|
(void)memmove(base + target->used, name->ndata,
|
|
|
|
(size_t)name->length);
|
|
|
|
}
|
1999-02-22 07:24:05 +00:00
|
|
|
isc_buffer_add(target, name->length);
|
2001-01-04 19:25:59 +00:00
|
|
|
dns_compress_add(cctx, name, name, offset);
|
2017-09-13 09:24:34 +10:00
|
|
|
if (comp_offsetp != NULL)
|
|
|
|
*comp_offsetp = offset;
|
1999-02-22 07:24:05 +00:00
|
|
|
}
|
2017-09-13 09:24:34 +10:00
|
|
|
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
1999-02-22 07:24:05 +00:00
|
|
|
}
|
1999-01-06 05:41:20 +00:00
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_name_concatenate(const dns_name_t *prefix, const dns_name_t *suffix,
|
|
|
|
dns_name_t *name, isc_buffer_t *target)
|
1999-02-22 07:24:05 +00:00
|
|
|
{
|
1999-03-11 00:44:17 +00:00
|
|
|
unsigned char *ndata, *offsets;
|
2002-08-27 04:53:43 +00:00
|
|
|
unsigned int nrem, labels, prefix_length, length;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool copy_prefix = true;
|
|
|
|
bool copy_suffix = true;
|
|
|
|
bool absolute = false;
|
1999-03-11 00:44:17 +00:00
|
|
|
dns_name_t tmp_name;
|
1999-02-22 07:24:05 +00:00
|
|
|
dns_offsets_t odata;
|
1999-03-08 18:55:28 +00:00
|
|
|
|
|
|
|
/*
|
1999-03-11 00:44:17 +00:00
|
|
|
* Concatenate 'prefix' and 'suffix'.
|
1999-03-08 18:55:28 +00:00
|
|
|
*/
|
1999-02-22 07:24:05 +00:00
|
|
|
|
1999-03-11 00:44:17 +00:00
|
|
|
REQUIRE(prefix == NULL || VALID_NAME(prefix));
|
|
|
|
REQUIRE(suffix == NULL || VALID_NAME(suffix));
|
|
|
|
REQUIRE(name == NULL || VALID_NAME(name));
|
2002-05-29 00:27:53 +00:00
|
|
|
REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
|
|
|
|
(target == NULL && name != NULL && ISC_BUFFER_VALID(name->buffer)));
|
1999-03-11 00:44:17 +00:00
|
|
|
if (prefix == NULL || prefix->labels == 0)
|
2018-04-17 08:29:14 -07:00
|
|
|
copy_prefix = false;
|
1999-03-11 00:44:17 +00:00
|
|
|
if (suffix == NULL || suffix->labels == 0)
|
2018-04-17 08:29:14 -07:00
|
|
|
copy_suffix = false;
|
1999-03-11 00:44:17 +00:00
|
|
|
if (copy_prefix &&
|
|
|
|
(prefix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
absolute = true;
|
1999-03-11 00:44:17 +00:00
|
|
|
REQUIRE(!copy_suffix);
|
|
|
|
}
|
|
|
|
if (name == NULL) {
|
2001-01-03 00:05:15 +00:00
|
|
|
DNS_NAME_INIT(&tmp_name, odata);
|
1999-03-11 00:44:17 +00:00
|
|
|
name = &tmp_name;
|
|
|
|
}
|
2002-05-29 00:27:53 +00:00
|
|
|
if (target == NULL) {
|
|
|
|
INSIST(name->buffer != NULL);
|
1999-03-08 18:55:28 +00:00
|
|
|
target = name->buffer;
|
1999-03-11 00:44:17 +00:00
|
|
|
isc_buffer_clear(name->buffer);
|
1999-03-08 18:55:28 +00:00
|
|
|
}
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
|
1999-08-19 23:26:16 +00:00
|
|
|
REQUIRE(BINDABLE(name));
|
1999-02-22 07:24:05 +00:00
|
|
|
|
1999-03-08 18:55:28 +00:00
|
|
|
/*
|
|
|
|
* Set up.
|
|
|
|
*/
|
1999-02-22 07:24:05 +00:00
|
|
|
nrem = target->length - target->used;
|
|
|
|
ndata = (unsigned char *)target->base + target->used;
|
2000-10-11 17:44:18 +00:00
|
|
|
if (nrem > DNS_NAME_MAXWIRE)
|
|
|
|
nrem = DNS_NAME_MAXWIRE;
|
1999-03-11 00:44:17 +00:00
|
|
|
length = 0;
|
|
|
|
prefix_length = 0;
|
|
|
|
labels = 0;
|
|
|
|
if (copy_prefix) {
|
|
|
|
prefix_length = prefix->length;
|
|
|
|
length += prefix_length;
|
|
|
|
labels += prefix->labels;
|
|
|
|
}
|
|
|
|
if (copy_suffix) {
|
|
|
|
length += suffix->length;
|
|
|
|
labels += suffix->labels;
|
|
|
|
}
|
2000-10-11 17:44:18 +00:00
|
|
|
if (length > DNS_NAME_MAXWIRE) {
|
2000-07-13 18:10:18 +00:00
|
|
|
MAKE_EMPTY(name);
|
|
|
|
return (DNS_R_NAMETOOLONG);
|
|
|
|
}
|
1999-03-11 00:44:17 +00:00
|
|
|
if (length > nrem) {
|
1999-08-12 20:26:45 +00:00
|
|
|
MAKE_EMPTY(name);
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
1999-03-11 00:44:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (copy_suffix) {
|
|
|
|
if ((suffix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
|
2018-04-17 08:29:14 -07:00
|
|
|
absolute = true;
|
2014-01-20 17:58:47 -08:00
|
|
|
memmove(ndata + prefix_length, suffix->ndata, suffix->length);
|
1999-03-11 00:44:17 +00:00
|
|
|
}
|
1999-02-22 07:24:05 +00:00
|
|
|
|
1999-03-08 18:55:28 +00:00
|
|
|
/*
|
1999-03-11 00:44:17 +00:00
|
|
|
* If 'prefix' and 'name' are the same object, and the object has
|
|
|
|
* a dedicated buffer, and we're using it, then we don't have to
|
|
|
|
* copy anything.
|
1999-03-08 18:55:28 +00:00
|
|
|
*/
|
1999-03-11 00:44:17 +00:00
|
|
|
if (copy_prefix && (prefix != name || prefix->buffer != target))
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(ndata, prefix->ndata, prefix_length);
|
1999-01-06 05:41:20 +00:00
|
|
|
|
1999-03-11 00:44:17 +00:00
|
|
|
name->ndata = ndata;
|
1999-02-22 07:24:05 +00:00
|
|
|
name->labels = labels;
|
1999-03-11 00:44:17 +00:00
|
|
|
name->length = length;
|
|
|
|
if (absolute)
|
|
|
|
name->attributes = DNS_NAMEATTR_ABSOLUTE;
|
|
|
|
else
|
|
|
|
name->attributes = 0;
|
1999-02-22 07:24:05 +00:00
|
|
|
|
2002-08-27 04:53:43 +00:00
|
|
|
if (name->labels > 0 && name->offsets != NULL) {
|
1999-03-11 00:44:17 +00:00
|
|
|
INIT_OFFSETS(name, offsets, odata);
|
2000-06-01 18:26:56 +00:00
|
|
|
set_offsets(name, offsets, NULL);
|
1999-03-08 18:55:28 +00:00
|
|
|
}
|
1999-02-22 07:24:05 +00:00
|
|
|
|
|
|
|
isc_buffer_add(target, name->length);
|
1999-03-08 18:55:28 +00:00
|
|
|
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
1999-01-06 05:41:20 +00:00
|
|
|
}
|
1999-04-23 04:58:43 +00:00
|
|
|
|
2003-10-25 00:31:12 +00:00
|
|
|
void
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_name_split(const dns_name_t *name, unsigned int suffixlabels,
|
1999-04-23 04:58:43 +00:00
|
|
|
dns_name_t *prefix, dns_name_t *suffix)
|
|
|
|
|
|
|
|
{
|
2002-08-27 04:53:43 +00:00
|
|
|
unsigned int splitlabel;
|
1999-04-23 04:58:43 +00:00
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
2000-10-14 04:38:22 +00:00
|
|
|
REQUIRE(suffixlabels > 0);
|
2016-06-22 10:49:25 +02:00
|
|
|
REQUIRE(suffixlabels <= name->labels);
|
1999-04-23 04:58:43 +00:00
|
|
|
REQUIRE(prefix != NULL || suffix != NULL);
|
|
|
|
REQUIRE(prefix == NULL ||
|
|
|
|
(VALID_NAME(prefix) &&
|
1999-08-19 23:26:16 +00:00
|
|
|
BINDABLE(prefix)));
|
1999-04-23 04:58:43 +00:00
|
|
|
REQUIRE(suffix == NULL ||
|
|
|
|
(VALID_NAME(suffix) &&
|
1999-08-19 23:26:16 +00:00
|
|
|
BINDABLE(suffix)));
|
1999-04-23 04:58:43 +00:00
|
|
|
|
|
|
|
splitlabel = name->labels - suffixlabels;
|
2000-11-27 19:45:45 +00:00
|
|
|
|
2002-08-27 04:53:43 +00:00
|
|
|
if (prefix != NULL)
|
|
|
|
dns_name_getlabelsequence(name, 0, splitlabel, prefix);
|
1999-04-23 04:58:43 +00:00
|
|
|
|
2002-08-27 04:53:43 +00:00
|
|
|
if (suffix != NULL)
|
|
|
|
dns_name_getlabelsequence(name, splitlabel,
|
|
|
|
suffixlabels, suffix);
|
1999-04-23 04:58:43 +00:00
|
|
|
|
2003-10-25 00:31:12 +00:00
|
|
|
return;
|
2000-02-25 01:06:54 +00:00
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
2006-02-28 02:39:52 +00:00
|
|
|
dns_name_dup(const dns_name_t *source, isc_mem_t *mctx,
|
|
|
|
dns_name_t *target)
|
|
|
|
{
|
1999-08-31 22:09:52 +00:00
|
|
|
/*
|
|
|
|
* Make 'target' a dynamically allocated copy of 'source'.
|
|
|
|
*/
|
|
|
|
|
1999-06-12 01:08:16 +00:00
|
|
|
REQUIRE(VALID_NAME(source));
|
|
|
|
REQUIRE(source->length > 0);
|
1999-07-03 20:51:31 +00:00
|
|
|
REQUIRE(VALID_NAME(target));
|
1999-08-19 23:26:16 +00:00
|
|
|
REQUIRE(BINDABLE(target));
|
1999-06-12 01:08:16 +00:00
|
|
|
|
1999-08-12 20:26:45 +00:00
|
|
|
/*
|
|
|
|
* Make 'target' empty in case of failure.
|
|
|
|
*/
|
|
|
|
MAKE_EMPTY(target);
|
1999-07-03 20:51:31 +00:00
|
|
|
|
1999-06-12 01:08:16 +00:00
|
|
|
target->ndata = isc_mem_get(mctx, source->length);
|
|
|
|
if (target->ndata == NULL)
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOMEMORY);
|
1999-06-12 01:08:16 +00:00
|
|
|
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(target->ndata, source->ndata, source->length);
|
1999-06-12 01:08:16 +00:00
|
|
|
|
|
|
|
target->length = source->length;
|
|
|
|
target->labels = source->labels;
|
1999-08-19 23:26:16 +00:00
|
|
|
target->attributes = DNS_NAMEATTR_DYNAMIC;
|
1999-06-12 01:08:16 +00:00
|
|
|
if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
|
|
|
|
target->attributes |= DNS_NAMEATTR_ABSOLUTE;
|
2000-03-30 00:57:06 +00:00
|
|
|
if (target->offsets != NULL) {
|
|
|
|
if (source->offsets != NULL)
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(target->offsets, source->offsets,
|
|
|
|
source->labels);
|
2000-03-30 00:57:06 +00:00
|
|
|
else
|
2000-06-01 18:26:56 +00:00
|
|
|
set_offsets(target, target->offsets, NULL);
|
2000-03-30 00:57:06 +00:00
|
|
|
}
|
|
|
|
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
2000-03-30 00:57:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_name_dupwithoffsets(const dns_name_t *source, isc_mem_t *mctx,
|
2000-03-30 00:57:06 +00:00
|
|
|
dns_name_t *target)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Make 'target' a read-only dynamically allocated copy of 'source'.
|
|
|
|
* 'target' will also have a dynamically allocated offsets table.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(source));
|
|
|
|
REQUIRE(source->length > 0);
|
|
|
|
REQUIRE(VALID_NAME(target));
|
|
|
|
REQUIRE(BINDABLE(target));
|
|
|
|
REQUIRE(target->offsets == NULL);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make 'target' empty in case of failure.
|
|
|
|
*/
|
|
|
|
MAKE_EMPTY(target);
|
|
|
|
|
|
|
|
target->ndata = isc_mem_get(mctx, source->length + source->labels);
|
|
|
|
if (target->ndata == NULL)
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOMEMORY);
|
2000-03-30 00:57:06 +00:00
|
|
|
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(target->ndata, source->ndata, source->length);
|
2000-03-30 00:57:06 +00:00
|
|
|
|
|
|
|
target->length = source->length;
|
|
|
|
target->labels = source->labels;
|
|
|
|
target->attributes = DNS_NAMEATTR_DYNAMIC | DNS_NAMEATTR_DYNOFFSETS |
|
|
|
|
DNS_NAMEATTR_READONLY;
|
|
|
|
if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
|
|
|
|
target->attributes |= DNS_NAMEATTR_ABSOLUTE;
|
|
|
|
target->offsets = target->ndata + source->length;
|
|
|
|
if (source->offsets != NULL)
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(target->offsets, source->offsets, source->labels);
|
2000-03-30 00:57:06 +00:00
|
|
|
else
|
2000-06-01 18:26:56 +00:00
|
|
|
set_offsets(target, target->offsets, NULL);
|
1999-06-12 01:08:16 +00:00
|
|
|
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
1999-06-12 01:08:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
dns_name_free(dns_name_t *name, isc_mem_t *mctx) {
|
2000-03-30 00:57:06 +00:00
|
|
|
size_t size;
|
|
|
|
|
1999-06-12 01:08:16 +00:00
|
|
|
/*
|
|
|
|
* Free 'name'.
|
|
|
|
*/
|
|
|
|
|
1999-08-31 22:09:52 +00:00
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
REQUIRE((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0);
|
|
|
|
|
2000-03-30 00:57:06 +00:00
|
|
|
size = name->length;
|
|
|
|
if ((name->attributes & DNS_NAMEATTR_DYNOFFSETS) != 0)
|
|
|
|
size += name->labels;
|
|
|
|
isc_mem_put(mctx, name->ndata, size);
|
1999-06-12 01:08:16 +00:00
|
|
|
dns_name_invalidate(name);
|
|
|
|
}
|
1999-08-31 22:09:52 +00:00
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_name_digest(const dns_name_t *name, dns_digestfunc_t digest, void *arg) {
|
1999-08-31 22:09:52 +00:00
|
|
|
dns_name_t downname;
|
|
|
|
unsigned char data[256];
|
|
|
|
isc_buffer_t buffer;
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t result;
|
1999-08-31 22:09:52 +00:00
|
|
|
isc_region_t r;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Send 'name' in DNSSEC canonical form to 'digest'.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
REQUIRE(digest != NULL);
|
|
|
|
|
2012-12-01 21:32:31 +11:00
|
|
|
#if defined(__clang__) && \
|
2012-12-03 07:58:01 +11:00
|
|
|
( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
|
2012-12-01 21:32:31 +11:00
|
|
|
memset(&downname, 0, sizeof(downname));
|
|
|
|
#endif
|
2001-01-03 00:05:15 +00:00
|
|
|
DNS_NAME_INIT(&downname, NULL);
|
2012-10-06 14:20:45 +10:00
|
|
|
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_init(&buffer, data, sizeof(data));
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-08-31 22:09:52 +00:00
|
|
|
result = dns_name_downcase(name, &downname, &buffer);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
1999-08-31 22:09:52 +00:00
|
|
|
return (result);
|
2000-08-01 01:33:37 +00:00
|
|
|
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(&buffer, &r);
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-08-31 22:09:52 +00:00
|
|
|
return ((digest)(arg, &r));
|
|
|
|
}
|
1999-10-13 22:45:17 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_name_dynamic(const dns_name_t *name) {
|
1999-10-13 22:45:17 +00:00
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
|
1999-10-17 19:22:50 +00:00
|
|
|
/*
|
|
|
|
* Returns whether there is dynamic memory associated with this name.
|
|
|
|
*/
|
|
|
|
|
1999-10-13 22:45:17 +00:00
|
|
|
return ((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0 ?
|
2018-04-17 08:29:14 -07:00
|
|
|
true : false);
|
1999-10-13 22:45:17 +00:00
|
|
|
}
|
1999-10-17 19:22:50 +00:00
|
|
|
|
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_name_print(const dns_name_t *name, FILE *stream) {
|
1999-10-17 19:22:50 +00:00
|
|
|
isc_result_t result;
|
|
|
|
isc_buffer_t b;
|
|
|
|
isc_region_t r;
|
|
|
|
char t[1024];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Print 'name' on 'stream'.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_init(&b, t, sizeof(t));
|
2018-04-17 08:29:14 -07:00
|
|
|
result = dns_name_totext(name, false, &b);
|
1999-10-17 19:22:50 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
return (result);
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(&b, &r);
|
1999-10-17 19:22:50 +00:00
|
|
|
fprintf(stream, "%.*s", (int)r.length, (char *)r.base);
|
|
|
|
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
2000-04-11 19:11:46 +00:00
|
|
|
|
2005-09-09 06:17:03 +00:00
|
|
|
isc_result_t
|
|
|
|
dns_name_settotextfilter(dns_name_totextfilter_t proc) {
|
|
|
|
isc_result_t result;
|
2005-09-10 01:02:08 +00:00
|
|
|
dns_name_totextfilter_t *mem;
|
2005-09-18 07:16:24 +00:00
|
|
|
int res;
|
2005-09-09 06:17:03 +00:00
|
|
|
|
2005-09-18 07:16:24 +00:00
|
|
|
result = totext_filter_proc_key_init();
|
2005-09-09 06:17:03 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
return (result);
|
2005-09-10 01:02:08 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If we already have been here set / clear as appropriate.
|
|
|
|
* Otherwise allocate memory.
|
|
|
|
*/
|
2005-09-18 07:16:24 +00:00
|
|
|
mem = isc_thread_key_getspecific(totext_filter_proc_key);
|
2005-09-10 01:02:08 +00:00
|
|
|
if (mem != NULL && proc != NULL) {
|
|
|
|
*mem = proc;
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
if (proc == NULL) {
|
2016-10-28 12:05:19 +11:00
|
|
|
if (mem != NULL)
|
|
|
|
isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
|
2005-09-18 07:16:24 +00:00
|
|
|
res = isc_thread_key_setspecific(totext_filter_proc_key, NULL);
|
|
|
|
if (res != 0)
|
2005-09-10 01:02:08 +00:00
|
|
|
result = ISC_R_UNEXPECTED;
|
|
|
|
return (result);
|
|
|
|
}
|
2008-04-01 23:47:10 +00:00
|
|
|
|
2005-09-18 07:16:24 +00:00
|
|
|
mem = isc_mem_get(thread_key_mctx, sizeof(*mem));
|
2005-09-10 01:02:08 +00:00
|
|
|
if (mem == NULL)
|
|
|
|
return (ISC_R_NOMEMORY);
|
|
|
|
*mem = proc;
|
2005-09-18 07:16:24 +00:00
|
|
|
if (isc_thread_key_setspecific(totext_filter_proc_key, mem) != 0) {
|
|
|
|
isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
|
2005-09-09 06:17:03 +00:00
|
|
|
result = ISC_R_UNEXPECTED;
|
2005-09-18 07:16:24 +00:00
|
|
|
}
|
2005-09-09 06:17:03 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2000-04-11 19:11:46 +00:00
|
|
|
void
|
2015-02-27 15:08:38 +11:00
|
|
|
dns_name_format(const dns_name_t *name, char *cp, unsigned int size) {
|
2000-04-11 19:11:46 +00:00
|
|
|
isc_result_t result;
|
|
|
|
isc_buffer_t buf;
|
|
|
|
|
|
|
|
REQUIRE(size > 0);
|
2000-08-01 01:33:37 +00:00
|
|
|
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
/*
|
|
|
|
* Leave room for null termination after buffer.
|
|
|
|
*/
|
|
|
|
isc_buffer_init(&buf, cp, size - 1);
|
2018-04-17 08:29:14 -07:00
|
|
|
result = dns_name_totext(name, true, &buf);
|
2000-04-11 19:11:46 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
/*
|
|
|
|
* Null terminate.
|
|
|
|
*/
|
2000-04-11 19:11:46 +00:00
|
|
|
isc_region_t r;
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(&buf, &r);
|
2000-04-11 19:11:46 +00:00
|
|
|
((char *) r.base)[r.length] = '\0';
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
|
|
|
|
} else
|
2000-04-11 19:11:46 +00:00
|
|
|
snprintf(cp, size, "<unknown>");
|
|
|
|
}
|
2001-01-03 00:05:15 +00:00
|
|
|
|
2009-03-11 07:02:34 +00:00
|
|
|
/*
|
|
|
|
* dns_name_tostring() -- similar to dns_name_format() but allocates its own
|
|
|
|
* memory.
|
|
|
|
*/
|
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_name_tostring(const dns_name_t *name, char **target, isc_mem_t *mctx) {
|
2009-03-11 07:02:34 +00:00
|
|
|
isc_result_t result;
|
|
|
|
isc_buffer_t buf;
|
|
|
|
isc_region_t reg;
|
|
|
|
char *p, txt[DNS_NAME_FORMATSIZE];
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
2009-03-11 23:47:35 +00:00
|
|
|
REQUIRE(target != NULL && *target == NULL);
|
2009-03-11 07:02:34 +00:00
|
|
|
|
|
|
|
isc_buffer_init(&buf, txt, sizeof(txt));
|
2018-04-17 08:29:14 -07:00
|
|
|
result = dns_name_totext(name, false, &buf);
|
2009-03-11 07:02:34 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
return (result);
|
|
|
|
|
|
|
|
isc_buffer_usedregion(&buf, ®);
|
|
|
|
p = isc_mem_allocate(mctx, reg.length + 1);
|
2015-04-29 03:16:50 +10:00
|
|
|
if (p == NULL)
|
|
|
|
return (ISC_R_NOMEMORY);
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(p, (char *) reg.base, (int) reg.length);
|
2009-03-11 07:02:34 +00:00
|
|
|
p[reg.length] = '\0';
|
|
|
|
|
|
|
|
*target = p;
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* dns_name_fromstring() -- convert directly from a string to a name,
|
|
|
|
* allocating memory as needed
|
|
|
|
*/
|
|
|
|
isc_result_t
|
2009-09-01 17:36:51 +00:00
|
|
|
dns_name_fromstring(dns_name_t *target, const char *src, unsigned int options,
|
|
|
|
isc_mem_t *mctx)
|
2011-01-13 01:59:28 +00:00
|
|
|
{
|
|
|
|
return (dns_name_fromstring2(target, src, dns_rootname, options, mctx));
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
dns_name_fromstring2(dns_name_t *target, const char *src,
|
|
|
|
const dns_name_t *origin, unsigned int options,
|
2011-01-13 04:59:26 +00:00
|
|
|
isc_mem_t *mctx)
|
2009-09-01 17:36:51 +00:00
|
|
|
{
|
2009-03-11 07:02:34 +00:00
|
|
|
isc_result_t result;
|
|
|
|
isc_buffer_t buf;
|
|
|
|
dns_fixedname_t fn;
|
|
|
|
dns_name_t *name;
|
|
|
|
|
2009-09-01 17:36:51 +00:00
|
|
|
REQUIRE(src != NULL);
|
|
|
|
|
2012-12-08 12:48:57 +11:00
|
|
|
isc_buffer_constinit(&buf, src, strlen(src));
|
2009-03-11 07:02:34 +00:00
|
|
|
isc_buffer_add(&buf, strlen(src));
|
2011-01-13 01:59:28 +00:00
|
|
|
if (BINDABLE(target) && target->buffer != NULL)
|
|
|
|
name = target;
|
|
|
|
else {
|
2018-03-28 14:38:09 +02:00
|
|
|
name = dns_fixedname_initname(&fn);
|
2011-01-13 01:59:28 +00:00
|
|
|
}
|
2009-03-11 07:02:34 +00:00
|
|
|
|
2011-01-13 01:59:28 +00:00
|
|
|
result = dns_name_fromtext(name, &buf, origin, options, NULL);
|
2009-03-11 07:02:34 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
return (result);
|
|
|
|
|
2011-01-13 01:59:28 +00:00
|
|
|
if (name != target)
|
|
|
|
result = dns_name_dupwithoffsets(name, mctx, target);
|
2009-03-11 07:02:34 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2001-01-03 00:05:15 +00:00
|
|
|
isc_result_t
|
2015-02-27 15:08:38 +11:00
|
|
|
dns_name_copy(const dns_name_t *source, dns_name_t *dest, isc_buffer_t *target) {
|
2001-12-28 20:59:27 +00:00
|
|
|
unsigned char *ndata;
|
2001-01-03 00:05:15 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Make dest a copy of source.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(source));
|
|
|
|
REQUIRE(VALID_NAME(dest));
|
|
|
|
REQUIRE(target != NULL || dest->buffer != NULL);
|
|
|
|
|
|
|
|
if (target == NULL) {
|
|
|
|
target = dest->buffer;
|
|
|
|
isc_buffer_clear(dest->buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
REQUIRE(BINDABLE(dest));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set up.
|
|
|
|
*/
|
|
|
|
if (target->length - target->used < source->length)
|
|
|
|
return (ISC_R_NOSPACE);
|
|
|
|
|
|
|
|
ndata = (unsigned char *)target->base + target->used;
|
|
|
|
dest->ndata = target->base;
|
|
|
|
|
2017-12-06 21:00:14 +11:00
|
|
|
if (source->length != 0)
|
|
|
|
memmove(ndata, source->ndata, source->length);
|
2001-01-03 00:05:15 +00:00
|
|
|
|
|
|
|
dest->ndata = ndata;
|
|
|
|
dest->labels = source->labels;
|
|
|
|
dest->length = source->length;
|
|
|
|
if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
|
|
|
|
dest->attributes = DNS_NAMEATTR_ABSOLUTE;
|
|
|
|
else
|
|
|
|
dest->attributes = 0;
|
|
|
|
|
|
|
|
if (dest->labels > 0 && dest->offsets != NULL) {
|
2001-12-28 20:59:27 +00:00
|
|
|
if (source->offsets != NULL)
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(dest->offsets, source->offsets, source->labels);
|
2001-12-28 20:59:27 +00:00
|
|
|
else
|
|
|
|
set_offsets(dest, dest->offsets, NULL);
|
2001-01-03 00:05:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
isc_buffer_add(target, dest->length);
|
|
|
|
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2005-09-18 07:16:24 +00:00
|
|
|
void
|
|
|
|
dns_name_destroy(void) {
|
|
|
|
RUNTIME_CHECK(isc_once_do(&once, thread_key_mutex_init)
|
|
|
|
== ISC_R_SUCCESS);
|
|
|
|
|
|
|
|
LOCK(&thread_key_mutex);
|
|
|
|
if (thread_key_initialized) {
|
|
|
|
isc_mem_detach(&thread_key_mctx);
|
|
|
|
isc_thread_key_delete(totext_filter_proc_key);
|
|
|
|
thread_key_initialized = 0;
|
|
|
|
}
|
|
|
|
UNLOCK(&thread_key_mutex);
|
|
|
|
|
|
|
|
}
|
2015-08-25 14:46:06 +10:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Service Discovery Prefixes RFC 6763.
|
|
|
|
*/
|
|
|
|
static unsigned char b_dns_sd_udp_data[] = "\001b\007_dns-sd\004_udp";
|
|
|
|
static unsigned char b_dns_sd_udp_offsets[] = { 0, 2, 10 };
|
|
|
|
static unsigned char db_dns_sd_udp_data[] = "\002db\007_dns-sd\004_udp";
|
|
|
|
static unsigned char db_dns_sd_udp_offsets[] = { 0, 3, 11 };
|
|
|
|
static unsigned char r_dns_sd_udp_data[] = "\001r\007_dns-sd\004_udp";
|
|
|
|
static unsigned char r_dns_sd_udp_offsets[] = { 0, 2, 10 };
|
|
|
|
static unsigned char dr_dns_sd_udp_data[] = "\002dr\007_dns-sd\004_udp";
|
|
|
|
static unsigned char dr_dns_sd_udp_offsets[] = { 0, 3, 11 };
|
|
|
|
static unsigned char lb_dns_sd_udp_data[] = "\002lb\007_dns-sd\004_udp";
|
|
|
|
static unsigned char lb_dns_sd_udp_offsets[] = { 0, 3, 11 };
|
|
|
|
|
2017-11-13 16:58:12 +11:00
|
|
|
static dns_name_t const dns_sd[] = {
|
2017-11-14 14:48:41 +11:00
|
|
|
DNS_NAME_INITNONABSOLUTE(b_dns_sd_udp_data, b_dns_sd_udp_offsets),
|
2017-11-13 16:58:12 +11:00
|
|
|
DNS_NAME_INITNONABSOLUTE(db_dns_sd_udp_data, db_dns_sd_udp_offsets),
|
|
|
|
DNS_NAME_INITNONABSOLUTE(r_dns_sd_udp_data, r_dns_sd_udp_offsets),
|
|
|
|
DNS_NAME_INITNONABSOLUTE(dr_dns_sd_udp_data, dr_dns_sd_udp_offsets),
|
|
|
|
DNS_NAME_INITNONABSOLUTE(lb_dns_sd_udp_data, lb_dns_sd_udp_offsets)
|
2015-08-25 14:46:06 +10:00
|
|
|
};
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2015-08-25 14:46:06 +10:00
|
|
|
dns_name_isdnssd(const dns_name_t *name) {
|
|
|
|
size_t i;
|
|
|
|
dns_name_t prefix;
|
|
|
|
|
|
|
|
if (dns_name_countlabels(name) > 3U) {
|
|
|
|
dns_name_init(&prefix, NULL);
|
|
|
|
dns_name_getlabelsequence(name, 0, 3, &prefix);
|
|
|
|
for (i = 0; i < (sizeof(dns_sd)/sizeof(dns_sd[0])); i++)
|
|
|
|
if (dns_name_equal(&prefix, &dns_sd[i]))
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
2015-08-25 14:46:06 +10:00
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2015-08-25 14:46:06 +10:00
|
|
|
}
|
2016-03-08 10:11:23 +11:00
|
|
|
|
|
|
|
static unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 };
|
|
|
|
static unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 };
|
|
|
|
static unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 };
|
|
|
|
|
|
|
|
static unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA";
|
|
|
|
|
|
|
|
static unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA";
|
|
|
|
|
|
|
|
static unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA";
|
|
|
|
|
|
|
|
static dns_name_t const rfc1918names[] = {
|
2017-11-13 16:58:12 +11:00
|
|
|
DNS_NAME_INITABSOLUTE(inaddr10, inaddr10_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr16172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr17172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr18172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr19172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr20172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr21172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr22172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr23172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr24172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr25172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr26172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr27172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr28172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr29172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr30172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr31172, inaddr172_offsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(inaddr168192, inaddr192_offsets)
|
2016-03-08 10:11:23 +11:00
|
|
|
};
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2016-03-08 10:11:23 +11:00
|
|
|
dns_name_isrfc1918(const dns_name_t *name) {
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i = 0; i < (sizeof(rfc1918names)/sizeof(*rfc1918names)); i++)
|
|
|
|
if (dns_name_issubdomain(name, &rfc1918names[i]))
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
|
|
|
return (false);
|
2016-03-08 10:11:23 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned char ulaoffsets[] = { 0, 2, 4, 8, 13 };
|
|
|
|
static unsigned char ip6fc[] = "\001c\001f\003ip6\004ARPA";
|
|
|
|
static unsigned char ip6fd[] = "\001d\001f\003ip6\004ARPA";
|
|
|
|
|
|
|
|
static dns_name_t const ulanames[] = {
|
2017-11-13 16:58:12 +11:00
|
|
|
DNS_NAME_INITABSOLUTE(ip6fc, ulaoffsets),
|
|
|
|
DNS_NAME_INITABSOLUTE(ip6fd, ulaoffsets)
|
2016-03-08 10:11:23 +11:00
|
|
|
};
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2016-03-08 10:11:23 +11:00
|
|
|
dns_name_isula(const dns_name_t *name) {
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i = 0; i < (sizeof(ulanames)/sizeof(*ulanames)); i++)
|
|
|
|
if (dns_name_issubdomain(name, &ulanames[i]))
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
|
|
|
return (false);
|
2016-03-08 10:11:23 +11:00
|
|
|
}
|
2017-09-28 16:40:45 +10:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Use a simple table as we don't want all the locale stuff
|
|
|
|
* associated with ishexdigit().
|
|
|
|
*/
|
|
|
|
const char
|
|
|
|
ishex[256] = {
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
|
|
};
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2017-09-28 16:40:45 +10:00
|
|
|
dns_name_istat(const dns_name_t *name) {
|
|
|
|
unsigned char len;
|
|
|
|
const unsigned char *ndata;
|
|
|
|
|
|
|
|
REQUIRE(VALID_NAME(name));
|
|
|
|
|
|
|
|
if (name->labels < 1)
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2017-09-28 16:40:45 +10:00
|
|
|
|
|
|
|
ndata = name->ndata;
|
|
|
|
len = ndata[0];
|
|
|
|
INSIST(len <= name->length);
|
|
|
|
ndata++;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Is there at least one trust anchor reported and is the
|
2018-07-04 10:19:53 +10:00
|
|
|
* label length consistent with a trust-anchor-telemetry label.
|
2017-09-28 16:40:45 +10:00
|
|
|
*/
|
|
|
|
if ((len < 8) || (len - 3) % 5 != 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2017-09-28 16:40:45 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ndata[0] != '_' ||
|
|
|
|
maptolower[ndata[1]] != 't' ||
|
|
|
|
maptolower[ndata[2]] != 'a') {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2017-09-28 16:40:45 +10:00
|
|
|
}
|
|
|
|
ndata += 3;
|
|
|
|
len -= 3;
|
|
|
|
|
|
|
|
while (len > 0) {
|
|
|
|
INSIST(len >= 5);
|
|
|
|
if (ndata[0] != '-' || !ishex[ndata[1]] || !ishex[ndata[2]] ||
|
|
|
|
!ishex[ndata[3]] || !ishex[ndata[4]]) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2017-09-28 16:40:45 +10:00
|
|
|
}
|
|
|
|
ndata += 5;
|
|
|
|
len -= 5;
|
|
|
|
}
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
2017-09-28 16:40:45 +10:00
|
|
|
}
|