2 * Copyright (c) 2004, 2006 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 #include <mach/mach.h>
27 #include <mach/mach_error.h>
29 #include "dnsinfo_create.h"
30 #include "dnsinfo_private.h"
31 #include "shared_dns_info.h"
34 #define ROUNDUP(a, size) \
35 (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
39 * to avoid extra calls to realloc() we want to pre-allocate the initial
40 * resolver and configuration buffers of a sufficient size that they would
41 * not normally need to be expanded.
43 #define INITIAL_CONFIGURATION_BUF_SIZE 8192
44 #define INITIAL_RESOLVER_BUF_SIZE 1024
48 * DNS [configuration] buffer functions
54 _dns_configuration_create()
56 _dns_config_buf_t
*config
;
58 config
= calloc(1, INITIAL_CONFIGURATION_BUF_SIZE
);
59 // config->n_attribute = 0;
60 // config->n_padding = 0;
61 return (dns_create_config_t
)config
;
66 config_add_attribute(dns_create_config_t
*_config
,
67 uint32_t attribute_type
,
68 uint32_t attribute_length
,
70 uint32_t extra_padding
)
72 _dns_config_buf_t
*config
= (_dns_config_buf_t
*)*_config
;
73 dns_attribute_t
*header
;
78 uint32_t rounded_length
;
82 oldLen
= ntohl(config
->n_attribute
);
83 rounded_length
= ROUNDUP(attribute_length
, sizeof(uint32_t));
84 newLen
= sizeof(dns_attribute_t
) + rounded_length
;
85 newSize
= sizeof(_dns_config_buf_t
) + oldLen
+ newLen
;
86 if (newSize
> INITIAL_CONFIGURATION_BUF_SIZE
) {
87 config
= realloc(config
, newSize
);
89 config
->n_attribute
= htonl(ntohl(config
->n_attribute
) + newLen
);
91 // increment additional padding that will be needed (later)
92 config
->n_padding
= htonl(ntohl(config
->n_padding
) + extra_padding
);
94 // add attribute [header]
96 header
= (dns_attribute_t
*)&config
->attribute
[oldLen
];
97 header
->type
= htonl(attribute_type
);
98 header
->length
= htonl(newLen
);
100 // add attribute [data]
102 bcopy(attribute
, &header
->attribute
[0], attribute_length
);
103 for (i
= attribute_length
; i
< rounded_length
; i
++) {
104 header
->attribute
[i
] = 0;
107 *_config
= (dns_create_config_t
)config
;
114 _dns_configuration_add_resolver(dns_create_config_t
*_config
,
115 dns_create_resolver_t _resolver
)
117 _dns_config_buf_t
*config
= (_dns_config_buf_t
*)*_config
;
118 uint32_t padding
= 0;
119 _dns_resolver_buf_t
*resolver
= (_dns_resolver_buf_t
*)_resolver
;
122 * compute the amount of space that will be needed for
123 * pointers to the resolver, the nameservers, the search
124 * list, and the sortaddr list.
126 padding
+= sizeof(DNS_PTR(dns_resolver_t
*, x
));
127 if (resolver
->resolver
.n_nameserver
!= 0) {
128 padding
+= ntohl(resolver
->resolver
.n_nameserver
) * sizeof(DNS_PTR(struct sockaddr
*, x
));
130 if (resolver
->resolver
.n_search
!= 0) {
131 padding
+= ntohl(resolver
->resolver
.n_search
) * sizeof(DNS_PTR(char *, x
));
133 if (resolver
->resolver
.n_sortaddr
!= 0) {
134 padding
+= ntohl(resolver
->resolver
.n_sortaddr
) * sizeof(DNS_PTR(dns_sortaddr_t
*, x
));
137 config
->config
.n_resolver
= htonl(ntohl(config
->config
.n_resolver
) + 1);
139 config_add_attribute(_config
,
140 CONFIG_ATTRIBUTE_RESOLVER
,
141 sizeof(_dns_resolver_buf_t
) + ntohl(resolver
->n_attribute
),
151 _dns_configuration_store(dns_create_config_t
*_config
)
153 dnsDataOut_t dataRef
= NULL
;
154 mach_msg_type_number_t dataLen
= 0;
156 kern_return_t status
;
158 server
= _dns_configuration_server_port();
159 if (server
== MACH_PORT_NULL
) {
163 if (_config
!= NULL
) {
164 _dns_config_buf_t
*config
= (_dns_config_buf_t
*)*_config
;
166 if (config
!= NULL
) {
167 dataRef
= (dnsDataOut_t
)config
;
168 dataLen
= sizeof(_dns_config_buf_t
) + ntohl(config
->n_attribute
);
172 status
= shared_dns_infoSet(server
, dataRef
, dataLen
);
173 (void) mach_port_deallocate(mach_task_self(), server
);
174 if (status
!= KERN_SUCCESS
) {
175 mach_error("shared_dns_infoSet():", status
);
185 _dns_configuration_free(dns_create_config_t
*_config
)
187 _dns_config_buf_t
*config
= (_dns_config_buf_t
*)*_config
;
196 * DNS resolver configuration functions
200 dns_create_resolver_t
201 _dns_resolver_create()
203 _dns_resolver_buf_t
*buf
;
205 buf
= calloc(1, INITIAL_RESOLVER_BUF_SIZE
);
206 // buf->n_attribute = 0;
207 return (dns_create_resolver_t
)buf
;
212 _dns_resolver_add_attribute(dns_create_resolver_t
*_resolver
,
213 uint32_t attribute_type
,
214 uint32_t attribute_length
,
217 dns_attribute_t
*header
;
222 _dns_resolver_buf_t
*resolver
= (_dns_resolver_buf_t
*)*_resolver
;
223 uint32_t rounded_length
;
227 oldLen
= ntohl(resolver
->n_attribute
);
228 rounded_length
= ROUNDUP(attribute_length
, sizeof(uint32_t));
229 newLen
= sizeof(dns_attribute_t
) + rounded_length
;
230 newSize
= sizeof(_dns_resolver_buf_t
) + oldLen
+ newLen
;
231 if (newSize
> INITIAL_RESOLVER_BUF_SIZE
) {
232 resolver
= realloc(resolver
, newSize
);
234 resolver
->n_attribute
= htonl(ntohl(resolver
->n_attribute
) + newLen
);
236 // add attribute [header]
238 header
= (dns_attribute_t
*)&resolver
->attribute
[oldLen
];
239 header
->type
= htonl(attribute_type
);
240 header
->length
= htonl(newLen
);
242 // add attribute [data]
244 bcopy(attribute
, &header
->attribute
[0], attribute_length
);
245 for (i
= attribute_length
; i
< rounded_length
; i
++) {
246 header
->attribute
[i
] = 0;
249 *_resolver
= (dns_create_resolver_t
)resolver
;
256 _dns_resolver_set_domain(dns_create_resolver_t
*_resolver
, const char *domain
)
258 _dns_resolver_add_attribute(_resolver
, RESOLVER_ATTRIBUTE_DOMAIN
, strlen(domain
) + 1, (void *)domain
);
265 _dns_resolver_add_nameserver(dns_create_resolver_t
*_resolver
, struct sockaddr
*nameserver
)
267 _dns_resolver_buf_t
*resolver
= (_dns_resolver_buf_t
*)*_resolver
;
269 resolver
->resolver
.n_nameserver
= htonl(ntohl(resolver
->resolver
.n_nameserver
) + 1);
270 _dns_resolver_add_attribute(_resolver
, RESOLVER_ATTRIBUTE_ADDRESS
, nameserver
->sa_len
, (void *)nameserver
);
277 _dns_resolver_set_port(dns_create_resolver_t
*_resolver
, uint16_t port
)
279 _dns_resolver_buf_t
*resolver
= (_dns_resolver_buf_t
*)*_resolver
;
281 resolver
->resolver
.port
= htons(port
);
288 _dns_resolver_add_search(dns_create_resolver_t
*_resolver
, const char *search
)
290 _dns_resolver_buf_t
*resolver
= (_dns_resolver_buf_t
*)*_resolver
;
292 resolver
->resolver
.n_search
= htonl(ntohl(resolver
->resolver
.n_search
) + 1);
293 _dns_resolver_add_attribute(_resolver
, RESOLVER_ATTRIBUTE_SEARCH
, strlen(search
) + 1, (void *)search
);
300 _dns_resolver_add_sortaddr(dns_create_resolver_t
*_resolver
, dns_sortaddr_t
*sortaddr
)
302 _dns_resolver_buf_t
*resolver
= (_dns_resolver_buf_t
*)*_resolver
;
304 resolver
->resolver
.n_sortaddr
= htonl(ntohl(resolver
->resolver
.n_sortaddr
) + 1);
305 _dns_resolver_add_attribute(_resolver
, RESOLVER_ATTRIBUTE_SORTADDR
, sizeof(dns_sortaddr_t
), (void *)sortaddr
);
312 _dns_resolver_set_options(dns_create_resolver_t
*_resolver
, const char *options
)
314 _dns_resolver_add_attribute(_resolver
, RESOLVER_ATTRIBUTE_OPTIONS
, strlen(options
) + 1, (void *)options
);
321 _dns_resolver_set_timeout(dns_create_resolver_t
*_resolver
, uint32_t timeout
)
323 _dns_resolver_buf_t
*resolver
= (_dns_resolver_buf_t
*)*_resolver
;
325 resolver
->resolver
.timeout
= htonl(timeout
);
332 _dns_resolver_set_order(dns_create_resolver_t
*_resolver
, uint32_t order
)
334 _dns_resolver_buf_t
*resolver
= (_dns_resolver_buf_t
*)*_resolver
;
336 resolver
->resolver
.search_order
= htonl(order
);
343 _dns_resolver_free(dns_create_resolver_t
*_resolver
)
345 _dns_resolver_buf_t
*resolver
= (_dns_resolver_buf_t
*)*_resolver
;