128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering/*** 228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering This file is part of avahi. 3a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi is free software; you can redistribute it and/or modify it 528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering under the terms of the GNU Lesser General Public License as 628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering published by the Free Software Foundation; either version 2.1 of the 728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering License, or (at your option) any later version. 8a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi is distributed in the hope that it will be useful, but WITHOUT 1028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 1128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 1228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering Public License for more details. 13a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering You should have received a copy of the GNU Lesser General Public 1528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering License along with avahi; if not, write to the Free Software 1628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 1728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering USA. 1828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering***/ 1928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 2028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering#ifdef HAVE_CONFIG_H 2128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering#include <config.h> 2228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering#endif 2328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 24b4bb609c78d2f4ce834a60efccd876117f0753f6Lennart Poettering#include <stdlib.h> 25b4bb609c78d2f4ce834a60efccd876117f0753f6Lennart Poettering 265ebf655c85076f200955458673a8bbf0dd927407Lennart Poettering#include <avahi-common/domain.h> 275d047523c87ba11aad8c384f7ffde25b4dd746edLennart Poettering#include <avahi-common/timeval.h> 288e46e738cae449bf44232c66e973c8e9e15fbcb5Robert Ginda#include "avahi-common/avahi-malloc.h" 295ebf655c85076f200955458673a8bbf0dd927407Lennart Poettering 3028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering#include "probe-sched.h" 31c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering#include "log.h" 326efe2615e04c6ef664fa9d49b013e261ba1e6e66Lennart Poettering#include "rr-util.h" 3328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 344ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering#define AVAHI_PROBE_HISTORY_MSEC 150 354ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering#define AVAHI_PROBE_DEFER_MSEC 50 3628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 3728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringtypedef struct AvahiProbeJob AvahiProbeJob; 3828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 3928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringstruct AvahiProbeJob { 4028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiProbeScheduler *scheduler; 4128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiTimeEvent *time_event; 42a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 434f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int chosen; /* Use for packet assembling */ 444f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int done; 45e63a65b3955b173a3e8d6b78c6377a518a9922d6Lennart Poettering struct timeval delivery; 4628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 4728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiRecord *record; 48a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 4928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AVAHI_LLIST_FIELDS(AvahiProbeJob, jobs); 5028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering}; 5128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 5228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringstruct AvahiProbeScheduler { 5328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiInterface *interface; 5428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiTimeEventQueue *time_event_queue; 5528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 5628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AVAHI_LLIST_HEAD(AvahiProbeJob, jobs); 574ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_HEAD(AvahiProbeJob, history); 5828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering}; 5928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 604f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringstatic AvahiProbeJob* job_new(AvahiProbeScheduler *s, AvahiRecord *record, int done) { 6128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiProbeJob *pj; 62a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 634f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(s); 644f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(record); 6528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 664f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(pj = avahi_new(AvahiProbeJob, 1))) { 674f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_log_error(__FILE__": Out of memory"); 684f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; /* OOM */ 694f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering } 70a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 7128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering pj->scheduler = s; 7228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering pj->record = avahi_record_ref(record); 7328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering pj->time_event = NULL; 744f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering pj->chosen = 0; 754ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 764ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if ((pj->done = done)) 774ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_PREPEND(AvahiProbeJob, jobs, s->history, pj); 784ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering else 794ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_PREPEND(AvahiProbeJob, jobs, s->jobs, pj); 8028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 8128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering return pj; 8228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 8328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 8428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringstatic void job_free(AvahiProbeScheduler *s, AvahiProbeJob *pj) { 854f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(pj); 8628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 8728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (pj->time_event) 884f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_time_event_free(pj->time_event); 8928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 904ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if (pj->done) 914ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_REMOVE(AvahiProbeJob, jobs, s->history, pj); 924ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering else 934ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_REMOVE(AvahiProbeJob, jobs, s->jobs, pj); 9428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 9528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_record_unref(pj->record); 964f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_free(pj); 9728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 9828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 994f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringstatic void elapse_callback(AvahiTimeEvent *e, void* data); 1004ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1014f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringstatic void job_set_elapse_time(AvahiProbeScheduler *s, AvahiProbeJob *pj, unsigned msec, unsigned jitter) { 102e63a65b3955b173a3e8d6b78c6377a518a9922d6Lennart Poettering struct timeval tv; 1034ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1044f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(s); 1054f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(pj); 1064ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1074ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering avahi_elapse_time(&tv, msec, jitter); 1084ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1094ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if (pj->time_event) 1104f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_time_event_update(pj->time_event, &tv); 1114ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering else 1124f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering pj->time_event = avahi_time_event_new(s->time_event_queue, &tv, elapse_callback, pj); 1134ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering} 1144ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1154ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poetteringstatic void job_mark_done(AvahiProbeScheduler *s, AvahiProbeJob *pj) { 1164f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(s); 1174f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(pj); 1184ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1194f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(!pj->done); 1204ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1214ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_REMOVE(AvahiProbeJob, jobs, s->jobs, pj); 1224ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_PREPEND(AvahiProbeJob, jobs, s->history, pj); 1234ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1244f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering pj->done = 1; 1254ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 1264ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering job_set_elapse_time(s, pj, AVAHI_PROBE_HISTORY_MSEC, 0); 127e63a65b3955b173a3e8d6b78c6377a518a9922d6Lennart Poettering gettimeofday(&pj->delivery, NULL); 1284ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering} 12928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 13028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart PoetteringAvahiProbeScheduler *avahi_probe_scheduler_new(AvahiInterface *i) { 13128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiProbeScheduler *s; 13228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 1334f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(i); 13428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 1354f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(s = avahi_new(AvahiProbeScheduler, 1))) { 1364f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_log_error(__FILE__": Out of memory"); 1374f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return NULL; 1384f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering } 139a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 14028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering s->interface = i; 14128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering s->time_event_queue = i->monitor->server->time_event_queue; 14228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 14328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AVAHI_LLIST_HEAD_INIT(AvahiProbeJob, s->jobs); 1444ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AVAHI_LLIST_HEAD_INIT(AvahiProbeJob, s->history); 145a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 14628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering return s; 14728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 14828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 14928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringvoid avahi_probe_scheduler_free(AvahiProbeScheduler *s) { 1504f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(s); 15128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 15228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_probe_scheduler_clear(s); 1534f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_free(s); 15428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 15528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 15628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poetteringvoid avahi_probe_scheduler_clear(AvahiProbeScheduler *s) { 1574f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(s); 158a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 15928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering while (s->jobs) 16028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering job_free(s, s->jobs); 1614ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering while (s->history) 1624ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering job_free(s, s->history); 16328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 164a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1654f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringstatic int packet_add_probe_query(AvahiProbeScheduler *s, AvahiDnsPacket *p, AvahiProbeJob *pj) { 1664f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t size; 16728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiKey *k; 1684f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int b; 16928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 1704f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(s); 1714f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(p); 1724f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(pj); 17328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 1744f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(!pj->chosen); 175a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 17628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Estimate the size for this record */ 17728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering size = 17828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_key_get_estimate_size(pj->record->key) + 17928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_record_get_estimate_size(pj->record); 18028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 18128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Too large */ 18228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (size > avahi_dns_packet_space(p)) 1834f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return 0; 18428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 18528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Create the probe query */ 1864f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(k = avahi_key_new(pj->record->key->name, pj->record->key->clazz, AVAHI_DNS_TYPE_ANY))) 1874f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return 0; /* OOM */ 188a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 1894f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering b = !!avahi_dns_packet_append_key(p, k, 0); 1904f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(b); 19128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 19228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Mark this job for addition to the packet */ 1934f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering pj->chosen = 1; 19428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 19528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Scan for more jobs whith matching key pattern */ 19628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering for (pj = s->jobs; pj; pj = pj->jobs_next) { 19728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (pj->chosen) 19828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering continue; 19928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 20028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Does the record match the probe? */ 20114f8d9beb7ef14b0aab5512345e09109bdd8cb0cLennart Poettering if (k->clazz != pj->record->key->clazz || !avahi_domain_equal(k->name, pj->record->key->name)) 20228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering continue; 203a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 20428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* This job wouldn't fit in */ 20528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (avahi_record_get_estimate_size(pj->record) > avahi_dns_packet_space(p)) 20628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering break; 20728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 20828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Mark this job for addition to the packet */ 2094f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering pj->chosen = 1; 21028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering } 21128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 21228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_key_unref(k); 213a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 2144f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return 1; 21528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 21628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 217854f901f491ccda79aee11edc3d59109cb229d28Lennart Poetteringstatic void elapse_callback(AVAHI_GCC_UNUSED AvahiTimeEvent *e, void* data) { 21828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiProbeJob *pj = data, *next; 21928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiProbeScheduler *s; 22028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiDnsPacket *p; 2214f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering unsigned n; 22228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 2234f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(pj); 22428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering s = pj->scheduler; 22528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 2264ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if (pj->done) { 2274ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering /* Lets remove it from the history */ 2284ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering job_free(s, pj); 2294ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return; 2304ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } 2314ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 2324f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(p = avahi_dns_packet_new_query(s->interface->hardware->mtu))) 2334f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return; /* OOM */ 23428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering n = 1; 235a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 23628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Add the import probe */ 23728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (!packet_add_probe_query(s, p, pj)) { 2384f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering size_t size; 23928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiKey *k; 2404f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering int b; 24128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 24228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_dns_packet_free(p); 24328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 24428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* The probe didn't fit in the package, so let's allocate a larger one */ 24528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 24628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering size = 24728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_key_get_estimate_size(pj->record->key) + 24828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_record_get_estimate_size(pj->record) + 24928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AVAHI_DNS_PACKET_HEADER_SIZE; 250a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 251bbf6b92f662ed909d5b4fca4a43b19e815812b3eLennart Poettering if (!(p = avahi_dns_packet_new_query(size + AVAHI_DNS_PACKET_EXTRA_SIZE))) 2524f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return; /* OOM */ 2534f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering 2544f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(k = avahi_key_new(pj->record->key->name, pj->record->key->clazz, AVAHI_DNS_TYPE_ANY))) { 2554f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_dns_packet_free(p); 2564f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return; /* OOM */ 2574f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering } 258a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 2594f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering b = avahi_dns_packet_append_key(p, k, 0) && avahi_dns_packet_append_record(p, pj->record, 0, 0); 26028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_key_unref(k); 26128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 26228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (b) { 26328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_NSCOUNT, 1); 26428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_QDCOUNT, 1); 26528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_interface_send_packet(s->interface, p); 26628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering } else 267a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering avahi_log_warn("Probe record too large, cannot send"); 268a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 26928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_dns_packet_free(p); 2704ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering job_mark_done(s, pj); 27128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 27228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering return; 27328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering } 27428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 27528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Try to fill up packet with more probes, if available */ 27628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering for (pj = s->jobs; pj; pj = pj->jobs_next) { 27728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 27828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (pj->chosen) 27928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering continue; 280a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 28128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (!packet_add_probe_query(s, p, pj)) 28228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering break; 283a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 28428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering n++; 28528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering } 28628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 28728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_QDCOUNT, n); 28828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 28928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering n = 0; 29028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 29128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Now add the chosen records to the authorative section */ 29228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering for (pj = s->jobs; pj; pj = next) { 29328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 29428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering next = pj->jobs_next; 29528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 29628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering if (!pj->chosen) 29728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering continue; 29828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 2994f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!avahi_dns_packet_append_record(p, pj->record, 0, 0)) { 300a3737cc61b48d7d435aadb573d3ef58e0849bf3dLennart Poettering/* avahi_log_warn("Bad probe size estimate!"); */ 30128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 30228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Unmark all following jobs */ 30328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering for (; pj; pj = pj->jobs_next) 3044f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering pj->chosen = 0; 305a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 30628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering break; 30728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering } 30828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 3094ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering job_mark_done(s, pj); 310a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 31128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering n ++; 31228d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering } 313a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 31428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_NSCOUNT, n); 31528d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 31628d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering /* Send it now */ 31728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_interface_send_packet(s->interface, p); 31828d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_dns_packet_free(p); 31928d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 32028d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 3214ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poetteringstatic AvahiProbeJob* find_scheduled_job(AvahiProbeScheduler *s, AvahiRecord *record) { 3224ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AvahiProbeJob *pj; 3234ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3244f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(s); 3254f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(record); 3264ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3274ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering for (pj = s->jobs; pj; pj = pj->jobs_next) { 3284f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(!pj->done); 329a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3304ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if (avahi_record_equal_no_ttl(pj->record, record)) 3314ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return pj; 3324ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } 3334ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3344ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return NULL; 3354ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering} 3364ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3374ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poetteringstatic AvahiProbeJob* find_history_job(AvahiProbeScheduler *s, AvahiRecord *record) { 3384ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering AvahiProbeJob *pj; 339a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3404f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(s); 3414f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(record); 3424ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3434ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering for (pj = s->history; pj; pj = pj->jobs_next) { 3444f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(pj->done); 3454ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3464ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if (avahi_record_equal_no_ttl(pj->record, record)) { 3474ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering /* Check whether this entry is outdated */ 3484ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3494ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if (avahi_age(&pj->delivery) > AVAHI_PROBE_HISTORY_MSEC*1000) { 3504ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering /* it is outdated, so let's remove it */ 3514ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering job_free(s, pj); 3524ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return NULL; 3534ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } 354a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3554ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return pj; 3564ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } 3574ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } 3584ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3594ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering return NULL; 3604ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering} 3614ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3624f0a5e7572a4257894b4bfede42c26d65152609eLennart Poetteringint avahi_probe_scheduler_post(AvahiProbeScheduler *s, AvahiRecord *record, int immediately) { 36328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering AvahiProbeJob *pj; 364e63a65b3955b173a3e8d6b78c6377a518a9922d6Lennart Poettering struct timeval tv; 365a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3664f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(s); 3674f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(record); 3684f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering assert(!avahi_key_is_pattern(record->key)); 3694ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3704ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if ((pj = find_history_job(s, record))) 3714f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return 0; 37248cfb3c876636d79dace3ebc8e82c946bc0b7ebfLennart Poettering 37328d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering avahi_elapse_time(&tv, immediately ? 0 : AVAHI_PROBE_DEFER_MSEC, 0); 37428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 3754ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if ((pj = find_scheduled_job(s, record))) { 3764ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3774ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering if (avahi_timeval_compare(&tv, &pj->delivery) < 0) { 3784ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering /* If the new entry should be scheduled earlier, update the old entry */ 3794ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering pj->delivery = tv; 3804f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering avahi_time_event_update(pj->time_event, &pj->delivery); 3814ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } 3824ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering 3834f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return 1; 3844ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } else { 3854ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering /* Create a new job and schedule it */ 3864f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering if (!(pj = job_new(s, record, 0))) 3874f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return 0; /* OOM */ 388a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 3894ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering pj->delivery = tv; 3904f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering pj->time_event = avahi_time_event_new(s->time_event_queue, &pj->delivery, elapse_callback, pj); 39128d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 392a97605e07ad7f44f2f65e15be64880e61a39ab43Lennart Poettering 393c0244c2448a5504581ae24e78b5859760b999b8eLennart Poettering/* avahi_log_debug("Accepted new probe job."); */ 39428d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering 3954f0a5e7572a4257894b4bfede42c26d65152609eLennart Poettering return 1; 3964ff0807c04fcc239de52a793bceb88e7f3408f3fLennart Poettering } 39728d336020ca1f6dbb88d64cac3ffdd1a67ee3de7Lennart Poettering} 398