From: Tobias Waldvogel Date: Wed, 11 Dec 2024 14:34:33 +0000 (+0100) Subject: fix unicast response port and timeout X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=68af31143b1fb36922befeb3eb332b3cb4911960;p=project%2Fmdnsd.git fix unicast response port and timeout Responses to One-Shot Multicast DNS Queries (as in RFC 6762 5.1) with CLASS_UNICAST set should be sent back to the port of the client and not to 5353. In addition timeouts should be ignored. Signed-off-by: Tobias Waldvogel --- diff --git a/dns.c b/dns.c index f6f0be5..e849396 100644 --- a/dns.c +++ b/dns.c @@ -357,12 +357,13 @@ static int parse_answer(struct interface *iface, struct sockaddr *from, static void parse_question(struct interface *iface, struct sockaddr *from, char *name, struct dns_question *q) { + int is_unicast = (q->class & CLASS_UNICAST) != 0; struct sockaddr *to = NULL; struct hostname *h; char *host; /* TODO: Multicast if more than one quarter of TTL has passed */ - if (q->class & CLASS_UNICAST) { + if (is_unicast) { to = from; if (interface_multicast(iface)) iface = interface_get(iface->name, iface->type | SOCKTYPE_BIT_UNICAST); @@ -375,7 +376,7 @@ parse_question(struct interface *iface, struct sockaddr *from, char *name, struc if (!strcmp(name, mdns_hostname_local)) { dns_reply_a(iface, to, announce_ttl, NULL); dns_reply_a_additional(iface, to, announce_ttl); - service_reply(iface, to, NULL, NULL, announce_ttl); + service_reply(iface, to, NULL, NULL, announce_ttl, is_unicast); } break; @@ -386,14 +387,14 @@ parse_question(struct interface *iface, struct sockaddr *from, char *name, struc service_announce_services(iface, to, announce_ttl); } else { if (name[0] == '_') { - service_reply(iface, to, NULL, name, announce_ttl); + service_reply(iface, to, NULL, name, announce_ttl, is_unicast); } else { /* First dot separates instance name from the rest */ char *dot = strchr(name, '.'); if (dot) { *dot = '\0'; - service_reply(iface, to, name, dot + 1, announce_ttl); + service_reply(iface, to, name, dot + 1, announce_ttl, is_unicast); *dot = '.'; } } diff --git a/interface.c b/interface.c index ad25b39..944666f 100644 --- a/interface.c +++ b/interface.c @@ -84,6 +84,7 @@ interface_send_packet4(struct interface *iface, struct sockaddr_in *to, struct i fprintf(stderr, "Ignoring IPv4 address for multicast interface\n"); } else { a.sin_addr.s_addr = to->sin_addr.s_addr; + a.sin_port = to->sin_port; } return sendmsg(fd, &m, 0); diff --git a/service.c b/service.c index 1f81031..9d3767b 100644 --- a/service.c +++ b/service.c @@ -144,7 +144,7 @@ service_reply_single(struct interface *iface, struct sockaddr *to, struct servic } void -service_reply(struct interface *iface, struct sockaddr *to, const char *instance, const char *service_domain, int ttl) +service_reply(struct interface *iface, struct sockaddr *to, const char *instance, const char *service_domain, int ttl, int force) { struct service *s; @@ -153,7 +153,7 @@ service_reply(struct interface *iface, struct sockaddr *to, const char *instance continue; if (service_domain && strcmp(s->service, service_domain)) continue; - service_reply_single(iface, to, s, ttl, 0); + service_reply_single(iface, to, s, ttl, force); } } diff --git a/service.h b/service.h index ea2a6ed..6cae5bb 100644 --- a/service.h +++ b/service.h @@ -41,7 +41,7 @@ extern struct vlist_tree announced_services; extern void service_init(int announce); extern void service_cleanup(void); -extern void service_reply(struct interface *iface, struct sockaddr *to, const char *instance, const char *service_domain, int ttl); +extern void service_reply(struct interface *iface, struct sockaddr *to, const char *instance, const char *service_domain, int ttl, int force); extern void service_announce_services(struct interface *iface, struct sockaddr *to, int ttl); extern void service_update(struct vlist_tree *tree, struct vlist_node *node_new, struct vlist_node *node_old);