4 #define FLX_ANNOUNCEMENT_JITTER_MSEC 0
6 static void remove_announcement(flxServer *s, flxAnnouncement *a) {
10 flx_time_event_queue_remove(s->time_event_queue, a->time_event);
12 FLX_LLIST_REMOVE(flxAnnouncement, by_interface, a->interface->announcements, a);
13 FLX_LLIST_REMOVE(flxAnnouncement, by_entry, a->entry->announcements, a);
18 static void elapse_announce(flxTimeEvent *e, void *userdata) {
19 flxAnnouncement *a = userdata;
26 flx_interface_post_response(a->interface, NULL, a->entry->record, FALSE);
28 if (a->n_announced++ <= 8)
31 g_message("Announcement #%i on interface %s.%i for entry [%s]", a->n_announced, a->interface->hardware->name, a->interface->protocol, t = flx_record_to_string(a->entry->record));
34 if (a->n_announced >= 4) {
35 g_message("Enough announcements for record [%s]", t = flx_record_to_string(a->entry->record));
37 remove_announcement(a->server, a);
39 flx_elapse_time(&tv, a->sec_delay*1000, FLX_ANNOUNCEMENT_JITTER_MSEC);
40 flx_time_event_queue_update(a->server->time_event_queue, a->time_event, &tv);
44 static void new_announcement(flxServer *s, flxInterface *i, flxServerEntry *e) {
53 g_message("NEW ANNOUNCEMENT: %s.%i [%s]", i->hardware->name, i->protocol, t = flx_record_to_string(e->record));
56 if (!flx_interface_match(i, e->interface, e->protocol) || !i->announcing)
59 /* We don't want duplicates */
60 for (a = e->announcements; a; a = a->by_entry_next)
61 if (a->interface == i)
64 g_message("New announcement on interface %s.%i for entry [%s]", i->hardware->name, i->protocol, t = flx_record_to_string(e->record));
67 flx_interface_post_response(i, NULL, e->record, FALSE);
69 a = g_new(flxAnnouncement, 1);
76 FLX_LLIST_PREPEND(flxAnnouncement, by_interface, i->announcements, a);
77 FLX_LLIST_PREPEND(flxAnnouncement, by_entry, e->announcements, a);
79 flx_elapse_time(&tv, a->sec_delay*1000, FLX_ANNOUNCEMENT_JITTER_MSEC);
80 a->time_event = flx_time_event_queue_add(s->time_event_queue, &tv, elapse_announce, a);
83 void flx_announce_interface(flxServer *s, flxInterface *i) {
92 g_message("ANNOUNCE INTERFACE");
94 for (e = s->entries; e; e = e->entry_next)
95 new_announcement(s, i, e);
98 static void announce_walk_callback(flxInterfaceMonitor *m, flxInterface *i, gpointer userdata) {
99 flxServerEntry *e = userdata;
105 new_announcement(m->server, i, e);
108 void flx_announce_entry(flxServer *s, flxServerEntry *e) {
112 g_message("ANNOUNCE ENTRY");
114 flx_interface_monitor_walk(s->monitor, e->interface, e->protocol, announce_walk_callback, e);
117 static flxRecord *make_goodbye_record(flxRecord *r) {
123 g_message("Preparing goodbye for record [%s]", t = flx_record_to_string(r));
126 g = flx_record_copy(r);
127 g_assert(g->ref == 1);
133 void flx_goodbye_interface(flxServer *s, flxInterface *i, gboolean goodbye) {
137 while (i->announcements)
138 remove_announcement(s, i->announcements);
140 if (goodbye && flx_interface_relevant(i)) {
143 for (e = s->entries; e; e = e->entry_next)
144 if (flx_interface_match(i, e->interface, e->protocol)) {
145 flxRecord *g = make_goodbye_record(e->record);
146 flx_interface_post_response(i, NULL, g, TRUE);
152 void flx_goodbye_entry(flxServer *s, flxServerEntry *e, gboolean goodbye) {
156 while (e->announcements)
157 remove_announcement(s, e->announcements);
160 flxRecord *g = make_goodbye_record(e->record);
161 flx_server_post_response(s, e->interface, e->protocol, g);
166 void flx_goodbye_all(flxServer *s, gboolean goodbye) {
171 for (e = s->entries; e; e = e->entry_next)
172 flx_goodbye_entry(s, e, goodbye);