probe-sched.c revision 4ff0807c04fcc239de52a793bceb88e7f3408f3f
128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering/* $Id$ */ 228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering/*** 428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering This file is part of avahi. 528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi is free software; you can redistribute it and/or modify it 728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering under the terms of the GNU Lesser General Public License as 828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering published by the Free Software Foundation; either version 2.1 of the 928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering License, or (at your option) any later version. 1028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 1128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi is distributed in the hope that it will be useful, but WITHOUT 1228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 1328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 1428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering Public License for more details. 1528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 1628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering You should have received a copy of the GNU Lesser General Public 1728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering License along with avahi; if not, write to the Free Software 1828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 1928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering USA. 2028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering***/ 2128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 2228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering#ifdef HAVE_CONFIG_H 2328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering#include <config.h> 2428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering#endif 2528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 2628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering#include "probe-sched.h" 2728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering#include "util.h" 2828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 294ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering#define AVAHI_PROBE_HISTORY_MSEC 150 304ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering#define AVAHI_PROBE_DEFER_MSEC 50 3128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 3228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringtypedef struct AvahiProbeJob AvahiProbeJob; 3328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 3428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringstruct AvahiProbeJob { 3528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiProbeScheduler *scheduler; 3628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiTimeEvent *time_event; 3728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 3828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering gboolean chosen; /* Use for packet assembling */ 394ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering gboolean done; 4028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering GTimeVal delivery; 4128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 4228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiRecord *record; 4328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 4428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AVAHI_LLIST_FIELDS(AvahiProbeJob, jobs); 4528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering}; 4628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 4728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringstruct AvahiProbeScheduler { 4828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiInterface *interface; 4928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiTimeEventQueue *time_event_queue; 5028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 5128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AVAHI_LLIST_HEAD(AvahiProbeJob, jobs); 524ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_HEAD(AvahiProbeJob, history); 5328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering}; 5428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 554ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poetteringstatic AvahiProbeJob* job_new(AvahiProbeScheduler *s, AvahiRecord *record, gboolean done) { 5628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiProbeJob *pj; 5728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 5828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(s); 5928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(record); 6028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 6128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering pj = g_new(AvahiProbeJob, 1); 6228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering pj->scheduler = s; 6328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering pj->record = avahi_record_ref(record); 6428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering pj->time_event = NULL; 6528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering pj->chosen = FALSE; 664ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 674ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if ((pj->done = done)) 684ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_PREPEND(AvahiProbeJob, jobs, s->history, pj); 694ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering else 704ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_PREPEND(AvahiProbeJob, jobs, s->jobs, pj); 7128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 7228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering return pj; 7328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 7428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 7528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringstatic void job_free(AvahiProbeScheduler *s, AvahiProbeJob *pj) { 7628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(pj); 7728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 7828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (pj->time_event) 7928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_time_event_queue_remove(s->time_event_queue, pj->time_event); 8028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 814ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if (pj->done) 824ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_REMOVE(AvahiProbeJob, jobs, s->history, pj); 834ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering else 844ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_REMOVE(AvahiProbeJob, jobs, s->jobs, pj); 8528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 8628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_record_unref(pj->record); 8728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_free(pj); 8828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 8928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 904ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poetteringstatic void elapse_callback(AvahiTimeEvent *e, gpointer data); 914ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 924ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poetteringstatic void job_set_elapse_time(AvahiProbeScheduler *s, AvahiProbeJob *pj, guint msec, guint jitter) { 934ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering GTimeVal tv; 944ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 954ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering g_assert(s); 964ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering g_assert(pj); 974ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 984ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering avahi_elapse_time(&tv, msec, jitter); 994ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1004ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if (pj->time_event) 1014ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering avahi_time_event_queue_update(s->time_event_queue, pj->time_event, &tv); 1024ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering else 1034ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering pj->time_event = avahi_time_event_queue_add(s->time_event_queue, &tv, elapse_callback, pj); 1044ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering} 1054ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1064ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poetteringstatic void job_mark_done(AvahiProbeScheduler *s, AvahiProbeJob *pj) { 1074ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering g_assert(s); 1084ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering g_assert(pj); 1094ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1104ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering g_assert(!pj->done); 1114ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1124ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_REMOVE(AvahiProbeJob, jobs, s->jobs, pj); 1134ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_PREPEND(AvahiProbeJob, jobs, s->history, pj); 1144ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1154ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering pj->done = TRUE; 1164ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1174ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering job_set_elapse_time(s, pj, AVAHI_PROBE_HISTORY_MSEC, 0); 1184ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering g_get_current_time(&pj->delivery); 1194ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering} 12028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 12128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart PoetteringAvahiProbeScheduler *avahi_probe_scheduler_new(AvahiInterface *i) { 12228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiProbeScheduler *s; 12328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 12428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(i); 12528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 12628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering s = g_new(AvahiProbeScheduler, 1); 12728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering s->interface = i; 12828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering s->time_event_queue = i->monitor->server->time_event_queue; 12928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 13028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AVAHI_LLIST_HEAD_INIT(AvahiProbeJob, s->jobs); 1314ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_HEAD_INIT(AvahiProbeJob, s->history); 13228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 13328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering return s; 13428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 13528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 13628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringvoid avahi_probe_scheduler_free(AvahiProbeScheduler *s) { 13728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(s); 13828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 13928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_probe_scheduler_clear(s); 14028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_free(s); 14128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 14228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 14328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringvoid avahi_probe_scheduler_clear(AvahiProbeScheduler *s) { 14428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(s); 14528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 14628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering while (s->jobs) 14728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering job_free(s, s->jobs); 1484ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering while (s->history) 1494ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering job_free(s, s->history); 15028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 15128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 15228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringstatic gboolean packet_add_probe_query(AvahiProbeScheduler *s, AvahiDnsPacket *p, AvahiProbeJob *pj) { 15328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering guint size; 15428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiKey *k; 15528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering gboolean b; 15628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 15728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(s); 15828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(p); 15928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(pj); 16028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 16128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(!pj->chosen); 16228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 16328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Estimate the size for this record */ 16428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering size = 16528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_key_get_estimate_size(pj->record->key) + 16628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_record_get_estimate_size(pj->record); 16728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 16828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Too large */ 16928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (size > avahi_dns_packet_space(p)) 17028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering return FALSE; 17128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 17228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Create the probe query */ 17328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering k = avahi_key_new(pj->record->key->name, pj->record->key->class, AVAHI_DNS_TYPE_ANY); 17428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering b = !!avahi_dns_packet_append_key(p, k, FALSE); 17528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(b); 17628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 17728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Mark this job for addition to the packet */ 17828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering pj->chosen = TRUE; 17928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 18028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Scan for more jobs whith matching key pattern */ 18128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering for (pj = s->jobs; pj; pj = pj->jobs_next) { 18228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (pj->chosen) 18328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering continue; 18428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 18528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Does the record match the probe? */ 18628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (k->class != pj->record->key->class || !avahi_domain_equal(k->name, pj->record->key->name)) 18728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering continue; 18828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 18928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* This job wouldn't fit in */ 19028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (avahi_record_get_estimate_size(pj->record) > avahi_dns_packet_space(p)) 19128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering break; 19228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 19328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Mark this job for addition to the packet */ 19428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering pj->chosen = TRUE; 19528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering } 19628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 19728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_key_unref(k); 19828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 19928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering return TRUE; 20028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 20128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 20228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringstatic void elapse_callback(AvahiTimeEvent *e, gpointer data) { 20328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiProbeJob *pj = data, *next; 20428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiProbeScheduler *s; 20528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiDnsPacket *p; 20628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering guint n; 20728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 20828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(pj); 20928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering s = pj->scheduler; 21028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 2114ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if (pj->done) { 2124ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering /* Lets remove it from the history */ 2134ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering job_free(s, pj); 2144ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return; 2154ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } 2164ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 21728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering p = avahi_dns_packet_new_query(s->interface->hardware->mtu); 21828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering n = 1; 21928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 22028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Add the import probe */ 22128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (!packet_add_probe_query(s, p, pj)) { 22228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering guint size; 22328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiKey *k; 22428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering gboolean b; 22528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 22628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_dns_packet_free(p); 22728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 22828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* The probe didn't fit in the package, so let's allocate a larger one */ 22928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 23028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering size = 23128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_key_get_estimate_size(pj->record->key) + 23228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_record_get_estimate_size(pj->record) + 23328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AVAHI_DNS_PACKET_HEADER_SIZE; 23428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 23528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (size > AVAHI_DNS_PACKET_MAX_SIZE) 23628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering size = AVAHI_DNS_PACKET_MAX_SIZE; 23728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 23828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering p = avahi_dns_packet_new_query(size); 23928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 24028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering k = avahi_key_new(pj->record->key->name, pj->record->key->class, AVAHI_DNS_TYPE_ANY); 24128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering b = avahi_dns_packet_append_key(p, k, FALSE) && avahi_dns_packet_append_record(p, pj->record, FALSE, 0); 24228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_key_unref(k); 24328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 24428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (b) { 24528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_NSCOUNT, 1); 24628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_QDCOUNT, 1); 24728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_interface_send_packet(s->interface, p); 24828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering } else 24928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_warning("Probe record too large, cannot send"); 25028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 25128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_dns_packet_free(p); 2524ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering job_mark_done(s, pj); 25328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 25428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering return; 25528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering } 25628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 25728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Try to fill up packet with more probes, if available */ 25828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering for (pj = s->jobs; pj; pj = pj->jobs_next) { 25928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 26028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (pj->chosen) 26128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering continue; 26228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 26328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (!packet_add_probe_query(s, p, pj)) 26428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering break; 26528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 26628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering n++; 26728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering } 26828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 26928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_QDCOUNT, n); 27028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 27128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering n = 0; 27228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 27328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Now add the chosen records to the authorative section */ 27428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering for (pj = s->jobs; pj; pj = next) { 27528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 27628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering next = pj->jobs_next; 27728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 27828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (!pj->chosen) 27928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering continue; 28028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 28128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (!avahi_dns_packet_append_record(p, pj->record, FALSE, 0)) { 28228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_warning("Bad probe size estimate!"); 28328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 28428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Unmark all following jobs */ 28528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering for (; pj; pj = pj->jobs_next) 28628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering pj->chosen = FALSE; 28728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 28828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering break; 28928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering } 29028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 2914ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering job_mark_done(s, pj); 29228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 29328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering n ++; 29428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering } 29528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 29628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_NSCOUNT, n); 29728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 29828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Send it now */ 29928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_interface_send_packet(s->interface, p); 30028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_dns_packet_free(p); 30128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 30228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 3034ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poetteringstatic AvahiProbeJob* find_scheduled_job(AvahiProbeScheduler *s, AvahiRecord *record) { 3044ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AvahiProbeJob *pj; 3054ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3064ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering g_assert(s); 3074ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering g_assert(record); 3084ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3094ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering for (pj = s->jobs; pj; pj = pj->jobs_next) { 3104ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering g_assert(!pj->done); 3114ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3124ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if (avahi_record_equal_no_ttl(pj->record, record)) 3134ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return pj; 3144ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } 3154ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3164ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return NULL; 3174ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering} 3184ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3194ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poetteringstatic AvahiProbeJob* find_history_job(AvahiProbeScheduler *s, AvahiRecord *record) { 3204ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AvahiProbeJob *pj; 3214ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3224ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering g_assert(s); 3234ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering g_assert(record); 3244ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3254ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering for (pj = s->history; pj; pj = pj->jobs_next) { 3264ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering g_assert(pj->done); 3274ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3284ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if (avahi_record_equal_no_ttl(pj->record, record)) { 3294ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering /* Check whether this entry is outdated */ 3304ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3314ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if (avahi_age(&pj->delivery) > AVAHI_PROBE_HISTORY_MSEC*1000) { 3324ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering /* it is outdated, so let's remove it */ 3334ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering job_free(s, pj); 3344ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return NULL; 3354ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } 3364ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3374ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return pj; 3384ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } 3394ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } 3404ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3414ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return NULL; 3424ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering} 3434ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 34428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringgboolean avahi_probe_scheduler_post(AvahiProbeScheduler *s, AvahiRecord *record, gboolean immediately) { 34528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiProbeJob *pj; 34628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering GTimeVal tv; 34728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 34828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(s); 34928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(record); 35028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering g_assert(!avahi_key_is_pattern(record->key)); 3514ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3524ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if ((pj = find_history_job(s, record))) 3534ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return FALSE; 35428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 35528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_elapse_time(&tv, immediately ? 0 : AVAHI_PROBE_DEFER_MSEC, 0); 35628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 3574ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if ((pj = find_scheduled_job(s, record))) { 3584ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3594ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if (avahi_timeval_compare(&tv, &pj->delivery) < 0) { 3604ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering /* If the new entry should be scheduled earlier, update the old entry */ 3614ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering pj->delivery = tv; 3624ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering avahi_time_event_queue_update(s->time_event_queue, pj->time_event, &pj->delivery); 3634ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } 3644ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3654ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return TRUE; 3664ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } else { 3674ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering /* Create a new job and schedule it */ 3684ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering pj = job_new(s, record, FALSE); 3694ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering pj->delivery = tv; 3704ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering pj->time_event = avahi_time_event_queue_add(s->time_event_queue, &pj->delivery, elapse_callback, pj); 37128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 3724ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3734de3df3db7df43474176533d0b5fac851dd4a9b4Lennart Poettering/* g_message("Accepted new probe job."); */ 37428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 3754ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return TRUE; 3764ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } 37728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 378