-
- ret = avahi_server_add(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE | AVAHI_ENTRY_ALLOWMUTIPLE, r);
- avahi_record_unref(r);
-
- if (ret < 0)
- return ret;
-
- return avahi_server_add_dns_server_name(s, g, interface, protocol, domain, type, n, port);
-}
-
-int avahi_server_add_dns_server_name(
- AvahiServer *s,
- AvahiSEntryGroup *g,
- AvahiIfIndex interface,
- AvahiProtocol protocol,
- const char *domain,
- AvahiDNSServerType type,
- const char *name,
- uint16_t port /** should be 53 */) {
-
- int ret = -1;
- char t[256], *d = NULL, *n = NULL;
- AvahiRecord *r;
-
- assert(s);
- assert(name);
- assert(type == AVAHI_DNS_SERVER_UPDATE || type == AVAHI_DNS_SERVER_RESOLVE);
-
- if (port == 0)
- return avahi_server_set_errno(s, AVAHI_ERR_INVALID_PORT);
-
- if (!avahi_is_valid_domain_name(name))
- return avahi_server_set_errno(s, AVAHI_ERR_INVALID_HOST_NAME);
-
- if (domain && !avahi_is_valid_domain_name(domain))
- return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME);
-
-
- if (!domain)
- domain = s->domain_name;
-
- if (!(n = avahi_normalize_name(name)) ||
- !(d = avahi_normalize_name(domain))) {
- avahi_free(n);
- avahi_free(d);
- return avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY);
- }
-
- snprintf(t, sizeof(t), "%s.%s", type == AVAHI_DNS_SERVER_RESOLVE ? "_domain._udp" : "_dns-update._udp", d);
- avahi_free(d);
-
- if (!(r = avahi_record_new_full(t, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV, AVAHI_DEFAULT_TTL_HOST_NAME))) {
- avahi_free(n);
- return avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY);
- }
-
- r->data.srv.priority = 0;
- r->data.srv.weight = 0;
- r->data.srv.port = port;
- r->data.srv.name = n;
- ret = avahi_server_add(s, g, interface, protocol, AVAHI_ENTRY_NULL, r);
- avahi_record_unref(r);
-
- return ret;
-}
-
-static void post_query_callback(AvahiInterfaceMonitor *m, AvahiInterface *i, void* userdata) {
- AvahiKey *k = userdata;
-
- assert(m);
- assert(i);
- assert(k);
-
- avahi_interface_post_query(i, k, 0);
-}
-
-void avahi_server_post_query(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, AvahiKey *key) {
- assert(s);
- assert(key);
-
- avahi_interface_monitor_walk(s->monitor, interface, protocol, post_query_callback, key);
-}
-
-void avahi_s_entry_group_change_state(AvahiSEntryGroup *g, AvahiEntryGroupState state) {
- assert(g);
-
- if (g->state == state)
- return;
-
- assert(state <= AVAHI_ENTRY_GROUP_COLLISION);
-
- g->state = state;
-
- if (g->callback)
- g->callback(g->server, g, state, g->userdata);
-}
-
-AvahiSEntryGroup *avahi_s_entry_group_new(AvahiServer *s, AvahiSEntryGroupCallback callback, void* userdata) {
- AvahiSEntryGroup *g;
-
- assert(s);
-
- if (!(g = avahi_new(AvahiSEntryGroup, 1))) {
- avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY);
- return NULL;
- }
-
- g->server = s;
- g->callback = callback;
- g->userdata = userdata;
- g->dead = 0;
- g->state = AVAHI_ENTRY_GROUP_UNCOMMITED;
- g->n_probing = 0;
- g->n_register_try = 0;
- g->register_time_event = NULL;
- g->register_time.tv_sec = 0;
- g->register_time.tv_usec = 0;
- AVAHI_LLIST_HEAD_INIT(AvahiEntry, g->entries);
-
- AVAHI_LLIST_PREPEND(AvahiSEntryGroup, groups, s->groups, g);
- return g;
-}
-
-void avahi_s_entry_group_free(AvahiSEntryGroup *g) {
- AvahiEntry *e;
-
- assert(g);
- assert(g->server);
-
- for (e = g->entries; e; e = e->by_group_next) {
- if (!e->dead) {
- avahi_goodbye_entry(g->server, e, 1);
- e->dead = 1;
- }
- }
-
- if (g->register_time_event) {
- avahi_time_event_free(g->register_time_event);
- g->register_time_event = NULL;
- }
-
- g->dead = 1;
-
- g->server->need_group_cleanup = 1;
- g->server->need_entry_cleanup = 1;
-}
-
-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) {
- avahi_announce_group(g->server, g);
- avahi_s_entry_group_check_probed(g, 0);
- }
-}
-
-static void entry_group_register_time_event_callback(AvahiTimeEvent *e, void* userdata) {
- AvahiSEntryGroup *g = userdata;
- assert(g);
-
-/* avahi_log_debug("Holdoff passed, waking up and going on."); */
-
- avahi_time_event_free(g->register_time_event);
- g->register_time_event = NULL;
-
- /* Holdoff time passed, so let's start probing */
- entry_group_commit_real(g);
-}
-
-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);
-
- 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 */
-/* avahi_log_debug("Holdoff passed, directly going on."); */
-
- entry_group_commit_real(g);
- } else {
-/* avahi_log_debug("Holdoff not passed, sleeping."); */
-
- /* 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;
-}