Skip to content

Commit a26a222

Browse files
SynchronicITfabiobaltieri
authored andcommitted
net: mdns: adding MDNS unicast response confirm rfc6732
Conform rfc6762 a mDNS responder should answer clients which are not using the mDNS port in the source address with unicast UDP to the same port as described in chapter 6.7 Fixes: #81657 Signed-off-by: Vincent van der Locht <[email protected]>
1 parent d9c5c8d commit a26a222

File tree

1 file changed

+31
-15
lines changed

1 file changed

+31
-15
lines changed

subsys/net/lib/dns/mdns_responder.c

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* Copyright (c) 2017 Intel Corporation
99
* Copyright (c) 2020 Friedt Professional Engineering Services, Inc
1010
* Copyright (c) 2024 Nordic Semiconductor ASA
11+
* Copyright (c) 2025 SynchronicIT BV
1112
*
1213
* SPDX-License-Identifier: Apache-2.0
1314
*/
@@ -110,6 +111,7 @@ static size_t external_records_count;
110111

111112
#ifndef CONFIG_NET_TEST
112113
static int setup_dst_addr(int sock, sa_family_t family,
114+
struct sockaddr *src, socklen_t src_len,
113115
struct sockaddr *dst, socklen_t *dst_len);
114116
#endif /* CONFIG_NET_TEST */
115117

@@ -194,25 +196,36 @@ static int set_ttl_hop_limit(int sock, int level, int option, int new_limit)
194196
}
195197

196198
int setup_dst_addr(int sock, sa_family_t family,
199+
struct sockaddr *src, socklen_t src_len,
197200
struct sockaddr *dst, socklen_t *dst_len)
198201
{
199202
int ret;
200203

201204
if (IS_ENABLED(CONFIG_NET_IPV4) && family == AF_INET) {
202-
create_ipv4_addr(net_sin(dst));
203-
*dst_len = sizeof(struct sockaddr_in);
205+
if ((src != NULL) && (net_sin(src)->sin_port != htons(MDNS_LISTEN_PORT))) {
206+
memcpy(dst, src, src_len);
207+
*dst_len = src_len;
208+
} else {
209+
create_ipv4_addr(net_sin(dst));
210+
*dst_len = sizeof(struct sockaddr_in);
204211

205-
ret = set_ttl_hop_limit(sock, IPPROTO_IP, IP_MULTICAST_TTL, 255);
206-
if (ret < 0) {
207-
NET_DBG("Cannot set %s multicast %s (%d)", "IPv4", "TTL", ret);
212+
ret = set_ttl_hop_limit(sock, IPPROTO_IP, IP_MULTICAST_TTL, 255);
213+
if (ret < 0) {
214+
NET_DBG("Cannot set %s multicast %s (%d)", "IPv4", "TTL", ret);
215+
}
208216
}
209217
} else if (IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) {
210-
create_ipv6_addr(net_sin6(dst));
211-
*dst_len = sizeof(struct sockaddr_in6);
218+
if ((src != NULL) && (net_sin6(src)->sin6_port != htons(MDNS_LISTEN_PORT))) {
219+
memcpy(dst, src, src_len);
220+
*dst_len = src_len;
221+
} else {
222+
create_ipv6_addr(net_sin6(dst));
223+
*dst_len = sizeof(struct sockaddr_in6);
212224

213-
ret = set_ttl_hop_limit(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 255);
214-
if (ret < 0) {
215-
NET_DBG("Cannot set %s multicast %s (%d)", "IPv6", "hoplimit", ret);
225+
ret = set_ttl_hop_limit(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 255);
226+
if (ret < 0) {
227+
NET_DBG("Cannot set %s multicast %s (%d)", "IPv6", "hoplimit", ret);
228+
}
216229
}
217230
} else {
218231
return -EPFNOSUPPORT;
@@ -346,7 +359,7 @@ static int send_response(int sock,
346359
COND_CODE_1(IS_ENABLED(CONFIG_NET_IPV6),
347360
(struct sockaddr_in6), (struct sockaddr_in)) dst;
348361

349-
ret = setup_dst_addr(sock, family, (struct sockaddr *)&dst, &dst_len);
362+
ret = setup_dst_addr(sock, family, src_addr, addrlen, (struct sockaddr *)&dst, &dst_len);
350363
if (ret < 0) {
351364
NET_DBG("unable to set up the response address");
352365
return ret;
@@ -456,7 +469,7 @@ static void send_sd_response(int sock,
456469
label[2] = proto_buf;
457470
label[3] = domain_buf;
458471

459-
ret = setup_dst_addr(sock, family, (struct sockaddr *)&dst, &dst_len);
472+
ret = setup_dst_addr(sock, family, src_addr, addrlen, (struct sockaddr *)&dst, &dst_len);
460473
if (ret < 0) {
461474
NET_DBG("unable to set up the response address");
462475
return;
@@ -608,12 +621,15 @@ static int dns_read(int sock,
608621

609622
queries = ret;
610623

611-
NET_DBG("Received %d %s from %s", queries,
624+
NET_DBG("Received %d %s from %s:%u", queries,
612625
queries > 1 ? "queries" : "query",
613626
net_sprint_addr(family,
614627
family == AF_INET ?
615628
(const void *)&net_sin(src_addr)->sin_addr :
616-
(const void *)&net_sin6(src_addr)->sin6_addr));
629+
(const void *)&net_sin6(src_addr)->sin6_addr),
630+
ntohs(family == AF_INET ?
631+
net_sin(src_addr)->sin_port :
632+
net_sin6(src_addr)->sin6_port));
617633

618634
do {
619635
enum dns_rr_type qtype;
@@ -1525,7 +1541,7 @@ static int send_unsolicited_response(struct net_if *iface,
15251541
COND_CODE_1(IS_ENABLED(CONFIG_NET_IPV6),
15261542
(struct sockaddr_in6), (struct sockaddr_in)) dst;
15271543

1528-
ret = setup_dst_addr(sock, family, (struct sockaddr *)&dst, &dst_len);
1544+
ret = setup_dst_addr(sock, family, NULL, 0, (struct sockaddr *)&dst, &dst_len);
15291545
if (ret < 0) {
15301546
NET_DBG("unable to set up the response address");
15311547
return ret;

0 commit comments

Comments
 (0)