case STATE_ANNOUNCE:
dns_reply_a(iface, NULL, announce_ttl);
- service_announce_services(iface, announce_ttl);
+ service_announce_services(iface, NULL, announce_ttl);
uloop_timeout_set(timeout, announce_ttl * 800);
break;
}
}
static void
-parse_question(struct interface *iface, char *name, struct dns_question *q)
+parse_question(struct interface *iface, struct sockaddr *from, char *name, struct dns_question *q)
{
+ struct sockaddr *to;
char *host;
- if ((q->class & CLASS_UNICAST) && iface->multicast)
+ /* TODO: Multicast if more than one quarter of TTL has passed */
+ if ((q->class & CLASS_UNICAST) && iface->multicast) {
iface = iface->peer;
+ to = from;
+ } else {
+ to = NULL;
+ }
DBG(1, "Q -> %s %s\n", dns_type_string(q->type), name);
switch (q->type) {
case TYPE_ANY:
if (!strcmp(name, mdns_hostname_local)) {
- service_reply(iface, NULL, announce_ttl);
- dns_reply_a(iface, NULL, announce_ttl);
+ dns_reply_a(iface, to, announce_ttl);
+ service_reply(iface, to, NULL, announce_ttl);
}
break;
case TYPE_PTR:
if (!strcmp(name, sdudp)) {
- service_announce_services(iface, announce_ttl);
+ service_announce_services(iface, to, announce_ttl);
} else {
/* First dot separates instance name from the rest */
char *dot = strchr(name, '.');
/* Make sure it's query for the instance name we use */
if (len && len == strlen(mdns_hostname) &&
!strncmp(name, mdns_hostname, len))
- service_reply(iface, dot + 1, announce_ttl);
+ service_reply(iface, to, dot + 1, announce_ttl);
}
break;
if (host)
*host = '\0';
if (!strcmp(mdns_hostname, name))
- dns_reply_a(iface, NULL, announce_ttl);
+ dns_reply_a(iface, to, announce_ttl);
break;
};
}
}
if (!(h->flags & FLAG_RESPONSE))
- parse_question(iface, name, q);
+ parse_question(iface, s, name, q);
}
if (!(h->flags & FLAG_RESPONSE))
vlist_for_each_element(&interfaces, iface, node)
if (iface->fd.fd > 0 && iface->multicast) {
dns_reply_a(iface, NULL, 0);
- service_announce_services(iface, 0);
+ service_announce_services(iface, NULL, 0);
}
vlist_for_each_element(&interfaces, iface, node)
interface_close(iface);
}
static void
-service_reply_single(struct interface *iface, struct service *s, int ttl, int force)
+service_reply_single(struct interface *iface, struct sockaddr *to, struct service *s, int ttl, int force)
{
const char *host = service_name(s->service);
char *service = strstr(host, "._");
dns_init_answer();
service_add_ptr(service_name(s->service), ttl);
- dns_send_answer(iface, NULL, service);
+ dns_send_answer(iface, to, service);
dns_init_answer();
service_add_srv(s, ttl);
if (s->txt && s->txt_len)
dns_add_answer(TYPE_TXT, (uint8_t *) s->txt, s->txt_len, ttl);
- dns_send_answer(iface, NULL, host);
+ dns_send_answer(iface, to, host);
}
void
-service_reply(struct interface *iface, const char *match, int ttl)
+service_reply(struct interface *iface, struct sockaddr *to, const char *match, int ttl)
{
struct service *s;
vlist_for_each_element(&services, s, node) {
if (!match || !strcmp(s->service, match))
- service_reply_single(iface, s, ttl, 0);
+ service_reply_single(iface, to, s, ttl, 0);
}
}
void
-service_announce_services(struct interface *iface, int ttl)
+service_announce_services(struct interface *iface, struct sockaddr *to, int ttl)
{
struct service *s;
if (ttl) {
dns_init_answer();
service_add_ptr(s->service, ttl);
- dns_send_answer(iface, NULL, sdudp);
+ dns_send_answer(iface, to, sdudp);
}
- service_reply_single(iface, s, ttl, 0);
+ service_reply_single(iface, to, s, ttl, 0);
}
}
if (service_init_announce)
vlist_for_each_element(&interfaces, iface, node) {
s->t = 0;
- service_reply_single(iface, s, announce_ttl, 1);
+ service_reply_single(iface, NULL, s, announce_ttl, 1);
}
return;
}
s = container_of(node_old, struct service, node);
if (!node_new && service_init_announce)
vlist_for_each_element(&interfaces, iface, node)
- service_reply_single(iface, s, 0, 1);
+ service_reply_single(iface, NULL, s, 0, 1);
free(s);
}
extern const char *sdudp;
extern void service_init(int announce);
extern void service_cleanup(void);
-extern void service_reply(struct interface *iface, const char *match, int ttl);
-extern void service_announce_services(struct interface *iface, int ttl);
+extern void service_reply(struct interface *iface, struct sockaddr *to, const char *match, int ttl);
+extern void service_announce_services(struct interface *iface, struct sockaddr *to, int ttl);
#endif