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