static void withdraw_llmnr_entry(AvahiServer *s, AvahiEntry *e) { assert(s); assert(e); assert(e->type == AVAHI_ENTRY_LLMNR); /* Withdraw the specified entry, and if is part of an entry group, * put that into LLMNR_COLLISION state */ if (e->dead) return; if (e->group) { AvahiEntry *k; assert(e->group->type == AVAHI_GROUP_LLMNR); /* Withdraw all entries of that group */ for (k = e->group->entries; k; k = k->by_group_next) { assert(k->type == AVAHI_ENTRY_LLMNR); if (!k->dead) k->dead = 1; } e->group->proto.llmnr.n_verifying = 0; avahi_s_entry_group_change_state(e->group, AVAHI_ENTRY_GROUP_LLMNR_COLLISION); } else e->dead = 1; s->llmnr.need_entry_cleanup = 1; return; }
static void check_established (AvahiSEntryGroup *group) { assert(group); assert(group->type == AVAHI_GROUP_LLMNR); /* Check for the state */ if(group->proto.llmnr.n_verifying == 0) avahi_s_entry_group_change_state(group, AVAHI_ENTRY_GROUP_LLMNR_ESTABLISHED); }
static void entry_group_commit_real(AvahiSEntryGroup *g) { assert(g); gettimeofday(&g->register_time, NULL); avahi_s_entry_group_change_state(g, AVAHI_ENTRY_GROUP_REGISTERING); if (g->dead) return; avahi_announce_group(g->server, g); avahi_s_entry_group_check_probed(g, 0); }
void avahi_s_entry_group_reset(AvahiSEntryGroup *g) { AvahiEntry *e; assert(g); for (e = g->entries; e; e = e->by_group_next) { if (!e->dead) { avahi_goodbye_entry(g->server, e, 1, 1); e->dead = 1; } } g->server->need_entry_cleanup = 1; g->n_probing = 0; avahi_s_entry_group_change_state(g, AVAHI_ENTRY_GROUP_UNCOMMITED); }
void avahi_s_entry_group_check_probed(AvahiSEntryGroup *g, int immediately) { AvahiEntry *e; assert(g); assert(!g->dead && g->type == AVAHI_GROUP_MDNS); /* Check whether all group members have been probed */ if (g->state != AVAHI_ENTRY_GROUP_REGISTERING || g->proto.mdns.n_probing > 0) return; avahi_s_entry_group_change_state(g, AVAHI_ENTRY_GROUP_ESTABLISHED); if (g->dead) return; for (e = g->entries; e; e = e->by_group_next) { AvahiAnnouncer *a; assert(e->type == AVAHI_ENTRY_MDNS); for (a = e->proto.mdns.announcers; a; a = a->by_entry_next) { if (a->state != AVAHI_WAITING) continue; a->state = AVAHI_ANNOUNCING; if (immediately) { /* Shortcut */ a->n_iteration = 1; next_state(a); } else { struct timeval tv; a->n_iteration = 0; avahi_elapse_time(&tv, 0, AVAHI_ANNOUNCEMENT_JITTER_MSEC); set_timeout(a, &tv); } } } }
int avahi_s_entry_group_commit(AvahiSEntryGroup *g) { struct timeval now; assert(g); assert(!g->dead); if (g->state != AVAHI_ENTRY_GROUP_UNCOMMITED && g->state != AVAHI_ENTRY_GROUP_COLLISION) return avahi_server_set_errno(g->server, AVAHI_ERR_BAD_STATE); if (avahi_s_entry_group_is_empty(g)) return avahi_server_set_errno(g->server, AVAHI_ERR_IS_EMPTY); g->n_register_try++; avahi_timeval_add(&g->register_time, 1000*(g->n_register_try >= AVAHI_RR_RATE_LIMIT_COUNT ? AVAHI_RR_HOLDOFF_MSEC_RATE_LIMIT : AVAHI_RR_HOLDOFF_MSEC)); gettimeofday(&now, NULL); if (avahi_timeval_compare(&g->register_time, &now) <= 0) { /* Holdoff time passed, so let's start probing */ entry_group_commit_real(g); } else { /* Holdoff time has not yet passed, so let's wait */ assert(!g->register_time_event); g->register_time_event = avahi_time_event_new(g->server->time_event_queue, &g->register_time, entry_group_register_time_event_callback, g); avahi_s_entry_group_change_state(g, AVAHI_ENTRY_GROUP_REGISTERING); } return AVAHI_OK; }