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