@@ -70,7 +70,7 @@ static void dns_result_cb(enum dns_resolve_status status,
7070break ;
7171}
7272
73- /* fallthru */
73+ __fallthrough ;
7474default :
7575strncpy (str , "Invalid proto family" , MAX_STR_LEN + 1 );
7676break ;
@@ -95,6 +95,31 @@ static void dns_result_cb(enum dns_resolve_status status,
9595PR_WARNING ("dns: Unhandled status %d received (errno %d)\n" , status , errno );
9696}
9797
98+ K_MSGQ_DEFINE (dns_infoq , sizeof (struct dns_addrinfo ), 3 , 1 );
99+
100+ static void dns_service_cb (enum dns_resolve_status status ,
101+ struct dns_addrinfo * info ,
102+ void * user_data )
103+ {
104+ int r ;
105+ const struct shell * sh = user_data ;
106+
107+ if (status == DNS_EAI_CANCELED ) {
108+ PR_WARNING ("dns: Timeout while resolving service.\n" );
109+ return ;
110+ }
111+
112+ if ((status == DNS_EAI_INPROGRESS ) && (info != NULL )) {
113+ /*
114+ * Only queue results that can be further processed.
115+ */
116+ r = k_msgq_put (& dns_infoq , info , K_NO_WAIT );
117+ if (r < 0 ) {
118+ PR_WARNING ("dns: k_msgq_put error %d" , r );
119+ }
120+ }
121+ }
122+
98123static const char * printable_iface (const char * iface_name ,
99124 const char * found ,
100125 const char * not_found )
@@ -237,7 +262,7 @@ static int cmd_net_dns_query(const struct shell *sh, size_t argc, char *argv[])
237262{
238263
239264#if defined(CONFIG_DNS_RESOLVER )
240- #define DNS_TIMEOUT (MSEC_PER_SEC * 2) /* ms */
265+ #define DNS_QUERY_TIMEOUT (MSEC_PER_SEC * 2) /* ms */
241266struct dns_resolve_context * ctx ;
242267enum dns_query_type qtype = DNS_QUERY_TYPE_A ;
243268char * host , * type = NULL ;
@@ -286,7 +311,7 @@ static int cmd_net_dns_query(const struct shell *sh, size_t argc, char *argv[])
286311}
287312
288313ret = dns_resolve_name (ctx , host , qtype , NULL , dns_result_cb ,
289- (void * )sh , DNS_TIMEOUT );
314+ (void * )sh , DNS_QUERY_TIMEOUT );
290315if (ret < 0 ) {
291316PR_WARNING ("Cannot resolve '%s' (%d)\n" , host , ret );
292317} else {
@@ -378,9 +403,11 @@ static int cmd_net_dns_list(const struct shell *sh, size_t argc, char *argv[])
378403static int cmd_net_dns_service (const struct shell * sh , size_t argc , char * argv [])
379404{
380405#if defined(CONFIG_DNS_RESOLVER )
381- #define DNS_TIMEOUT (MSEC_PER_SEC * 2 ) /* ms */
406+ #define DNS_SERVICE_TIMEOUT (MSEC_PER_SEC * 4 ) /* ms */
382407struct dns_resolve_context * ctx ;
408+ char * cp ;
383409char * service ;
410+ uint16_t port ;
384411uint16_t dns_id ;
385412int ret , arg = 1 ;
386413
@@ -390,18 +417,109 @@ static int cmd_net_dns_service(const struct shell *sh, size_t argc, char *argv[]
390417return - ENOEXEC ;
391418}
392419
420+ /* remove any lingering info data */
421+ k_msgq_purge (& dns_infoq );
422+
393423ctx = dns_resolve_get_default ();
394424if (ctx == NULL ) {
395425PR_WARNING ("No default DNS context found.\n" );
396426return - ENOEXEC ;
397427}
398428
399- ret = dns_resolve_service (ctx , service , & dns_id , dns_result_cb ,
400- (void * )sh , DNS_TIMEOUT );
429+ ret = dns_resolve_service (ctx , service , & dns_id , dns_service_cb ,
430+ (void * )sh , DNS_SERVICE_TIMEOUT );
401431if (ret < 0 ) {
402432PR_WARNING ("Cannot resolve '%s' (%d)\n" , service , ret );
403- } else {
404- PR ("Query for '%s' sent.\n" , service );
433+ return ret ;
434+ }
435+
436+ PR ("Resolve for '%s' service sent.\n" , service );
437+ port = 0 ;
438+ for (;;) {
439+ struct dns_addrinfo info ;
440+ enum dns_query_type qtype ;
441+ char query [DNS_MAX_NAME_SIZE + 1 ];
442+ union {
443+ char in4 [INET_ADDRSTRLEN ];
444+ char in6 [INET6_ADDRSTRLEN ];
445+ } str ;
446+
447+ ret = k_msgq_get (& dns_infoq , & info , K_MSEC (DNS_SERVICE_TIMEOUT ));
448+ if (ret < 0 ) {
449+ /* just assume a timeout so no more data to process */
450+ break ;
451+ }
452+
453+ switch (info .ai_family ) {
454+ case AF_INET :
455+ cp = net_addr_ntop (AF_INET ,
456+ & net_sin (& info .ai_addr )-> sin_addr ,
457+ str .in4 , sizeof (str .in4 ));
458+ PR ("AF_INET %s:%u\n" , cp ? cp : "<invalid>" , port );
459+ break ;
460+
461+ case AF_INET6 :
462+ cp = net_addr_ntop (AF_INET6 ,
463+ & net_sin6 (& info .ai_addr )-> sin6_addr ,
464+ str .in6 , sizeof (str .in6 ));
465+ PR ("AF_INET6 [%s]:%u\n" , cp ? cp : "<invalid>" , port );
466+ break ;
467+
468+ case AF_LOCAL :
469+ PR ("AF_LOCAL %.*s\n" ,
470+ (int )info .ai_addrlen , info .ai_canonname );
471+
472+ snprintf (query , sizeof (query ), "%.*s" ,
473+ info .ai_addrlen , info .ai_canonname );
474+
475+ qtype = DNS_QUERY_TYPE_SRV ;
476+ ret = dns_resolve_name (ctx , query , qtype ,
477+ & dns_id ,
478+ dns_service_cb , (void * )sh ,
479+ DNS_SERVICE_TIMEOUT );
480+ if (ret < 0 ) {
481+ return ret ;
482+ }
483+ break ;
484+
485+ case AF_UNSPEC :
486+ if (info .ai_extension == DNS_RESOLVE_SRV ) {
487+ PR ("SRV %d %d %d %.*s\n" ,
488+ info .ai_srv .priority ,
489+ info .ai_srv .weight ,
490+ info .ai_srv .port ,
491+ (int )info .ai_srv .targetlen ,
492+ info .ai_srv .target );
493+
494+ port = info .ai_srv .port ;
495+
496+ snprintf (query , sizeof (query ), "%.*s" ,
497+ info .ai_srv .targetlen ,
498+ info .ai_srv .target );
499+
500+ /*
501+ * Sending a query for both AAAA and A records
502+ * should be ok, but the resolver doesn't
503+ * gracefully handle the query for different
504+ * types.
505+ */
506+ qtype = DNS_QUERY_TYPE_AAAA ;
507+ ret = dns_resolve_name (ctx , query , qtype ,
508+ & dns_id ,
509+ dns_service_cb ,
510+ (void * )sh ,
511+ DNS_SERVICE_TIMEOUT );
512+ if (ret < 0 ) {
513+ return ret ;
514+ }
515+ break ;
516+ }
517+
518+ __fallthrough ;
519+ default :
520+ PR_WARNING ("dns: unhandled info %u on msgq\n" , info .ai_family );
521+ break ;
522+ }
405523}
406524#else
407525PR_INFO ("DNS resolver not supported. Set CONFIG_DNS_RESOLVER to "
0 commit comments