X-Git-Url: https://git.librecmc.org/?p=oweals%2Fmdnsd.git;a=blobdiff_plain;f=service.c;h=97b6f911121c2cd2b22334a4705e66f5a23d723c;hp=075ac15325fcc927cb9368eaedfe2b229cb86230;hb=HEAD;hpb=c78cfb1475f755c85949882e0d9d857a800348a1 diff --git a/service.c b/service.c index 075ac15..97b6f91 100644 --- a/service.c +++ b/service.c @@ -34,6 +34,7 @@ #include "announce.h" enum { + SERVICE_INSTANCE, SERVICE_SERVICE, SERVICE_PORT, SERVICE_TXT, @@ -46,6 +47,7 @@ struct service { time_t t; const char *id; + const char *instance; const char *service; const uint8_t *txt; int txt_len; @@ -54,6 +56,7 @@ struct service { }; static const struct blobmsg_policy service_policy[__SERVICE_MAX] = { + [SERVICE_INSTANCE] = { .name = "instance", .type = BLOBMSG_TYPE_STRING }, [SERVICE_SERVICE] = { .name = "service", .type = BLOBMSG_TYPE_STRING }, [SERVICE_PORT] = { .name = "port", .type = BLOBMSG_TYPE_INT32 }, [SERVICE_TXT] = { .name = "txt", .type = BLOBMSG_TYPE_ARRAY }, @@ -65,15 +68,23 @@ service_update(struct vlist_tree *tree, struct vlist_node *node_new, static struct blob_buf b; static VLIST_TREE(services, avl_strcmp, service_update, false, false); -const char *sdudp = "_services._dns-sd._udp.local"; static int service_init_announce; +/** + * service_instance_name - construct Service Instance Name as in RFC 6763 + * + * RFC 6763 specifies Service Instance Names in the following way: + * + * Service Instance Name = . . + * + * @s: service to generate service instance name for + */ static const char * -service_name(const char *domain) +service_instance_name(struct service *s) { static char buffer[256]; - snprintf(buffer, sizeof(buffer), "%s.%s", mdns_hostname, domain); + snprintf(buffer, sizeof(buffer), "%s.%s", s->instance, s->service); return buffer; } @@ -110,8 +121,10 @@ service_timeout(struct service *s) { time_t t = monotonic_time(); - if (t - s->t <= TOUT_LOOKUP) + if (t - s->t <= TOUT_LOOKUP) { + DBG(2, "t=%lu, s->t=%lu, t - s->t = %lu\n", t, s->t, t - s->t); return 0; + } return t; } @@ -119,7 +132,7 @@ service_timeout(struct service *s) static void service_reply_single(struct interface *iface, struct sockaddr *to, struct service *s, int ttl, int force) { - const char *host = service_name(s->service); + const char *host = service_instance_name(s); char *service = strstr(host, "._"); time_t t = service_timeout(s); @@ -132,7 +145,7 @@ service_reply_single(struct interface *iface, struct sockaddr *to, struct servic s->t = t; dns_init_answer(); - service_add_ptr(service_name(s->service), ttl); + service_add_ptr(service_instance_name(s), ttl); dns_send_answer(iface, to, service); dns_init_answer(); @@ -143,13 +156,16 @@ service_reply_single(struct interface *iface, struct sockaddr *to, struct servic } void -service_reply(struct interface *iface, struct sockaddr *to, const char *match, int ttl) +service_reply(struct interface *iface, struct sockaddr *to, const char *instance, const char *service_domain, int ttl) { struct service *s; vlist_for_each_element(&services, s, node) { - if (!match || !strcmp(s->service, match)) - service_reply_single(iface, to, s, ttl, 0); + if (instance && strcmp(s->instance, instance)) + continue; + if (service_domain && strcmp(s->service, service_domain)) + continue; + service_reply_single(iface, to, s, ttl, 0); } } @@ -163,7 +179,7 @@ service_announce_services(struct interface *iface, struct sockaddr *to, int ttl) if (ttl) { dns_init_answer(); service_add_ptr(s->service, ttl); - dns_send_answer(iface, to, sdudp); + dns_send_answer(iface, to, C_DNS_SD); } service_reply_single(iface, to, s, ttl, 0); } @@ -198,7 +214,7 @@ service_load_blob(struct blob_attr *b) { struct blob_attr *txt, *_tb[__SERVICE_MAX]; struct service *s; - char *d_service, *d_id; + char *d_instance, *d_service, *d_id; uint8_t *d_txt; int rem2; int txt_len = 0; @@ -214,6 +230,7 @@ service_load_blob(struct blob_attr *b) s = calloc_a(sizeof(*s), &d_id, strlen(blobmsg_name(b)) + 1, + &d_instance, _tb[SERVICE_INSTANCE] ? strlen(blobmsg_get_string(_tb[SERVICE_INSTANCE])) + 1 : 0, &d_service, strlen(blobmsg_get_string(_tb[SERVICE_SERVICE])) + 1, &d_txt, txt_len); if (!s) @@ -221,6 +238,10 @@ service_load_blob(struct blob_attr *b) s->port = blobmsg_get_u32(_tb[SERVICE_PORT]); s->id = strcpy(d_id, blobmsg_name(b)); + if (_tb[SERVICE_INSTANCE]) + s->instance = strcpy(d_instance, blobmsg_get_string(_tb[SERVICE_INSTANCE])); + else + s->instance = umdns_host_label; s->service = strcpy(d_service, blobmsg_get_string(_tb[SERVICE_SERVICE])); s->active = 1; s->t = 0;