move rdata_buffer to cache_answer()
[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 char host[256];
45
46 snprintf(host, sizeof(host), "%s.local", hostname);
47
48 switch (iface->announce_state) {
49 case STATE_PROBE1:
50 case STATE_PROBE2:
51 case STATE_PROBE3:
52 dns_send_question(iface, host, TYPE_ANY);
53 uloop_timeout_set(timeout, 250);
54 iface->announce_state++;
55 break;
56
57 case STATE_PROBE_WAIT:
58 uloop_timeout_set(timeout, 500);
59 iface->announce_state++;
60 break;
61
62 case STATE_PROBE_END:
63 if (cache_host_is_known(host)) {
64 fprintf(stderr, "the host %s already exists. stopping announce service\n", host);
65 return;
66 }
67 iface->announce_state++;
68
69 case STATE_ANNOUNCE:
70 service_announce(iface);
71 uloop_timeout_set(timeout, announce_ttl * 800);
72 break;
73 }
74 }
75
76 void
77 announce_init(struct interface *iface)
78 {
79 iface->announce_state = STATE_PROBE1;
80 iface->announce_timer.cb = announce_timer;
81 uloop_timeout_set(&iface->announce_timer, 100);
82 }
83
84 void
85 announce_free(struct interface *iface)
86 {
87 uloop_timeout_cancel(&iface->announce_timer);
88 }