1#ifndef foointernalhfoo 2#define foointernalhfoo 3 4/*** 5 This file is part of avahi. 6 7 avahi is free software; you can redistribute it and/or modify it 8 under the terms of the GNU Lesser General Public License as 9 published by the Free Software Foundation; either version 2.1 of the 10 License, or (at your option) any later version. 11 12 avahi is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 15 Public License for more details. 16 17 You should have received a copy of the GNU Lesser General Public 18 License along with avahi; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 20 USA. 21***/ 22 23/** A locally registered DNS resource record */ 24typedef struct AvahiEntry AvahiEntry; 25 26#include <avahi-common/llist.h> 27#include <avahi-common/watch.h> 28#include <avahi-common/timeval.h> 29 30#include "core.h" 31#include "iface.h" 32#include "prioq.h" 33#include "timeeventq.h" 34#include "announce.h" 35#include "browse.h" 36#include "dns.h" 37#include "rrlist.h" 38#include "hashmap.h" 39#include "wide-area.h" 40#include "multicast-lookup.h" 41#include "dns-srv-rr.h" 42 43#include "llmnr-querier.h" 44#include "verify.h" 45#include "llmnr-lookup.h" 46 47#define AVAHI_LEGACY_UNICAST_REFLECT_SLOTS_MAX 100 48 49#define AVAHI_FLAGS_VALID(flags, max) (!((flags) & ~(max))) 50 51#define AVAHI_RR_HOLDOFF_MSEC 1000 52#define AVAHI_RR_HOLDOFF_MSEC_RATE_LIMIT 20000 53#define AVAHI_RR_RATE_LIMIT_COUNT 15 54 55typedef struct AvahiLegacyUnicastReflectSlot AvahiLegacyUnicastReflectSlot; 56 57struct AvahiLegacyUnicastReflectSlot { 58 AvahiServer *server; 59 60 uint16_t id, original_id; 61 AvahiAddress address; 62 uint16_t port; 63 int interface; 64 struct timeval elapse_time; 65 AvahiTimeEvent *time_event; 66}; 67 68typedef enum { 69 AVAHI_ENTRY_MDNS, 70 AVAHI_ENTRY_LLMNR 71} AvahiEntryType; 72 73struct AvahiEntry { 74 AvahiServer *server; 75 AvahiSEntryGroup *group; 76 77 int dead; 78 79 AvahiPublishFlags flags; 80 AvahiRecord *record; 81 AvahiIfIndex interface; 82 AvahiProtocol protocol; 83 84 AVAHI_LLIST_FIELDS(AvahiEntry, entries); 85 AVAHI_LLIST_FIELDS(AvahiEntry, by_key); 86 AVAHI_LLIST_FIELDS(AvahiEntry, by_group); 87 88 /* Type to decide whether an mDNS entry of LLMNR */ 89 AvahiEntryType type; 90 91 union { 92 struct { 93 AVAHI_LLIST_HEAD(AvahiAnnouncer, announcers); 94 } mdns; 95 96 struct { 97 AVAHI_LLIST_HEAD(AvahiLLMNREntryVerify, verifiers); 98 } llmnr; 99 } proto; 100}; 101 102 103typedef enum { 104 AVAHI_GROUP_UNSET, 105 AVAHI_GROUP_MDNS, 106 AVAHI_GROUP_LLMNR 107} AvahiSEntryGroupType; 108 109struct AvahiSEntryGroup { 110 AvahiServer *server; 111 int dead; 112 113 AvahiEntryGroupState state; 114 void* userdata; 115 AvahiSEntryGroupCallback callback; 116 117 AvahiSEntryGroupType type; 118 union { 119 struct { 120 unsigned n_probing; 121 unsigned n_register_try; 122 123 struct timeval register_time; 124 AvahiTimeEvent *register_time_event; 125 struct timeval established_at; 126 } mdns; 127 128 struct { 129 unsigned n_verifying; 130 unsigned n_entries; 131 } llmnr; 132 } proto; 133 134 AVAHI_LLIST_FIELDS(AvahiSEntryGroup, groups); 135 AVAHI_LLIST_HEAD(AvahiEntry, entries); 136}; 137 138struct AvahiServer { 139 const AvahiPoll *poll_api; 140 141 AvahiInterfaceMonitor *monitor; 142 AvahiServerConfig config; 143 144 struct { 145 /* mDNS entries and groups */ 146 AVAHI_LLIST_HEAD(AvahiEntry, entries); 147 AvahiHashmap *entries_by_key; 148 AVAHI_LLIST_HEAD(AvahiSEntryGroup, groups); 149 int need_entry_cleanup, need_group_cleanup; 150 151 /*mDNS sockets and watch objects */ 152 int fd_ipv4, fd_ipv6, 153 /* The following two sockets two are used for reflection only */ 154 fd_legacy_unicast_ipv4, fd_legacy_unicast_ipv6; 155 156 AvahiWatch *watch_ipv4, *watch_ipv6, 157 *watch_legacy_unicast_ipv4, *watch_legacy_unicast_ipv6; 158 159 /* mDNS record list to assemble responses*/ 160 AvahiRecordList *record_list; 161 162 AvahiSEntryGroup *hinfo_entry_group; 163 AvahiSEntryGroup *browse_domain_entry_group; 164 165 AvahiMulticastLookupEngine *multicast_lookup_engine; 166 } mdns; 167 168 struct { 169 /* LLMNR entries and groups */ 170 AVAHI_LLIST_HEAD(AvahiEntry, entries); 171 AvahiHashmap *entries_by_key; 172 AVAHI_LLIST_HEAD(AvahiSEntryGroup, groups); 173 int need_entry_cleanup, need_group_cleanup; 174 175 /* LLMNR sockets and watch objects */ 176 int fd_ipv4, fd_ipv6; 177 AvahiWatch *watch_ipv4, *watch_ipv6; 178 179 /* LLMNR record list to assemble LLMNR responses */ 180 AvahiRecordList *record_list; 181 182 AvahiLLMNRLookupEngine *llmnr_lookup_engine; 183 184 } llmnr; 185 186 struct { 187 AvahiWideAreaLookupEngine *wide_area_lookup_engine; 188 } wide_area; 189 190 AVAHI_LLIST_HEAD(AvahiSRecordBrowser, record_browsers); 191 AvahiHashmap *record_browser_hashmap; 192 AVAHI_LLIST_HEAD(AvahiSHostNameResolver, host_name_resolvers); 193 AVAHI_LLIST_HEAD(AvahiSAddressResolver, address_resolvers); 194 AVAHI_LLIST_HEAD(AvahiSDomainBrowser, domain_browsers); 195 AVAHI_LLIST_HEAD(AvahiSServiceTypeBrowser, service_type_browsers); 196 AVAHI_LLIST_HEAD(AvahiSServiceBrowser, service_browsers); 197 AVAHI_LLIST_HEAD(AvahiSServiceResolver, service_resolvers); 198 AVAHI_LLIST_HEAD(AvahiSDNSServerBrowser, dns_server_browsers); 199 200 int need_browser_cleanup; 201 202 /* Used for scheduling RR cleanup */ 203 AvahiTimeEvent *cleanup_time_event; 204 205 AvahiTimeEventQueue *time_event_queue; 206 207 char *host_name, *host_name_fqdn, *domain_name; 208 209 AvahiServerState state; 210 AvahiServerCallback callback; 211 void* userdata; 212 213 unsigned n_host_rr_pending; 214 215 /* Used for reflection of legacy unicast packets */ 216 AvahiLegacyUnicastReflectSlot **legacy_unicast_reflect_slots; 217 uint16_t legacy_unicast_reflect_id; 218 219 /* The last error code */ 220 int error; 221 222 /* The local service cookie */ 223 uint32_t local_service_cookie; 224 225}; 226 227void avahi_entry_free(AvahiServer*s, AvahiEntry *e); 228void avahi_entry_group_free(AvahiServer *s, AvahiSEntryGroup *g); 229 230void avahi_cleanup_dead_entries(AvahiServer *s); 231 232void avahi_server_prepare_response(AvahiServer *s, AvahiInterface *i, AvahiEntry *e, int unicast_response, int auxiliary); 233void avahi_server_prepare_matching_responses(AvahiServer *s, AvahiInterface *i, AvahiKey *k, int unicast_response); 234void avahi_server_generate_response(AvahiServer *s, AvahiInterface *i, AvahiDnsPacket *p, const AvahiAddress *a, uint16_t port, int legacy_unicast, int is_probe); 235 236void avahi_s_entry_group_change_state(AvahiSEntryGroup *g, AvahiEntryGroupState state); 237 238int avahi_entry_is_commited(AvahiEntry *e); 239 240void avahi_server_enumerate_aux_records(AvahiServer *s, AvahiInterface *i, AvahiRecord *r, void (*callback)(AvahiServer *s, AvahiRecord *r, int flush_cache, void* userdata), void* userdata); 241 242void avahi_host_rr_entry_group_callback(AvahiServer *s, AvahiSEntryGroup *g, AvahiEntryGroupState state, void *userdata); 243 244void avahi_server_decrease_host_rr_pending(AvahiServer *s); 245 246int avahi_server_set_errno(AvahiServer *s, int error); 247 248int avahi_server_is_service_local(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, const char *name); 249int avahi_server_is_record_local(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, AvahiRecord *record); 250 251int avahi_server_add_ptr( 252 AvahiServer *s, 253 AvahiSEntryGroup *g, 254 AvahiIfIndex interface, 255 AvahiProtocol protocol, 256 AvahiPublishFlags flags, 257 uint32_t ttl, 258 const char *name, 259 const char *dest); 260 261#define AVAHI_CHECK_VALIDITY(server, expression, error) { \ 262 if (!(expression)) \ 263 return avahi_server_set_errno((server), (error)); \ 264} 265 266#define AVAHI_CHECK_VALIDITY_RETURN_NULL(server, expression, error) { \ 267 if (!(expression)) { \ 268 avahi_server_set_errno((server), (error)); \ 269 return NULL; \ 270 } \ 271} 272 273#define AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(server, expression, error) {\ 274 if (!(expression)) { \ 275 ret = avahi_server_set_errno((server), (error)); \ 276 goto fail; \ 277 } \ 278} 279 280#define AVAHI_ASSERT_TRUE(expression) { \ 281 int __tmp = !!(expression); \ 282 assert(__tmp); \ 283} 284 285#define AVAHI_ASSERT_SUCCESS(expression) { \ 286 int __tmp = (expression); \ 287 assert(__tmp == 0); \ 288} 289 290#endif 291