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#define AVAHI_LEGACY_UNICAST_REFLECT_SLOTS_MAX 100
44
45#define AVAHI_FLAGS_VALID(flags, max) (!((flags) & ~(max)))
46
47#define AVAHI_RR_HOLDOFF_MSEC 1000
48#define AVAHI_RR_HOLDOFF_MSEC_RATE_LIMIT 20000
49#define AVAHI_RR_RATE_LIMIT_COUNT 15
50
51typedef struct AvahiLegacyUnicastReflectSlot AvahiLegacyUnicastReflectSlot;
52
53struct AvahiLegacyUnicastReflectSlot {
54    AvahiServer *server;
55
56    uint16_t id, original_id;
57    AvahiAddress address;
58    uint16_t port;
59    int interface;
60    struct timeval elapse_time;
61    AvahiTimeEvent *time_event;
62};
63
64struct AvahiEntry {
65    AvahiServer *server;
66    AvahiSEntryGroup *group;
67
68    int dead;
69
70    AvahiPublishFlags flags;
71    AvahiRecord *record;
72    AvahiIfIndex interface;
73    AvahiProtocol protocol;
74
75    AVAHI_LLIST_FIELDS(AvahiEntry, entries);
76    AVAHI_LLIST_FIELDS(AvahiEntry, by_key);
77    AVAHI_LLIST_FIELDS(AvahiEntry, by_group);
78
79    AVAHI_LLIST_HEAD(AvahiAnnouncer, announcers);
80};
81
82struct AvahiSEntryGroup {
83    AvahiServer *server;
84    int dead;
85
86    AvahiEntryGroupState state;
87    void* userdata;
88    AvahiSEntryGroupCallback callback;
89
90    unsigned n_probing;
91
92    unsigned n_register_try;
93    struct timeval register_time;
94    AvahiTimeEvent *register_time_event;
95
96    struct timeval established_at;
97
98    AVAHI_LLIST_FIELDS(AvahiSEntryGroup, groups);
99    AVAHI_LLIST_HEAD(AvahiEntry, entries);
100};
101
102struct AvahiServer {
103    const AvahiPoll *poll_api;
104
105    AvahiInterfaceMonitor *monitor;
106    AvahiServerConfig config;
107
108    AVAHI_LLIST_HEAD(AvahiEntry, entries);
109    AvahiHashmap *entries_by_key;
110
111    AVAHI_LLIST_HEAD(AvahiSEntryGroup, groups);
112
113    AVAHI_LLIST_HEAD(AvahiSRecordBrowser, record_browsers);
114    AvahiHashmap *record_browser_hashmap;
115    AVAHI_LLIST_HEAD(AvahiSHostNameResolver, host_name_resolvers);
116    AVAHI_LLIST_HEAD(AvahiSAddressResolver, address_resolvers);
117    AVAHI_LLIST_HEAD(AvahiSDomainBrowser, domain_browsers);
118    AVAHI_LLIST_HEAD(AvahiSServiceTypeBrowser, service_type_browsers);
119    AVAHI_LLIST_HEAD(AvahiSServiceBrowser, service_browsers);
120    AVAHI_LLIST_HEAD(AvahiSServiceResolver, service_resolvers);
121    AVAHI_LLIST_HEAD(AvahiSDNSServerBrowser, dns_server_browsers);
122
123    int need_entry_cleanup, need_group_cleanup, need_browser_cleanup;
124
125    /* Used for scheduling RR cleanup */
126    AvahiTimeEvent *cleanup_time_event;
127
128    AvahiTimeEventQueue *time_event_queue;
129
130    char *host_name, *host_name_fqdn, *domain_name;
131
132    int fd_ipv4, fd_ipv6,
133        /* The following two sockets two are used for reflection only */
134        fd_legacy_unicast_ipv4, fd_legacy_unicast_ipv6;
135
136    AvahiWatch *watch_ipv4, *watch_ipv6,
137        *watch_legacy_unicast_ipv4, *watch_legacy_unicast_ipv6;
138
139    AvahiServerState state;
140    AvahiServerCallback callback;
141    void* userdata;
142
143    AvahiSEntryGroup *hinfo_entry_group;
144    AvahiSEntryGroup *browse_domain_entry_group;
145    unsigned n_host_rr_pending;
146
147    /* Used for assembling responses */
148    AvahiRecordList *record_list;
149
150    /* Used for reflection of legacy unicast packets */
151    AvahiLegacyUnicastReflectSlot **legacy_unicast_reflect_slots;
152    uint16_t legacy_unicast_reflect_id;
153
154    /* The last error code */
155    int error;
156
157    /* The local service cookie */
158    uint32_t local_service_cookie;
159
160    AvahiMulticastLookupEngine *multicast_lookup_engine;
161    AvahiWideAreaLookupEngine *wide_area_lookup_engine;
162};
163
164void avahi_entry_free(AvahiServer*s, AvahiEntry *e);
165void avahi_entry_group_free(AvahiServer *s, AvahiSEntryGroup *g);
166
167void avahi_cleanup_dead_entries(AvahiServer *s);
168
169void avahi_server_prepare_response(AvahiServer *s, AvahiInterface *i, AvahiEntry *e, int unicast_response, int auxiliary);
170void avahi_server_prepare_matching_responses(AvahiServer *s, AvahiInterface *i, AvahiKey *k, int unicast_response);
171void avahi_server_generate_response(AvahiServer *s, AvahiInterface *i, AvahiDnsPacket *p, const AvahiAddress *a, uint16_t port, int legacy_unicast, int is_probe);
172
173void avahi_s_entry_group_change_state(AvahiSEntryGroup *g, AvahiEntryGroupState state);
174
175int avahi_entry_is_commited(AvahiEntry *e);
176
177void avahi_server_enumerate_aux_records(AvahiServer *s, AvahiInterface *i, AvahiRecord *r, void (*callback)(AvahiServer *s, AvahiRecord *r, int flush_cache, void* userdata), void* userdata);
178
179void avahi_host_rr_entry_group_callback(AvahiServer *s, AvahiSEntryGroup *g, AvahiEntryGroupState state, void *userdata);
180
181void avahi_server_decrease_host_rr_pending(AvahiServer *s);
182
183int avahi_server_set_errno(AvahiServer *s, int error);
184
185int avahi_server_is_service_local(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, const char *name);
186int avahi_server_is_record_local(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, AvahiRecord *record);
187
188int avahi_server_add_ptr(
189    AvahiServer *s,
190    AvahiSEntryGroup *g,
191    AvahiIfIndex interface,
192    AvahiProtocol protocol,
193    AvahiPublishFlags flags,
194    uint32_t ttl,
195    const char *name,
196    const char *dest);
197
198#define AVAHI_CHECK_VALIDITY(server, expression, error) { \
199        if (!(expression)) \
200            return avahi_server_set_errno((server), (error)); \
201}
202
203#define AVAHI_CHECK_VALIDITY_RETURN_NULL(server, expression, error) { \
204        if (!(expression)) { \
205            avahi_server_set_errno((server), (error)); \
206            return NULL; \
207        } \
208}
209
210#define AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(server, expression, error) {\
211    if (!(expression)) { \
212        ret = avahi_server_set_errno((server), (error)); \
213        goto fail; \
214    } \
215}
216
217#define AVAHI_ASSERT_TRUE(expression) { \
218    int __tmp = !!(expression); \
219    assert(__tmp); \
220}
221
222#define AVAHI_ASSERT_SUCCESS(expression) { \
223    int __tmp = (expression); \
224    assert(__tmp == 0); \
225}
226
227#endif
228