Use unicast IP address when sending unicast service reply
[project/mdnsd.git] / announce.c
1 /*
2  * Copyright (C) 2014 John Crispin <blogic@openwrt.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License version 2.1
6  * as published by the Free Software Foundation
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #include <sys/types.h>
15
16 #include <stdio.h>
17
18 #include <libubox/uloop.h>
19
20 #include "cache.h"
21 #include "dns.h"
22 #include "util.h"
23 #include "service.h"
24 #include "announce.h"
25 #include "interface.h"
26
27 #define TTL_TIMEOUT     75
28
29 enum {
30         STATE_PROBE1 = 0,
31         STATE_PROBE2,
32         STATE_PROBE3,
33         STATE_PROBE_WAIT,
34         STATE_PROBE_END,
35         STATE_ANNOUNCE,
36 };
37
38 int announce_ttl = 75 * 60;
39
40 static void
41 announce_timer(struct uloop_timeout *timeout)
42 {
43         struct interface *iface = container_of(timeout, struct interface, announce_timer);
44
45         switch (iface->announce_state) {
46                 case STATE_PROBE1:
47                 case STATE_PROBE2:
48                 case STATE_PROBE3:
49                         dns_send_question(iface, mdns_hostname_local, TYPE_ANY, 1);
50                         uloop_timeout_set(timeout, 250);
51                         iface->announce_state++;
52                         break;
53
54                 case STATE_PROBE_WAIT:
55                         uloop_timeout_set(timeout, 500);
56                         iface->announce_state++;
57                         break;
58
59                 case STATE_PROBE_END:
60                         if (cache_host_is_known(mdns_hostname_local)) {
61                                 fprintf(stderr, "the host %s already exists. stopping announce service\n", mdns_hostname_local);
62                                 return;
63                         }
64                         iface->announce_state++;
65                         /* Fall through */
66
67                 case STATE_ANNOUNCE:
68                         dns_reply_a(iface, NULL, announce_ttl);
69                         service_announce_services(iface, NULL, announce_ttl);
70                         uloop_timeout_set(timeout, announce_ttl * 800);
71                         break;
72         }
73 }
74
75 void
76 announce_init(struct interface *iface)
77 {
78         iface->announce_state = STATE_PROBE1;
79         iface->announce_timer.cb = announce_timer;
80         uloop_timeout_set(&iface->announce_timer, 100);
81 }
82
83 void
84 announce_free(struct interface *iface)
85 {
86         uloop_timeout_cancel(&iface->announce_timer);
87 }