static void job_set_elapse_time(AvahiProbeScheduler *s, AvahiProbeJob *pj, unsigned msec, unsigned jitter) { struct timeval tv; assert(s); assert(pj); avahi_elapse_time(&tv, msec, jitter); if (pj->time_event) avahi_time_event_update(pj->time_event, &tv); else pj->time_event = avahi_time_event_new(s->time_event_queue, &tv, elapse_callback, pj); }
static void set_timeout(AvahiAnnouncer *a, const struct timeval *tv) { assert(a); if (!tv) { if (a->time_event) { avahi_time_event_free(a->time_event); a->time_event = NULL; } } else { if (a->time_event) avahi_time_event_update(a->time_event, tv); else a->time_event = avahi_time_event_new(a->server->time_event_queue, tv, elapse_announce, a); } }
static void reschedule_llmnr_query_job(AvahiLLMNRQueryJob *qj) { struct timeval tv; assert(qj); assert(!avahi_record_list_is_empty(qj->lq->c_bit_clear)); if(!(qj->prev_scheduled)) { qj->prev_scheduled = 1; avahi_elapse_time(&tv, AVAHI_LLMNR_INTERVAL + AVAHI_LLMNR_JITTER, 0); avahi_time_event_update(qj->time_event, &tv); } else { /* We have already waited but we still have not received any response/s with 'c' bit clear. */ qj->lq->callback(qj->lq->interface->hardware->index, qj->lq->interface->protocol, NULL, qj->lq->userdata); /*avahi_time_event_free(qj->time_event); qj->time_event = NULL;*/ avahi_llmnr_query_job_destroy(qj->scheduler, qj); } return; }
int avahi_query_scheduler_post(AvahiQueryScheduler *s, AvahiKey *key, int immediately, unsigned *ret_id) { struct timeval tv; AvahiQueryJob *qj; assert(s); assert(key); if ((qj = find_history_job(s, key))) return 0; avahi_elapse_time(&tv, immediately ? 0 : AVAHI_QUERY_DEFER_MSEC, 0); if ((qj = find_scheduled_job(s, key))) { /* Duplicate questions suppression */ if (avahi_timeval_compare(&tv, &qj->delivery) < 0) { /* If the new entry should be scheduled earlier, * update the old entry */ qj->delivery = tv; avahi_time_event_update(qj->time_event, &qj->delivery); } qj->n_posted++; } else { if (!(qj = job_new(s, key, 0))) return 0; /* OOM */ qj->delivery = tv; qj->time_event = avahi_time_event_new(s->time_event_queue, &qj->delivery, elapse_callback, qj); } if (ret_id) *ret_id = qj->id; return 1; }
int avahi_probe_scheduler_post(AvahiProbeScheduler *s, AvahiRecord *record, int immediately) { AvahiProbeJob *pj; struct timeval tv; assert(s); assert(record); assert(!avahi_key_is_pattern(record->key)); if ((pj = find_history_job(s, record))) return 0; avahi_elapse_time(&tv, immediately ? 0 : AVAHI_PROBE_DEFER_MSEC, 0); if ((pj = find_scheduled_job(s, record))) { if (avahi_timeval_compare(&tv, &pj->delivery) < 0) { /* If the new entry should be scheduled earlier, update the old entry */ pj->delivery = tv; avahi_time_event_update(pj->time_event, &pj->delivery); } return 1; } else { /* Create a new job and schedule it */ if (!(pj = job_new(s, record, 0))) return 0; /* OOM */ pj->delivery = tv; pj->time_event = avahi_time_event_new(s->time_event_queue, &pj->delivery, elapse_callback, pj); /* avahi_log_debug("Accepted new probe job."); */ return 1; } }
static void resend_llmnr_query(AvahiLLMNRQueryJob *qj) { AvahiLLMNRQuery *lq = qj->lq; struct timeval tv; assert(qj); if(lq->type == AVAHI_LLMNR_SIMPLE_QUERY || lq->type == AVAHI_LLMNR_UNIQUENESS_VERIFICATION_QUERY) { /**Check whether we have already sent this query three times */ if(qj->n_sent >= 3) { lq->callback(lq->interface->hardware->index, lq->interface->protocol, NULL, lq->userdata); avahi_llmnr_query_job_destroy(qj->scheduler, qj); /* Free Timeevent */ /* avahi_time_event_free(qj->time_event); qj->time_event = NULL;*/ } else { /* Send packet */ avahi_interface_send_packet(lq->interface, qj->p, AVAHI_LLMNR); (qj->n_sent)++; /* Schedule further queries*/ avahi_elapse_time(&tv, AVAHI_LLMNR_INTERVAL, 0); avahi_time_event_update(qj->time_event, &tv); } } else { assert(lq->type == AVAHI_LLMNR_CONFLICT_QUERY); assert(qj->n_sent == 1); /* Destroy this query */ lq->callback(lq->interface->hardware->index, lq->interface->protocol, NULL, lq->userdata); avahi_llmnr_query_job_destroy(qj->scheduler, qj); } return; }
int avahi_response_scheduler_post(AvahiResponseScheduler *s, AvahiRecord *record, int flush_cache, const AvahiAddress *querier, int immediately) { AvahiResponseJob *rj; struct timeval tv; /* char *t; */ assert(s); assert(record); assert(!avahi_key_is_pattern(record->key)); /* t = avahi_record_to_string(record); */ /* avahi_log_debug("post %i %s", immediately, t); */ /* avahi_free(t); */ /* Check whether this response is suppressed */ if (querier && (rj = find_suppressed_job(s, record, querier)) && avahi_record_is_goodbye(record) == avahi_record_is_goodbye(rj->record) && rj->record->ttl >= record->ttl/2) { /* avahi_log_debug("Response suppressed by known answer suppression."); */ return 0; } /* Check if we already sent this response recently */ if ((rj = find_history_job(s, record))) { if (avahi_record_is_goodbye(record) == avahi_record_is_goodbye(rj->record) && rj->record->ttl >= record->ttl/2 && (rj->flush_cache || !flush_cache)) { /* avahi_log_debug("Response suppressed by local duplicate suppression (history)"); */ return 0; } /* Outdated ... */ job_free(s, rj); } avahi_elapse_time(&tv, immediately ? 0 : AVAHI_RESPONSE_DEFER_MSEC, immediately ? 0 : AVAHI_RESPONSE_JITTER_MSEC); if ((rj = find_scheduled_job(s, record))) { /* avahi_log_debug("Response suppressed by local duplicate suppression (scheduled)"); */ /* Update a little ... */ /* Update the time if the new is prior to the old */ if (avahi_timeval_compare(&tv, &rj->delivery) < 0) { rj->delivery = tv; avahi_time_event_update(rj->time_event, &rj->delivery); } /* Update the flush cache bit */ if (flush_cache) rj->flush_cache = 1; /* Update the querier field */ if (!querier || (rj->querier_valid && avahi_address_cmp(querier, &rj->querier) != 0)) rj->querier_valid = 0; /* Update record data (just for the TTL) */ avahi_record_unref(rj->record); rj->record = avahi_record_ref(record); return 1; } else { /* avahi_log_debug("Accepted new response job."); */ /* Create a new job and schedule it */ if (!(rj = job_new(s, record, AVAHI_SCHEDULED))) return 0; /* OOM */ rj->delivery = tv; rj->time_event = avahi_time_event_new(s->time_event_queue, &rj->delivery, elapse_callback, rj); rj->flush_cache = flush_cache; if ((rj->querier_valid = !!querier)) rj->querier = *querier; return 1; } }