]>
Commit | Line | Data |
---|---|---|
c1b412f1 DB |
1 | /* |
2 | * QEMU DNS resolver | |
3 | * | |
4 | * Copyright (c) 2016-2017 Red Hat, Inc. | |
5 | * | |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2 of the License, or (at your option) any later version. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public | |
17 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. | |
18 | * | |
19 | */ | |
20 | ||
21 | #ifndef QIO_DNS_RESOLVER_H | |
22 | #define QIO_DNS_RESOLVER_H | |
23 | ||
9af23989 | 24 | #include "qapi/qapi-types-sockets.h" |
c1b412f1 DB |
25 | #include "qom/object.h" |
26 | #include "io/task.h" | |
27 | ||
28 | #define TYPE_QIO_DNS_RESOLVER "qio-dns-resolver" | |
29 | #define QIO_DNS_RESOLVER(obj) \ | |
30 | OBJECT_CHECK(QIODNSResolver, (obj), TYPE_QIO_DNS_RESOLVER) | |
31 | #define QIO_DNS_RESOLVER_CLASS(klass) \ | |
32 | OBJECT_CLASS_CHECK(QIODNSResolverClass, klass, TYPE_QIO_DNS_RESOLVER) | |
33 | #define QIO_DNS_RESOLVER_GET_CLASS(obj) \ | |
34 | OBJECT_GET_CLASS(QIODNSResolverClass, obj, TYPE_QIO_DNS_RESOLVER) | |
35 | ||
36 | typedef struct QIODNSResolver QIODNSResolver; | |
37 | typedef struct QIODNSResolverClass QIODNSResolverClass; | |
38 | ||
39 | /** | |
40 | * QIODNSResolver: | |
41 | * | |
42 | * The QIODNSResolver class provides a framework for doing | |
43 | * DNS resolution on SocketAddress objects, independently | |
44 | * of socket creation. | |
45 | * | |
46 | * <example> | |
47 | * <title>Resolving addresses synchronously</title> | |
48 | * <programlisting> | |
49 | * int mylisten(SocketAddress *addr, Error **errp) { | |
50 | * QIODNSResolver *resolver = qio_dns_resolver_get_instance(); | |
51 | * SocketAddress **rawaddrs = NULL; | |
52 | * size_t nrawaddrs = 0; | |
53 | * Error *err = NULL; | |
54 | * QIOChannel **socks = NULL; | |
55 | * size_t nsocks = 0; | |
56 | * | |
57 | * if (qio_dns_resolver_lookup_sync(dns, addr, &nrawaddrs, | |
58 | * &rawaddrs, errp) < 0) { | |
59 | * return -1; | |
60 | * } | |
61 | * | |
62 | * for (i = 0; i < nrawaddrs; i++) { | |
63 | * QIOChannel *sock = qio_channel_new(); | |
64 | * Error *local_err = NULL; | |
65 | * qio_channel_listen_sync(sock, rawaddrs[i], &local_err); | |
66 | * if (local_err) { | |
67 | * error_propagate(&err, local_err); | |
68 | * } else { | |
69 | * socks = g_renew(QIOChannelSocket *, socks, nsocks + 1); | |
70 | * socks[nsocks++] = sock; | |
71 | * } | |
72 | * qapi_free_SocketAddress(rawaddrs[i]); | |
73 | * } | |
74 | * g_free(rawaddrs); | |
75 | * | |
76 | * if (nsocks == 0) { | |
77 | * error_propagate(errp, err); | |
78 | * } else { | |
79 | * error_free(err); | |
80 | * } | |
81 | * } | |
82 | * </programlisting> | |
83 | * </example> | |
84 | * | |
85 | * <example> | |
86 | * <title>Resolving addresses asynchronously</title> | |
87 | * <programlisting> | |
88 | * typedef struct MyListenData { | |
89 | * Error *err; | |
90 | * QIOChannelSocket **socks; | |
91 | * size_t nsocks; | |
92 | * } MyListenData; | |
93 | * | |
94 | * void mylistenresult(QIOTask *task, void *opaque) { | |
95 | * MyListenData *data = opaque; | |
96 | * QIODNSResolver *resolver = | |
97 | * QIO_DNS_RESOLVER(qio_task_get_source(task); | |
98 | * SocketAddress **rawaddrs = NULL; | |
99 | * size_t nrawaddrs = 0; | |
100 | * Error *err = NULL; | |
101 | * | |
102 | * if (qio_task_propagate_error(task, &data->err)) { | |
103 | * return; | |
104 | * } | |
105 | * | |
106 | * qio_dns_resolver_lookup_result(resolver, task, | |
107 | * &nrawaddrs, &rawaddrs); | |
108 | * | |
109 | * for (i = 0; i < nrawaddrs; i++) { | |
110 | * QIOChannel *sock = qio_channel_new(); | |
111 | * Error *local_err = NULL; | |
112 | * qio_channel_listen_sync(sock, rawaddrs[i], &local_err); | |
113 | * if (local_err) { | |
114 | * error_propagate(&err, local_err); | |
115 | * } else { | |
116 | * socks = g_renew(QIOChannelSocket *, socks, nsocks + 1); | |
117 | * socks[nsocks++] = sock; | |
118 | * } | |
119 | * qapi_free_SocketAddress(rawaddrs[i]); | |
120 | * } | |
121 | * g_free(rawaddrs); | |
122 | * | |
123 | * if (nsocks == 0) { | |
124 | * error_propagate(&data->err, err); | |
125 | * } else { | |
126 | * error_free(err); | |
127 | * } | |
128 | * } | |
129 | * | |
130 | * void mylisten(SocketAddress *addr, MyListenData *data) { | |
131 | * QIODNSResolver *resolver = qio_dns_resolver_get_instance(); | |
132 | * qio_dns_resolver_lookup_async(dns, addr, | |
133 | * mylistenresult, data, NULL); | |
134 | * } | |
135 | * </programlisting> | |
136 | * </example> | |
137 | */ | |
138 | struct QIODNSResolver { | |
139 | Object parent; | |
140 | }; | |
141 | ||
142 | struct QIODNSResolverClass { | |
143 | ObjectClass parent; | |
144 | }; | |
145 | ||
146 | ||
147 | /** | |
148 | * qio_dns_resolver_get_instance: | |
149 | * | |
150 | * Get the singleton dns resolver instance. The caller | |
151 | * does not own a reference on the returned object. | |
152 | * | |
153 | * Returns: the single dns resolver instance | |
154 | */ | |
155 | QIODNSResolver *qio_dns_resolver_get_instance(void); | |
156 | ||
157 | /** | |
158 | * qio_dns_resolver_lookup_sync: | |
159 | * @resolver: the DNS resolver instance | |
160 | * @addr: the address to resolve | |
161 | * @naddr: pointer to hold number of resolved addresses | |
162 | * @addrs: pointer to hold resolved addresses | |
163 | * @errp: pointer to NULL initialized error object | |
164 | * | |
165 | * This will attempt to resolve the address provided | |
166 | * in @addr. If resolution succeeds, @addrs will be filled | |
167 | * with all the resolved addresses. @naddrs will specify | |
168 | * the number of entries allocated in @addrs. The caller | |
169 | * is responsible for freeing each entry in @addrs, as | |
170 | * well as @addrs itself. @naddrs is guaranteed to be | |
171 | * greater than zero on success. | |
172 | * | |
173 | * DNS resolution will be done synchronously so execution | |
174 | * of the caller may be blocked for an arbitrary length | |
175 | * of time. | |
176 | * | |
177 | * Returns: 0 if resolution was successful, -1 on error | |
178 | */ | |
179 | int qio_dns_resolver_lookup_sync(QIODNSResolver *resolver, | |
180 | SocketAddress *addr, | |
181 | size_t *naddrs, | |
182 | SocketAddress ***addrs, | |
183 | Error **errp); | |
184 | ||
185 | /** | |
186 | * qio_dns_resolver_lookup_async: | |
187 | * @resolver: the DNS resolver instance | |
188 | * @addr: the address to resolve | |
189 | * @func: the callback to invoke on lookup completion | |
190 | * @opaque: data blob to pass to @func | |
191 | * @notify: the callback to free @opaque, or NULL | |
192 | * | |
193 | * This will attempt to resolve the address provided | |
194 | * in @addr. The callback @func will be invoked when | |
195 | * resolution has either completed or failed. On | |
196 | * success, the @func should call the method | |
197 | * qio_dns_resolver_lookup_result() to obtain the | |
198 | * results. | |
199 | * | |
200 | * DNS resolution will be done asynchronously so execution | |
201 | * of the caller will not be blocked. | |
202 | */ | |
203 | void qio_dns_resolver_lookup_async(QIODNSResolver *resolver, | |
204 | SocketAddress *addr, | |
205 | QIOTaskFunc func, | |
206 | gpointer opaque, | |
207 | GDestroyNotify notify); | |
208 | ||
209 | /** | |
210 | * qio_dns_resolver_lookup_result: | |
211 | * @resolver: the DNS resolver instance | |
212 | * @task: the task object to get results for | |
213 | * @naddr: pointer to hold number of resolved addresses | |
214 | * @addrs: pointer to hold resolved addresses | |
215 | * | |
216 | * This method should be called from the callback passed | |
217 | * to qio_dns_resolver_lookup_async() in order to obtain | |
218 | * results. @addrs will be filled with all the resolved | |
219 | * addresses. @naddrs will specify the number of entries | |
220 | * allocated in @addrs. The caller is responsible for | |
221 | * freeing each entry in @addrs, as well as @addrs itself. | |
222 | */ | |
223 | void qio_dns_resolver_lookup_result(QIODNSResolver *resolver, | |
224 | QIOTask *task, | |
225 | size_t *naddrs, | |
226 | SocketAddress ***addrs); | |
227 | ||
228 | #endif /* QIO_DNS_RESOLVER_H */ |