Skip to content

Commit 6db6a46

Browse files
author
Dmitry Rozhkov
committed
resolved: put DNS-SD records to mDNS-enabled zones.
1 parent 6501dd3 commit 6db6a46

File tree

8 files changed

+187
-0
lines changed

8 files changed

+187
-0
lines changed

src/resolve/resolved-dns-scope.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "hostname-util.h"
2828
#include "missing.h"
2929
#include "random-util.h"
30+
#include "resolved-dnssd.h"
3031
#include "resolved-dns-scope.h"
3132
#include "resolved-llmnr.h"
3233
#include "resolved-mdns.h"
@@ -1123,3 +1124,58 @@ int dns_scope_announce(DnsScope *scope, bool goodbye) {
11231124

11241125
return 0;
11251126
}
1127+
1128+
int dns_scope_add_dnssd_services(DnsScope *scope) {
1129+
Iterator i;
1130+
DnssdService *service;
1131+
int r;
1132+
1133+
assert(scope);
1134+
1135+
if (hashmap_size(scope->manager->dnssd_services) == 0)
1136+
return 0;
1137+
1138+
scope->announced = false;
1139+
1140+
HASHMAP_FOREACH(service, scope->manager->dnssd_services, i) {
1141+
r = dns_zone_put(&scope->zone, scope, service->ptr_rr, false);
1142+
if (r < 0)
1143+
log_warning_errno(r, "Failed to add PTR record to MDNS zone: %m");
1144+
1145+
r = dns_zone_put(&scope->zone, scope, service->srv_rr, true);
1146+
if (r < 0)
1147+
log_warning_errno(r, "Failed to add SRV record to MDNS zone: %m");
1148+
1149+
r = dns_zone_put(&scope->zone, scope, service->txt_rr, true);
1150+
if (r < 0)
1151+
log_warning_errno(r, "Failed to add TXT record to MDNS zone: %m");
1152+
}
1153+
1154+
return 0;
1155+
}
1156+
1157+
int dns_scope_remove_dnssd_services(DnsScope *scope) {
1158+
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1159+
Iterator i;
1160+
DnssdService *service;
1161+
int r;
1162+
1163+
assert(scope);
1164+
1165+
key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_PTR,
1166+
"_services._dns-sd._udp.local");
1167+
if (!key)
1168+
return log_oom();
1169+
1170+
r = dns_zone_remove_rrs_by_key(&scope->zone, key);
1171+
if (r < 0)
1172+
return r;
1173+
1174+
HASHMAP_FOREACH(service, scope->manager->dnssd_services, i) {
1175+
dns_zone_remove_rr(&scope->zone, service->ptr_rr);
1176+
dns_zone_remove_rr(&scope->zone, service->srv_rr);
1177+
dns_zone_remove_rr(&scope->zone, service->txt_rr);
1178+
}
1179+
1180+
return 0;
1181+
}

src/resolve/resolved-dns-scope.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,7 @@ bool dns_scope_network_good(DnsScope *s);
119119
int dns_scope_ifindex(DnsScope *s);
120120

121121
int dns_scope_announce(DnsScope *scope, bool goodbye);
122+
123+
int dns_scope_add_dnssd_services(DnsScope *scope);
124+
125+
int dns_scope_remove_dnssd_services(DnsScope *scope);

src/resolve/resolved-dns-zone.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,22 @@ void dns_zone_remove_rr(DnsZone *z, DnsResourceRecord *rr) {
119119
dns_zone_item_remove_and_free(z, i);
120120
}
121121

122+
int dns_zone_remove_rrs_by_key(DnsZone *z, DnsResourceKey *key) {
123+
_cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
124+
DnsResourceRecord *rr;
125+
bool tentative;
126+
int r;
127+
128+
r = dns_zone_lookup(z, key, 0, &answer, &soa, &tentative);
129+
if (r < 0)
130+
return r;
131+
132+
DNS_ANSWER_FOREACH(rr, answer)
133+
dns_zone_remove_rr(z, rr);
134+
135+
return 0;
136+
}
137+
122138
static int dns_zone_init(DnsZone *z) {
123139
int r;
124140

src/resolve/resolved-dns-zone.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ void dns_zone_flush(DnsZone *z);
6868

6969
int dns_zone_put(DnsZone *z, DnsScope *s, DnsResourceRecord *rr, bool probe);
7070
void dns_zone_remove_rr(DnsZone *z, DnsResourceRecord *rr);
71+
int dns_zone_remove_rrs_by_key(DnsZone *z, DnsResourceKey *key);
7172

7273
int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, int ifindex, DnsAnswer **answer, DnsAnswer **soa, bool *tentative);
7374

