Line data Source code
1 1 : /** @file
2 : * @brief DNS resolving library
3 : *
4 : * An API for applications to resolve a DNS name.
5 : */
6 :
7 : /*
8 : * Copyright (c) 2017 Intel Corporation
9 : *
10 : * SPDX-License-Identifier: Apache-2.0
11 : */
12 :
13 : #ifndef ZEPHYR_INCLUDE_NET_DNS_RESOLVE_H_
14 : #define ZEPHYR_INCLUDE_NET_DNS_RESOLVE_H_
15 :
16 : #include <zephyr/kernel.h>
17 : #include <zephyr/net/net_ip.h>
18 : #include <zephyr/net/net_if.h>
19 : #include <zephyr/net/socket_poll.h>
20 : #include <zephyr/net/net_core.h>
21 :
22 : #ifdef __cplusplus
23 : extern "C" {
24 : #endif
25 :
26 : /**
27 : * @brief DNS resolving library
28 : * @defgroup dns_resolve DNS Resolve Library
29 : * @since 1.8
30 : * @version 0.8.0
31 : * @ingroup networking
32 : * @{
33 : */
34 :
35 : /**
36 : * DNS query type enum
37 : */
38 1 : enum dns_query_type {
39 : /** IPv4 query */
40 : DNS_QUERY_TYPE_A = 1,
41 : /** Canonical name query */
42 : DNS_QUERY_TYPE_CNAME = 5,
43 : /** Pointer query */
44 : DNS_QUERY_TYPE_PTR = 12,
45 : /** Text query */
46 : DNS_QUERY_TYPE_TXT = 16,
47 : /** IPv6 query */
48 : DNS_QUERY_TYPE_AAAA = 28,
49 : /** Service location query */
50 : DNS_QUERY_TYPE_SRV = 33
51 : };
52 :
53 : /**
54 : * Entity that added the DNS server.
55 : */
56 1 : enum dns_server_source {
57 : /** Source is unknown */
58 : DNS_SOURCE_UNKNOWN = 0,
59 : /** Server information is added manually, for example by an application */
60 : DNS_SOURCE_MANUAL,
61 : /** Server information is from DHCPv4 server */
62 : DNS_SOURCE_DHCPV4,
63 : /** Server information is from DHCPv6 server */
64 : DNS_SOURCE_DHCPV6,
65 : /** Server information is from IPv6 SLAAC (router advertisement) */
66 : DNS_SOURCE_IPV6_RA,
67 : /** Server information is from PPP */
68 : DNS_SOURCE_PPP,
69 : };
70 :
71 : /** Max size of the resolved name. */
72 : #if defined(CONFIG_DNS_RESOLVER_MAX_NAME_LEN)
73 : #define DNS_MAX_NAME_SIZE CONFIG_DNS_RESOLVER_MAX_NAME_LEN
74 : #else
75 1 : #define DNS_MAX_NAME_SIZE 20
76 : #endif /* CONFIG_DNS_RESOLVER_MAX_NAME_LEN */
77 :
78 : /** Max size of the resolved txt record. */
79 : #if defined(CONFIG_DNS_RESOLVER_MAX_TEXT_LEN)
80 : #define DNS_MAX_TEXT_SIZE CONFIG_DNS_RESOLVER_MAX_TEXT_LEN
81 : #else
82 1 : #define DNS_MAX_TEXT_SIZE 64
83 : #endif /* CONFIG_DNS_RESOLVER_MAX_TEXT_LEN */
84 :
85 : /** @cond INTERNAL_HIDDEN */
86 :
87 : #define DNS_BUF_TIMEOUT K_MSEC(500) /* ms */
88 :
89 : /* This value is recommended by RFC 1035 */
90 : #if defined(CONFIG_DNS_RESOLVER_MAX_ANSWER_SIZE)
91 : #define DNS_RESOLVER_MAX_BUF_SIZE CONFIG_DNS_RESOLVER_MAX_ANSWER_SIZE
92 : #else
93 : #define DNS_RESOLVER_MAX_BUF_SIZE 512
94 : #endif /* CONFIG_DNS_RESOLVER_MAX_ANSWER_SIZE */
95 :
96 : /* Make sure that we can compile things even if CONFIG_DNS_RESOLVER
97 : * is not enabled.
98 : */
99 : #if defined(CONFIG_DNS_RESOLVER_MAX_SERVERS)
100 : #define DNS_RESOLVER_MAX_SERVERS CONFIG_DNS_RESOLVER_MAX_SERVERS
101 : #else
102 : #define DNS_RESOLVER_MAX_SERVERS 0
103 : #endif
104 :
105 : #if defined(CONFIG_DNS_NUM_CONCUR_QUERIES)
106 : #define DNS_NUM_CONCUR_QUERIES CONFIG_DNS_NUM_CONCUR_QUERIES
107 : #else
108 : #define DNS_NUM_CONCUR_QUERIES 1
109 : #endif
110 :
111 : #if defined(CONFIG_NET_IF_MAX_IPV6_COUNT)
112 : #define MAX_IPV6_IFACE_COUNT CONFIG_NET_IF_MAX_IPV6_COUNT
113 : #else
114 : #define MAX_IPV6_IFACE_COUNT 1
115 : #endif
116 :
117 : #if defined(CONFIG_NET_IF_MAX_IPV4_COUNT)
118 : #define MAX_IPV4_IFACE_COUNT CONFIG_NET_IF_MAX_IPV4_COUNT
119 : #else
120 : #define MAX_IPV4_IFACE_COUNT 1
121 : #endif
122 :
123 : /* If mDNS is enabled, then add some extra well known multicast servers to the
124 : * server list.
125 : */
126 : #if defined(CONFIG_MDNS_RESOLVER)
127 : #if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_IPV4)
128 : #define MDNS_SERVER_COUNT 2
129 : #else
130 : #define MDNS_SERVER_COUNT 1
131 : #endif /* CONFIG_NET_IPV6 && CONFIG_NET_IPV4 */
132 : #else
133 : #define MDNS_SERVER_COUNT 0
134 : #endif /* CONFIG_MDNS_RESOLVER */
135 :
136 : /* If LLMNR is enabled, then add some extra well known multicast servers to the
137 : * server list.
138 : */
139 : #if defined(CONFIG_LLMNR_RESOLVER)
140 : #if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_IPV4)
141 : #define LLMNR_SERVER_COUNT 2
142 : #else
143 : #define LLMNR_SERVER_COUNT 1
144 : #endif /* CONFIG_NET_IPV6 && CONFIG_NET_IPV4 */
145 : #else
146 : #define LLMNR_SERVER_COUNT 0
147 : #endif /* CONFIG_MDNS_RESOLVER */
148 :
149 : #define DNS_MAX_MCAST_SERVERS (MDNS_SERVER_COUNT + LLMNR_SERVER_COUNT)
150 :
151 : #if defined(CONFIG_MDNS_RESPONDER)
152 : #if defined(CONFIG_NET_IPV6)
153 : #define MDNS_MAX_IPV6_IFACE_COUNT CONFIG_NET_IF_MAX_IPV6_COUNT
154 : #else
155 : #define MDNS_MAX_IPV6_IFACE_COUNT 0
156 : #endif /* CONFIG_NET_IPV6 */
157 :
158 : #if defined(CONFIG_NET_IPV4)
159 : #define MDNS_MAX_IPV4_IFACE_COUNT CONFIG_NET_IF_MAX_IPV4_COUNT
160 : #else
161 : #define MDNS_MAX_IPV4_IFACE_COUNT 0
162 : #endif /* CONFIG_NET_IPV4 */
163 :
164 : #define MDNS_MAX_POLL (MDNS_MAX_IPV4_IFACE_COUNT + MDNS_MAX_IPV6_IFACE_COUNT)
165 : #else
166 : #define MDNS_MAX_POLL 0
167 : #endif /* CONFIG_MDNS_RESPONDER */
168 :
169 : #if defined(CONFIG_LLMNR_RESPONDER)
170 : #if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_IPV4)
171 : #define LLMNR_MAX_POLL 2
172 : #else
173 : #define LLMNR_MAX_POLL 1
174 : #endif
175 : #else
176 : #define LLMNR_MAX_POLL 0
177 : #endif /* CONFIG_LLMNR_RESPONDER */
178 :
179 : #define DNS_RESOLVER_MAX_POLL (DNS_RESOLVER_MAX_SERVERS + DNS_MAX_MCAST_SERVERS)
180 :
181 : /** How many sockets the dispatcher is able to poll. */
182 : #define DNS_DISPATCHER_MAX_POLL (DNS_RESOLVER_MAX_POLL + MDNS_MAX_POLL + LLMNR_MAX_POLL)
183 :
184 : #if defined(CONFIG_ZVFS_POLL_MAX)
185 : BUILD_ASSERT(CONFIG_ZVFS_POLL_MAX >= DNS_DISPATCHER_MAX_POLL,
186 : "CONFIG_ZVFS_POLL_MAX must be larger than " STRINGIFY(DNS_DISPATCHER_MAX_POLL));
187 : #endif
188 :
189 : /** @brief What is the type of the socket given to DNS socket dispatcher,
190 : * resolver or responder.
191 : */
192 : enum dns_socket_type {
193 : DNS_SOCKET_RESOLVER = 1, /**< Socket is used for resolving (client type) */
194 : DNS_SOCKET_RESPONDER = 2 /**< Socket is used for responding (server type) */
195 : };
196 :
197 : struct dns_resolve_context;
198 : struct mdns_responder_context;
199 : struct dns_socket_dispatcher;
200 :
201 : /**
202 : * @typedef dns_socket_dispatcher_cb
203 : * @brief Callback used when the DNS socket dispatcher has found a handler for
204 : * this type of socket.
205 : *
206 : * @param ctx struct dns_socket_dispatcher context.
207 : * @param sock Socket which is seeing traffic.
208 : * @param addr Socket address of the peer that sent the DNS packet.
209 : * @param addrlen Length of the socket address.
210 : * @param buf Pointer to data buffer containing the DNS message.
211 : * @param data_len Length of the data in buffer chain.
212 : *
213 : * @return 0 if ok, <0 if error
214 : */
215 : typedef int (*dns_socket_dispatcher_cb)(struct dns_socket_dispatcher *ctx, int sock,
216 : struct sockaddr *addr, size_t addrlen,
217 : struct net_buf *buf, size_t data_len);
218 :
219 : /** @brief DNS socket dispatcher context. */
220 : struct dns_socket_dispatcher {
221 : /** slist node for the different dispatcher contexts */
222 : sys_snode_t node;
223 : /** Socket service for this dispatcher instance */
224 : const struct net_socket_service_desc *svc;
225 : /** DNS resolver context that contains information needed by the
226 : * resolver/responder handler, or mDNS responder context.
227 : */
228 : union {
229 : void *ctx;
230 : struct dns_resolve_context *resolve_ctx;
231 : struct mdns_responder_context *mdns_ctx;
232 : };
233 :
234 : /** Type of the socket (resolver / responder) */
235 : enum dns_socket_type type;
236 : /** Local endpoint address (used when binding the socket) */
237 : struct sockaddr local_addr;
238 : /** DNS socket dispatcher callback is called for incoming traffic */
239 : dns_socket_dispatcher_cb cb;
240 : /** Socket descriptors to poll */
241 : struct zsock_pollfd *fds;
242 : /** Length of the poll array */
243 : int fds_len;
244 : /** Local socket to dispatch */
245 : int sock;
246 : /** Interface we are bound to */
247 : int ifindex;
248 : /** There can be two contexts to dispatch. This points to the other
249 : * context if sharing the socket between resolver / responder.
250 : */
251 : struct dns_socket_dispatcher *pair;
252 : /** Mutex lock protecting access to this dispatcher context */
253 : struct k_mutex lock;
254 : /** Buffer allocation timeout */
255 : k_timeout_t buf_timeout;
256 : };
257 :
258 : /**
259 : * @brief Register a DNS dispatcher socket. Each code wanting to use
260 : * the dispatcher needs to create the dispatcher context and call
261 : * this function.
262 : *
263 : * @param ctx DNS socket dispatcher context.
264 : *
265 : * @return 0 if ok, <1 if error
266 : */
267 : int dns_dispatcher_register(struct dns_socket_dispatcher *ctx);
268 :
269 : /**
270 : * @brief Unregister a DNS dispatcher socket. Called when the
271 : * resolver/responder no longer needs to receive traffic for the
272 : * socket.
273 : *
274 : * @param ctx DNS socket dispatcher context.
275 : *
276 : * @return 0 if ok, <1 if error
277 : */
278 : int dns_dispatcher_unregister(struct dns_socket_dispatcher *ctx);
279 :
280 : /** @endcond */
281 :
282 : /**
283 : * Enumerate the extensions that are available in the address info
284 : */
285 0 : enum dns_resolve_extension {
286 : DNS_RESOLVE_NONE = 0,
287 : DNS_RESOLVE_TXT,
288 : DNS_RESOLVE_SRV,
289 : };
290 :
291 0 : struct dns_resolve_txt {
292 0 : size_t textlen;
293 0 : char text[DNS_MAX_TEXT_SIZE + 1];
294 : };
295 :
296 0 : struct dns_resolve_srv {
297 0 : uint16_t priority;
298 0 : uint16_t weight;
299 0 : uint16_t port;
300 0 : size_t targetlen;
301 0 : char target[DNS_MAX_NAME_SIZE + 1];
302 : };
303 :
304 : /**
305 : * Address info struct is passed to callback that gets all the results.
306 : */
307 1 : struct dns_addrinfo {
308 : /** Address family of the address information and discriminator */
309 1 : uint8_t ai_family;
310 :
311 : union {
312 : struct {
313 : /** Length of the ai_addr field or ai_canonname */
314 1 : socklen_t ai_addrlen;
315 :
316 : /* AF_INET or AF_INET6 address info */
317 0 : struct sockaddr ai_addr;
318 :
319 : /** AF_LOCAL Canonical name of the address */
320 1 : char ai_canonname[DNS_MAX_NAME_SIZE + 1];
321 : };
322 :
323 : /* AF_UNSPEC extensions */
324 : struct {
325 0 : enum dns_resolve_extension ai_extension;
326 :
327 : union {
328 0 : struct dns_resolve_txt ai_txt;
329 0 : struct dns_resolve_srv ai_srv;
330 : };
331 : };
332 0 : };
333 : };
334 :
335 : /**
336 : * Status values for the callback.
337 : */
338 1 : enum dns_resolve_status {
339 : /** Invalid value for `ai_flags' field */
340 : DNS_EAI_BADFLAGS = -1,
341 : /** NAME or SERVICE is unknown */
342 : DNS_EAI_NONAME = -2,
343 : /** Temporary failure in name resolution */
344 : DNS_EAI_AGAIN = -3,
345 : /** Non-recoverable failure in name res */
346 : DNS_EAI_FAIL = -4,
347 : /** No address associated with NAME */
348 : DNS_EAI_NODATA = -5,
349 : /** `ai_family' not supported */
350 : DNS_EAI_FAMILY = -6,
351 : /** `ai_socktype' not supported */
352 : DNS_EAI_SOCKTYPE = -7,
353 : /** SRV not supported for `ai_socktype' */
354 : DNS_EAI_SERVICE = -8,
355 : /** Address family for NAME not supported */
356 : DNS_EAI_ADDRFAMILY = -9,
357 : /** Memory allocation failure */
358 : DNS_EAI_MEMORY = -10,
359 : /** System error returned in `errno' */
360 : DNS_EAI_SYSTEM = -11,
361 : /** Argument buffer overflow */
362 : DNS_EAI_OVERFLOW = -12,
363 : /** Processing request in progress */
364 : DNS_EAI_INPROGRESS = -100,
365 : /** Request canceled */
366 : DNS_EAI_CANCELED = -101,
367 : /** Request not canceled */
368 : DNS_EAI_NOTCANCELED = -102,
369 : /** All requests done */
370 : DNS_EAI_ALLDONE = -103,
371 : /** IDN encoding failed */
372 : DNS_EAI_IDN_ENCODE = -105,
373 : };
374 :
375 : /**
376 : * @typedef dns_resolve_cb_t
377 : * @brief DNS resolve callback
378 : *
379 : * @details The DNS resolve callback is called after a successful
380 : * DNS resolving. The resolver can call this callback multiple times, one
381 : * for each resolved address.
382 : *
383 : * @param status The status of the query:
384 : * DNS_EAI_INPROGRESS returned for each resolved address
385 : * DNS_EAI_ALLDONE mark end of the resolving, info is set to NULL in
386 : * this case
387 : * DNS_EAI_CANCELED if the query was canceled manually or timeout happened
388 : * DNS_EAI_FAIL if the name cannot be resolved by the server
389 : * DNS_EAI_NODATA if there is no such name
390 : * other values means that an error happened.
391 : * @param info Query results are stored here.
392 : * @param user_data The user data given in dns_resolve_name() call.
393 : */
394 1 : typedef void (*dns_resolve_cb_t)(enum dns_resolve_status status,
395 : struct dns_addrinfo *info,
396 : void *user_data);
397 :
398 : /** @cond INTERNAL_HIDDEN */
399 :
400 : enum dns_resolve_context_state {
401 : DNS_RESOLVE_CONTEXT_UNINITIALIZED = 0,
402 : DNS_RESOLVE_CONTEXT_ACTIVE,
403 : DNS_RESOLVE_CONTEXT_DEACTIVATING,
404 : DNS_RESOLVE_CONTEXT_INACTIVE,
405 : };
406 :
407 : /** @endcond */
408 :
409 : /**
410 : * DNS resolve context structure.
411 : */
412 1 : struct dns_resolve_context {
413 : /** List of configured DNS servers */
414 1 : struct dns_server {
415 : /** DNS server information */
416 1 : struct sockaddr dns_server;
417 :
418 : /** Connection to the DNS server */
419 1 : int sock;
420 :
421 : /** Network interface index if the DNS resolving should be done
422 : * via this interface. Value 0 indicates any interface can be used.
423 : */
424 1 : int if_index;
425 :
426 : /** Source of the DNS server, e.g., manual, DHCPv4/6, etc. */
427 1 : enum dns_server_source source;
428 :
429 : /** Is this server mDNS one */
430 1 : uint8_t is_mdns : 1;
431 :
432 : /** Is this server LLMNR one */
433 1 : uint8_t is_llmnr : 1;
434 :
435 : /** @cond INTERNAL_HIDDEN */
436 : /** Dispatch DNS data between resolver and responder */
437 : struct dns_socket_dispatcher dispatcher;
438 : /** @endcond */
439 0 : } servers[DNS_RESOLVER_MAX_POLL];
440 :
441 : /** @cond INTERNAL_HIDDEN */
442 : /** Socket polling for each server connection */
443 : struct zsock_pollfd fds[DNS_RESOLVER_MAX_POLL];
444 : /** @endcond */
445 :
446 : /** Prevent concurrent access */
447 1 : struct k_mutex lock;
448 :
449 : /** This timeout is also used when a buffer is required from the
450 : * buffer pools.
451 : */
452 1 : k_timeout_t buf_timeout;
453 :
454 : /** Result callbacks. We have multiple callbacks here so that it is
455 : * possible to do multiple queries at the same time.
456 : *
457 : * Contents of this structure can be inspected and changed only when
458 : * the lock is held.
459 : */
460 1 : struct dns_pending_query {
461 : /** Timeout timer */
462 1 : struct k_work_delayable timer;
463 :
464 : /** Back pointer to ctx, needed in timeout handler */
465 1 : struct dns_resolve_context *ctx;
466 :
467 : /** Result callback.
468 : *
469 : * A null value indicates the slot is not in use.
470 : */
471 1 : dns_resolve_cb_t cb;
472 :
473 : /** User data */
474 1 : void *user_data;
475 :
476 : /** TX timeout */
477 1 : k_timeout_t timeout;
478 :
479 : /** String containing the thing to resolve like www.example.com
480 : *
481 : * This is set to a non-null value when the query is started,
482 : * and is not used thereafter.
483 : *
484 : * If the query completed at a point where the work item was
485 : * still pending the pointer is cleared to indicate that the
486 : * query is complete, but release of the query slot will be
487 : * deferred until a request for a slot determines that the
488 : * work item has been released.
489 : */
490 1 : const char *query;
491 :
492 : /** Query type */
493 1 : enum dns_query_type query_type;
494 :
495 : /** DNS id of this query */
496 1 : uint16_t id;
497 :
498 : /** Hash of the DNS name + query type we are querying.
499 : * This hash is calculated so we can match the response that
500 : * we are receiving. This is needed mainly for mDNS which is
501 : * setting the DNS id to 0, which means that the id alone
502 : * cannot be used to find correct pending query.
503 : */
504 1 : uint16_t query_hash;
505 0 : } queries[DNS_NUM_CONCUR_QUERIES];
506 :
507 : /** Is this context in use */
508 1 : enum dns_resolve_context_state state;
509 : };
510 :
511 : /** @cond INTERNAL_HIDDEN */
512 :
513 : struct mdns_probe_user_data {
514 : struct mdns_responder_context *ctx;
515 : char query[DNS_MAX_NAME_SIZE + 1];
516 : uint16_t dns_id;
517 : };
518 :
519 : struct mdns_responder_context {
520 : struct sockaddr server_addr;
521 : struct dns_socket_dispatcher dispatcher;
522 : struct zsock_pollfd fds[1];
523 : int sock;
524 : struct net_if *iface;
525 : #if defined(CONFIG_MDNS_RESPONDER_PROBE)
526 : struct k_work_delayable probe_timer;
527 : struct dns_resolve_context probe_ctx;
528 : struct mdns_probe_user_data probe_data;
529 : #endif
530 : };
531 :
532 : /** @endcond */
533 :
534 : /**
535 : * @brief Init DNS resolving context.
536 : *
537 : * @details This function sets the DNS server address and initializes the
538 : * DNS context that is used by the actual resolver. DNS server addresses
539 : * can be specified either in textual form, or as struct sockaddr (or both).
540 : * Note that the recommended way to resolve DNS names is to use
541 : * the dns_get_addr_info() API. In that case user does not need to
542 : * call dns_resolve_init() as the DNS servers are already setup by the system.
543 : *
544 : * @param ctx DNS context. If the context variable is allocated from
545 : * the stack, then the variable needs to be valid for the whole duration of
546 : * the resolving. Caller does not need to fill the variable beforehand or
547 : * edit the context afterwards.
548 : * @param dns_servers_str DNS server addresses using textual strings. The
549 : * array is NULL terminated. The port number can be given in the string.
550 : * Syntax for the server addresses with or without port numbers:
551 : * IPv4 : 10.0.9.1
552 : * IPv4 + port : 10.0.9.1:5353
553 : * IPv6 : 2001:db8::22:42
554 : * IPv6 + port : [2001:db8::22:42]:5353
555 : * @param dns_servers_sa DNS server addresses as struct sockaddr. The array
556 : * is NULL terminated. Port numbers are optional in struct sockaddr, the
557 : * default will be used if set to 0.
558 : *
559 : * @return 0 if ok, <0 if error.
560 : */
561 1 : int dns_resolve_init(struct dns_resolve_context *ctx,
562 : const char *dns_servers_str[],
563 : const struct sockaddr *dns_servers_sa[]);
564 :
565 : /**
566 : * @brief Init DNS resolving context with default Kconfig options.
567 : *
568 : * @param ctx DNS context.
569 : *
570 : * @return 0 if ok, <0 if error.
571 : */
572 1 : int dns_resolve_init_default(struct dns_resolve_context *ctx);
573 :
574 : /**
575 : * @brief Close DNS resolving context.
576 : *
577 : * @details This releases DNS resolving context and marks the context unusable.
578 : * Caller must call the dns_resolve_init() again to make context usable.
579 : *
580 : * @param ctx DNS context
581 : *
582 : * @return 0 if ok, <0 if error.
583 : */
584 1 : int dns_resolve_close(struct dns_resolve_context *ctx);
585 :
586 : /**
587 : * @brief Reconfigure DNS resolving context.
588 : *
589 : * @details Reconfigures DNS context with new server list.
590 : *
591 : * @param ctx DNS context
592 : * @param servers_str DNS server addresses using textual strings. The
593 : * array is NULL terminated. The port number can be given in the string.
594 : * Syntax for the server addresses with or without port numbers:
595 : * IPv4 : 10.0.9.1
596 : * IPv4 + port : 10.0.9.1:5353
597 : * IPv6 : 2001:db8::22:42
598 : * IPv6 + port : [2001:db8::22:42]:5353
599 : * @param servers_sa DNS server addresses as struct sockaddr. The array
600 : * is NULL terminated. Port numbers are optional in struct sockaddr, the
601 : * default will be used if set to 0.
602 : * @param source Source of the DNS servers, e.g., manual, DHCPv4/6, etc.
603 : *
604 : * @return 0 if ok, <0 if error.
605 : */
606 1 : int dns_resolve_reconfigure(struct dns_resolve_context *ctx,
607 : const char *servers_str[],
608 : const struct sockaddr *servers_sa[],
609 : enum dns_server_source source);
610 :
611 : /**
612 : * @brief Reconfigure DNS resolving context with new server list and
613 : * allowing servers to be specified to a specific network interface.
614 : *
615 : * @param ctx DNS context
616 : * @param servers_str DNS server addresses using textual strings. The
617 : * array is NULL terminated. The port number can be given in the string.
618 : * Syntax for the server addresses with or without port numbers:
619 : * IPv4 : 10.0.9.1
620 : * IPv4 + port : 10.0.9.1:5353
621 : * IPv6 : 2001:db8::22:42
622 : * IPv6 + port : [2001:db8::22:42]:5353
623 : * @param servers_sa DNS server addresses as struct sockaddr. The array
624 : * is NULL terminated. Port numbers are optional in struct sockaddr, the
625 : * default will be used if set to 0.
626 : * @param interfaces Network interfaces to which the DNS servers are bound.
627 : * This is an array of network interface indices. The array must be
628 : * the same length as the servers_str and servers_sa arrays.
629 : * @param source Source of the DNS servers, e.g., manual, DHCPv4/6, etc.
630 : *
631 : * @return 0 if ok, <0 if error.
632 : */
633 1 : int dns_resolve_reconfigure_with_interfaces(struct dns_resolve_context *ctx,
634 : const char *servers_str[],
635 : const struct sockaddr *servers_sa[],
636 : int interfaces[],
637 : enum dns_server_source source);
638 :
639 : /**
640 : * @brief Remove servers from the DNS resolving context.
641 : *
642 : * @param ctx DNS context
643 : * @param if_index Network interface from which the DNS servers are removed.
644 : *
645 : * @return 0 if ok, <0 if error.
646 : */
647 1 : int dns_resolve_remove(struct dns_resolve_context *ctx, int if_index);
648 :
649 : /**
650 : * @brief Remove servers from the DNS resolving context that were added by
651 : * a specific source.
652 : *
653 : * @param ctx DNS context
654 : * @param if_index Network interface from which the DNS servers are removed.
655 : * @param source Source of the DNS servers, e.g., manual, DHCPv4/6, etc.
656 : *
657 : * @return 0 if ok, <0 if error.
658 : */
659 1 : int dns_resolve_remove_source(struct dns_resolve_context *ctx, int if_index,
660 : enum dns_server_source source);
661 :
662 : /**
663 : * @brief Cancel a pending DNS query.
664 : *
665 : * @details This releases DNS resources used by a pending query.
666 : *
667 : * @param ctx DNS context
668 : * @param dns_id DNS id of the pending query
669 : *
670 : * @return 0 if ok, <0 if error.
671 : */
672 1 : int dns_resolve_cancel(struct dns_resolve_context *ctx,
673 : uint16_t dns_id);
674 :
675 : /**
676 : * @brief Cancel a pending DNS query using id, name and type.
677 : *
678 : * @details This releases DNS resources used by a pending query.
679 : *
680 : * @param ctx DNS context
681 : * @param dns_id DNS id of the pending query
682 : * @param query_name Name of the resource we are trying to query (hostname)
683 : * @param query_type Type of the query (A or AAAA)
684 : *
685 : * @return 0 if ok, <0 if error.
686 : */
687 1 : int dns_resolve_cancel_with_name(struct dns_resolve_context *ctx,
688 : uint16_t dns_id,
689 : const char *query_name,
690 : enum dns_query_type query_type);
691 :
692 : /**
693 : * @brief Resolve DNS name.
694 : *
695 : * @details This function can be used to resolve e.g., IPv4 or IPv6 address.
696 : * Note that this is asynchronous call, the function will return immediately
697 : * and system will call the callback after resolving has finished or timeout
698 : * has occurred.
699 : * We might send the query to multiple servers (if there are more than one
700 : * server configured), but we only use the result of the first received
701 : * response.
702 : *
703 : * @param ctx DNS context
704 : * @param query What the caller wants to resolve.
705 : * @param type What kind of data the caller wants to get.
706 : * @param dns_id DNS id is returned to the caller. This is needed if one
707 : * wishes to cancel the query. This can be set to NULL if there is no need
708 : * to cancel the query.
709 : * @param cb Callback to call after the resolving has finished or timeout
710 : * has happened.
711 : * @param user_data The user data.
712 : * @param timeout The timeout value for the query. Possible values:
713 : * SYS_FOREVER_MS: the query is tried forever, user needs to cancel it
714 : * manually if it takes too long time to finish
715 : * >0: start the query and let the system timeout it after specified ms
716 : *
717 : * @return 0 if resolving was started ok, < 0 otherwise
718 : */
719 1 : int dns_resolve_name(struct dns_resolve_context *ctx,
720 : const char *query,
721 : enum dns_query_type type,
722 : uint16_t *dns_id,
723 : dns_resolve_cb_t cb,
724 : void *user_data,
725 : int32_t timeout);
726 :
727 : /**
728 : * @brief Resolve DNS service.
729 : *
730 : * @details This function can be used to resolve service records needed in
731 : * DNS-SD service discovery.
732 : * Note that this is an asynchronous call, the function will return immediately
733 : * and the system will call the callback after resolving has finished or a timeout
734 : * has occurred.
735 : * We might send the query to multiple servers (if there are more than one
736 : * server configured), but we only use the result of the first received
737 : * response.
738 : *
739 : * @param ctx DNS context
740 : * @param query What the caller wants to resolve.
741 : * @param dns_id DNS id is returned to the caller. This is needed if one
742 : * wishes to cancel the query. This can be set to NULL if there is no need
743 : * to cancel the query.
744 : * @param cb Callback to call after the resolving has finished or timeout
745 : * has happened.
746 : * @param user_data The user data.
747 : * @param timeout The timeout value for the query. Possible values:
748 : * SYS_FOREVER_MS: the query is tried forever, user needs to cancel it
749 : * manually if it takes too long time to finish
750 : * >0: start the query and let the system timeout it after specified ms
751 : *
752 : * @return 0 if resolving was started ok, < 0 otherwise
753 : */
754 1 : static inline int dns_resolve_service(struct dns_resolve_context *ctx,
755 : const char *query,
756 : uint16_t *dns_id,
757 : dns_resolve_cb_t cb,
758 : void *user_data,
759 : int32_t timeout)
760 : {
761 : return dns_resolve_name(ctx, query, DNS_QUERY_TYPE_PTR,
762 : dns_id, cb, user_data, timeout);
763 : }
764 :
765 : /**
766 : * @brief Get default DNS context.
767 : *
768 : * @details The system level DNS context uses DNS servers that are
769 : * defined in project config file. If no DNS servers are defined by the
770 : * user, then resolving DNS names using default DNS context will do nothing.
771 : * The configuration options are described in subsys/net/lib/dns/Kconfig file.
772 : *
773 : * @return Default DNS context.
774 : */
775 1 : struct dns_resolve_context *dns_resolve_get_default(void);
776 :
777 : /**
778 : * @brief Get IP address info from DNS.
779 : *
780 : * @details This function can be used to resolve e.g., IPv4 or IPv6 address.
781 : * Note that this is asynchronous call, the function will return immediately
782 : * and system will call the callback after resolving has finished or timeout
783 : * has occurred.
784 : * We might send the query to multiple servers (if there are more than one
785 : * server configured), but we only use the result of the first received
786 : * response.
787 : * This variant uses system wide DNS servers.
788 : *
789 : * @param query What the caller wants to resolve.
790 : * @param type What kind of data the caller wants to get.
791 : * @param dns_id DNS id is returned to the caller. This is needed if one
792 : * wishes to cancel the query. This can be set to NULL if there is no need
793 : * to cancel the query.
794 : * @param cb Callback to call after the resolving has finished or timeout
795 : * has happened.
796 : * @param user_data The user data.
797 : * @param timeout The timeout value for the connection. Possible values:
798 : * SYS_FOREVER_MS: the query is tried forever, user needs to cancel it
799 : * manually if it takes too long time to finish
800 : * >0: start the query and let the system timeout it after specified ms
801 : *
802 : * @return 0 if resolving was started ok, < 0 otherwise
803 : */
804 1 : static inline int dns_get_addr_info(const char *query,
805 : enum dns_query_type type,
806 : uint16_t *dns_id,
807 : dns_resolve_cb_t cb,
808 : void *user_data,
809 : int32_t timeout)
810 : {
811 : return dns_resolve_name(dns_resolve_get_default(),
812 : query,
813 : type,
814 : dns_id,
815 : cb,
816 : user_data,
817 : timeout);
818 : }
819 :
820 : /**
821 : * @brief Cancel a pending DNS query.
822 : *
823 : * @details This releases DNS resources used by a pending query.
824 : *
825 : * @param dns_id DNS id of the pending query
826 : *
827 : * @return 0 if ok, <0 if error.
828 : */
829 1 : static inline int dns_cancel_addr_info(uint16_t dns_id)
830 : {
831 : return dns_resolve_cancel(dns_resolve_get_default(), dns_id);
832 : }
833 :
834 : /**
835 : * @}
836 : */
837 :
838 : /** @cond INTERNAL_HIDDEN */
839 :
840 : /**
841 : * @brief Get string representation of the DNS server source.
842 : *
843 : * @param source Source of the DNS server.
844 : *
845 : * @return String representation of the DNS server source.
846 : */
847 : const char *dns_get_source_str(enum dns_server_source source);
848 :
849 : /**
850 : * @brief Initialize DNS subsystem.
851 : */
852 : #if defined(CONFIG_DNS_RESOLVER_AUTO_INIT)
853 : void dns_init_resolver(void);
854 :
855 : #else
856 : #define dns_init_resolver(...)
857 : #endif /* CONFIG_DNS_RESOLVER_AUTO_INIT */
858 :
859 : /** @endcond */
860 :
861 : #ifdef __cplusplus
862 : }
863 : #endif
864 :
865 : #endif /* ZEPHYR_INCLUDE_NET_DNS_RESOLVE_H_ */
|