]> git.saurik.com Git - apple/libresolv.git/blob - dns_async.c
libresolv-65.tar.gz
[apple/libresolv.git] / dns_async.c
1 /*
2 * Copyright (c) 2003 - 2008 Apple, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include <mach/mach.h>
28 #include <pthread.h>
29 #include <netdb.h>
30 #include <netdb_async.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #include <dns.h>
34 #include <dns_util.h>
35 #include <stdarg.h>
36 #include <si_module.h>
37
38 extern void *LI_ils_create(char *fmt, ...);
39
40 /*
41 typedef void (*dns_async_callback)(int32_t status, char *buf, uint32_t len, struct sockaddr *from, int fromlen, void *context);
42 */
43
44 typedef struct
45 {
46 void *orig_callback;
47 void *orig_context;
48 si_mod_t *dns;
49 } _dns_context_t;
50
51 static void
52 _dns_callback(si_item_t *item, uint32_t status, void *ctx)
53 {
54 _dns_context_t *my_ctx;
55 si_dnspacket_t *res;
56 char *packet;
57 struct sockaddr *from;
58 uint32_t pl;
59 int fl;
60
61 if (ctx == NULL) return;
62
63 my_ctx = (_dns_context_t *)ctx;
64 if (my_ctx->orig_callback == NULL)
65 {
66 si_item_release(item);
67 si_module_release(my_ctx->dns);
68 free(my_ctx);
69 return;
70 }
71
72 if (status >= SI_STATUS_INTERNAL) status = NO_RECOVERY;
73
74 packet = NULL;
75 pl = 0;
76 from = NULL;
77 fl = 0;
78
79 res = NULL;
80 if (item != NULL) res = (si_dnspacket_t *)((char *)item + sizeof(si_item_t));
81
82 if ((res != NULL) && (res->dns_packet_len > 0))
83 {
84 packet = malloc(res->dns_packet_len);
85 if (packet == NULL) status = NO_RECOVERY;
86 else
87 {
88 pl = res->dns_packet_len;
89 memcpy(packet, res->dns_packet, res->dns_packet_len);
90
91 if (res->dns_server_len > 0)
92 {
93 from = malloc(res->dns_server_len);
94 if (from == NULL)
95 {
96 status = NO_RECOVERY;
97 free(packet);
98 packet = NULL;
99 pl = 0;
100 }
101 else
102 {
103 fl = res->dns_server_len;
104 memcpy(from, res->dns_server, res->dns_server_len);
105 }
106 }
107 }
108 }
109
110 si_item_release(item);
111
112 ((dns_async_callback)(my_ctx->orig_callback))(status, packet, pl, from, fl, my_ctx->orig_context);
113
114 si_module_release(my_ctx->dns);
115 free(my_ctx);
116 }
117
118 int32_t
119 dns_async_start(mach_port_t *p, const char *name, uint16_t dnsclass, uint16_t dnstype, uint32_t do_search, dns_async_callback callback, void *context)
120 {
121 si_mod_t *dns;
122 int call;
123 uint32_t c, t;
124 _dns_context_t *my_ctx;
125
126 *p = MACH_PORT_NULL;
127
128 if (name == NULL) return NO_RECOVERY;
129
130 dns = si_module_with_name("mdns");
131 if (dns == NULL) return NO_RECOVERY;
132
133 my_ctx = (_dns_context_t *)calloc(1, sizeof(_dns_context_t));
134 if (my_ctx == NULL)
135 {
136 si_module_release(dns);
137 return NO_RECOVERY;
138 }
139
140 my_ctx->orig_callback = callback;
141 my_ctx->orig_context = context;
142 my_ctx->dns = dns;
143
144 call = SI_CALL_DNS_QUERY;
145 if (do_search != 0) call = SI_CALL_DNS_SEARCH;
146
147 c = dnsclass;
148 t = dnstype;
149
150 *p = si_async_call(dns, call, name, NULL, NULL, c, t, 0, 0, (void *)_dns_callback, (void *)my_ctx);
151 if (*p == MACH_PORT_NULL)
152 {
153 free(my_ctx);
154 si_module_release(dns);
155 return NO_RECOVERY;
156 }
157
158 return 0;
159 }
160
161 void
162 dns_async_cancel(mach_port_t p)
163 {
164 si_async_cancel(p);
165 }
166
167 int32_t
168 dns_async_send(mach_port_t *p, const char *name, uint16_t dnsclass, uint16_t dnstype, uint32_t do_search)
169 {
170 return dns_async_start(p, name, dnsclass, dnstype, do_search, NULL, NULL);
171 }
172
173 /* unsupported */
174 int32_t
175 dns_async_receive(mach_port_t p, char **buf, uint32_t *len, struct sockaddr **from, uint32_t *fromlen)
176 {
177 return 0;
178 }
179
180 int32_t
181 dns_async_handle_reply(void *msg)
182 {
183 si_async_handle_reply(msg);
184 return 0;
185 }