src/resolve/resolved-dnssd.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ static int dnssd_service_load(Manager *manager, const char *filename) {
119119

120120
service->manager = manager;
121121

122+
r = dnssd_update_rrs(service);
123+
if (r < 0)
124+
return r;
125+
122126
service = NULL;
123127

124128
return 0;
@@ -192,6 +196,73 @@ int dnssd_load(Manager *manager) {
192196
return 0;
193197
}
194198

199+
int dnssd_update_rrs(DnssdService *s) {
200+
_cleanup_free_ char *n = NULL;
201+
_cleanup_free_ char *service_name = NULL;
202+
_cleanup_free_ char *full_name = NULL;
203+
int r;
204+
205+
assert(s);
206+
assert(s->txt);
207+
assert(s->manager);
208+
209+
s->ptr_rr = dns_resource_record_unref(s->ptr_rr);
210+
s->srv_rr = dns_resource_record_unref(s->srv_rr);
211+
s->txt_rr = dns_resource_record_unref(s->txt_rr);
212+
213+
r = dnssd_render_instance_name(s, &n);
214+
if (r < 0)
215+
return r;
216+
217+
r = dns_name_concat(s->type, "local", &service_name);
218+
if (r < 0)
219+
return r;
220+
r = dns_name_concat(n, service_name, &full_name);
221+
if (r < 0)
222+
return r;
223+
224+
s->txt_rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_TXT,
225+
full_name);
226+
if (!s->txt_rr)
227+
goto oom;
228+
229+
s->txt_rr->ttl = MDNS_DEFAULT_TTL;
230+
s->txt_rr->txt.items = dns_txt_item_copy(s->txt);
231+
if (!s->txt_rr->txt.items)
232+
goto oom;
233+
234+
s->ptr_rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_PTR,
235+
service_name);
236+
if (!s->ptr_rr)
237+
goto oom;
238+
239+
s->ptr_rr->ttl = MDNS_DEFAULT_TTL;
240+
s->ptr_rr->ptr.name = strdup(full_name);
241+
if (!s->ptr_rr->ptr.name)
242+
goto oom;
243+
244+
s->srv_rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_SRV,
245+
full_name);
246+
if (!s->srv_rr)
247+
goto oom;
248+
249+
s->srv_rr->ttl = MDNS_DEFAULT_TTL;
250+
s->srv_rr->srv.priority = s->priority;
251+
s->srv_rr->srv.weight = s->weight;
252+
s->srv_rr->srv.port = s->port;
253+
s->srv_rr->srv.name = strdup(s->manager->mdns_hostname);
254+
if (!s->srv_rr->srv.name)
255+
goto oom;
256+
257+
return 0;
258+
259+
oom:
260+
s->txt_rr = dns_resource_record_unref(s->txt_rr);
261+
s->ptr_rr = dns_resource_record_unref(s->ptr_rr);
262+
s->srv_rr = dns_resource_record_unref(s->srv_rr);
263+
return -ENOMEM;
264+
}
265+
195266
int dnssd_txt_item_new_from_string(const char *key, const char *value, DnsTxtItem **ret_item) {
196267
size_t length;
197268
DnsTxtItem *i;

src/resolve/resolved-dnssd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,4 @@ int dnssd_render_instance_name(DnssdService *s, char **ret_name);
5555
int dnssd_load(Manager *manager);
5656
int dnssd_txt_item_new_from_string(const char *key, const char *value, DnsTxtItem **ret_item);
5757
int dnssd_txt_item_new_from_data(const char *key, const void *value, const size_t size, DnsTxtItem **ret_item);
58+
int dnssd_update_rrs(DnssdService *s);

src/resolve/resolved-link.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,41 @@ void link_allocate_scopes(Link *l) {
191191

192192
void link_add_rrs(Link *l, bool force_remove) {
193193
LinkAddress *a;
194+
int r;
194195

195196
LIST_FOREACH(addresses, a, l->addresses)
196197
link_address_add_rrs(a, force_remove);
198+
199+
if (!force_remove &&
200+
l->mdns_support == RESOLVE_SUPPORT_YES &&
201+
l->manager->mdns_support == RESOLVE_SUPPORT_YES) {
202+
203+
if (l->mdns_ipv4_scope) {
204+
r = dns_scope_add_dnssd_services(l->mdns_ipv4_scope);
205+
if (r < 0)
206+
log_warning_errno(r, "Failed to add IPv4 DNS-SD services: %m");
207+
}
208+
209+
if (l->mdns_ipv6_scope) {
210+
r = dns_scope_add_dnssd_services(l->mdns_ipv6_scope);
211+
if (r < 0)
212+
log_warning_errno(r, "Failed to add IPv6 DNS-SD services: %m");
213+
}
214+
215+
} else {
216+
217+
if (l->mdns_ipv4_scope) {
218+
r = dns_scope_remove_dnssd_services(l->mdns_ipv4_scope);
219+
if (r < 0)
220+
log_warning_errno(r, "Failed to remove IPv4 DNS-SD services: %m");
221+
}
222+
223+
if (l->mdns_ipv6_scope) {
224+
r = dns_scope_remove_dnssd_services(l->mdns_ipv6_scope);
225+
if (r < 0)
226+
log_warning_errno(r, "Failed to remove IPv6 DNS-SD services: %m");
227+
}
228+
}
197229
}
198230

199231
int link_process_rtnl(Link *l, sd_netlink_message *m) {

src/resolve/resolved-manager.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,7 @@ int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_a
11041104
void manager_refresh_rrs(Manager *m) {
11051105
Iterator i;
11061106
Link *l;
1107+
DnssdService *s;
11071108

11081109
assert(m);
11091110

@@ -1112,6 +1113,11 @@ void manager_refresh_rrs(Manager *m) {
11121113
m->mdns_host_ipv4_key = dns_resource_key_unref(m->mdns_host_ipv4_key);
11131114
m->mdns_host_ipv6_key = dns_resource_key_unref(m->mdns_host_ipv6_key);
11141115

1116+
if (m->mdns_support == RESOLVE_SUPPORT_YES)
1117+
HASHMAP_FOREACH(s, m->dnssd_services, i)
1118+
if (dnssd_update_rrs(s) < 0)
1119+
log_warning("Failed to refresh DNS-SD service '%s'", s->name);
1120+
11151121
HASHMAP_FOREACH(l, m->links, i) {
11161122
link_add_rrs(l, true);
11171123
link_add_rrs(l, false);

0 commit comments

Comments
 (0)