1 /**
2  * @file
3  * MDNS responder private definitions
4  */
5 
6  /*
7  * Copyright (c) 2015 Verisure Innovation AB
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without modification,
11  * are permitted provided that the following conditions are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright notice,
14  *    this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  *    this list of conditions and the following disclaimer in the documentation
17  *    and/or other materials provided with the distribution.
18  * 3. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
22  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
24  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
30  * OF SUCH DAMAGE.
31  *
32  * This file is part of the lwIP TCP/IP stack.
33  *
34  * Author: Erik Ekman <erik@kryo.se>
35  * Author: Jasper Verschueren <jasper.verschueren@apart-audio.com>
36  *
37  */
38 #ifndef LWIP_HDR_MDNS_PRIV_H
39 #define LWIP_HDR_MDNS_PRIV_H
40 
41 #include "lwip/apps/mdns.h"
42 #include "lwip/apps/mdns_opts.h"
43 #include "lwip/pbuf.h"
44 
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48 
49 #if LWIP_MDNS_RESPONDER
50 
51 #define MDNS_READNAME_ERROR 0xFFFF
52 #define NUM_DOMAIN_OFFSETS 10
53 
54 #define SRV_PRIORITY 0
55 #define SRV_WEIGHT   0
56 
57 /* mDNS TTL: (RFC6762 section 10)
58  *  - 120 seconds if the hostname appears somewhere in the RR
59  *  - 75 minutes if not (4500 seconds)
60  *  - 10 seconds if responding to a legacy query
61  */
62 #define MDNS_TTL_10    10
63 #define MDNS_TTL_120   120
64 #define MDNS_TTL_4500  4500
65 
66 /* RFC6762 section 8.1: If fifteen conflicts occur within any ten-second period,
67  * then the host MUST wait at least five seconds before each successive
68  * additional probe attempt.
69  */
70 #define MDNS_PROBE_MAX_CONFLICTS_BEFORE_RATE_LIMIT  15
71 #define MDNS_PROBE_MAX_CONFLICTS_TIME_WINDOW        10000
72 #define MDNS_PROBE_MAX_CONFLICTS_TIMEOUT            5000
73 
74 #if LWIP_MDNS_SEARCH
75 /** Description of a search request */
76 struct mdns_request {
77   /** Name of service, like 'myweb' */
78   char name[MDNS_LABEL_MAXLEN + 1];
79   /** Type of service, like '_http' or '_services._dns-sd' */
80   struct mdns_domain service;
81   /** Callback function called for each response */
82   search_result_fn_t result_fn;
83   void *arg;
84   /** Protocol, TCP or UDP */
85   u16_t proto;
86   /** Query type (PTR, SRV, ...) */
87   u8_t qtype;
88   /** PTR only request. */
89   u16_t only_ptr;
90 };
91 #endif
92 
93 /** Description of a service */
94 struct mdns_service {
95   /** TXT record to answer with */
96   struct mdns_domain txtdata;
97   /** Name of service, like 'myweb' */
98   char name[MDNS_LABEL_MAXLEN + 1];
99   /** Type of service, like '_http' */
100   char service[MDNS_LABEL_MAXLEN + 1];
101   /** Callback function and userdata
102    * to update txtdata buffer */
103   service_get_txt_fn_t txt_fn;
104   void *txt_userdata;
105   /** Protocol, TCP or UDP */
106   u16_t proto;
107   /** Port of the service */
108   u16_t port;
109 };
110 
111 /** mDNS output packet */
112 struct mdns_outpacket {
113   /** Packet data */
114   struct pbuf *pbuf;
115   /** Current write offset in packet */
116   u16_t write_offset;
117   /** Number of questions written */
118   u16_t questions;
119   /** Number of normal answers written */
120   u16_t answers;
121   /** Number of authoritative answers written */
122   u16_t authoritative;
123   /** Number of additional answers written */
124   u16_t additional;
125   /** Offsets for written domain names in packet.
126    *  Used for compression */
127   u16_t domain_offsets[NUM_DOMAIN_OFFSETS];
128 };
129 
130 /** mDNS output message */
131 struct mdns_outmsg {
132   /** Identifier. Used in legacy queries */
133   u16_t tx_id;
134   /** dns flags */
135   u8_t flags;
136   /** Destination IP/port if sent unicast */
137   ip_addr_t dest_addr;
138   u16_t dest_port;
139   /** If all answers in packet should set cache_flush bit */
140   u8_t cache_flush;
141   /** If reply should be sent unicast (as requested) */
142   u8_t unicast_reply_requested;
143   /** If legacy query. (tx_id needed, and write
144    *  question again in reply before answer) */
145   u8_t legacy_query;
146   /** If the query is a probe msg we need to respond immediately. Independent of
147    *  the QU or QM flag. */
148   u8_t probe_query_recv;
149   /* Question bitmask for host information */
150   u8_t host_questions;
151   /* Questions bitmask per service */
152   u8_t serv_questions[MDNS_MAX_SERVICES];
153   /* Reply bitmask for host information */
154   u8_t host_replies;
155   /* Bitmask for which reverse IPv6 hosts to answer */
156   u8_t host_reverse_v6_replies;
157   /* Reply bitmask per service */
158   u8_t serv_replies[MDNS_MAX_SERVICES];
159 #ifdef LWIP_MDNS_SEARCH
160   /** Search query to send */
161   struct mdns_request *query;
162 #endif
163 };
164 
165 /** Delayed msg info */
166 struct mdns_delayed_msg {
167   /** Signals if a multicast msg needs to be send out */
168   u8_t multicast_msg_waiting;
169   /** Multicast timeout for all multicast traffic except probe answers */
170   u8_t multicast_timeout;
171   /** Multicast timeout only for probe answers */
172   u8_t multicast_probe_timeout;
173   /** Output msg used for delayed multicast responses */
174   struct mdns_outmsg delayed_msg_multicast;
175   /** Prefer multicast over unicast timeout -> 25% of TTL = we take 30s as
176       general delay. */
177   u8_t multicast_timeout_25TTL;
178   /** Only send out new unicast message if previous was send */
179   u8_t unicast_msg_in_use;
180   /** Output msg used for delayed unicast responses */
181   struct mdns_outmsg delayed_msg_unicast;
182 };
183 
184 /* MDNS states */
185 typedef enum {
186   /* MDNS module is off */
187   MDNS_STATE_OFF,
188   /* Waiting before probing can be started */
189   MDNS_STATE_PROBE_WAIT,
190   /* Probing the unique records */
191   MDNS_STATE_PROBING,
192   /* Waiting before announcing the probed unique records */
193   MDNS_STATE_ANNOUNCE_WAIT,
194   /* Announcing all records */
195   MDNS_STATE_ANNOUNCING,
196   /* Probing and announcing completed */
197   MDNS_STATE_COMPLETE
198 } mdns_resp_state_enum_t;
199 
200 /** Description of a host/netif */
201 struct mdns_host {
202   /** Hostname */
203   char name[MDNS_LABEL_MAXLEN + 1];
204   /** Pointer to services */
205   struct mdns_service *services[MDNS_MAX_SERVICES];
206   /** Number of probes/announces sent for the current name */
207   u8_t sent_num;
208   /** State of the mdns responder */
209   mdns_resp_state_enum_t state;
210 #if LWIP_IPV4
211   /** delayed msg struct for IPv4 */
212   struct mdns_delayed_msg ipv4;
213 #endif
214 #if LWIP_IPV6
215   /** delayed msg struct for IPv6 */
216   struct mdns_delayed_msg ipv6;
217 #endif
218   /** Timestamp of probe conflict saved in list */
219   u32_t conflict_time[MDNS_PROBE_MAX_CONFLICTS_BEFORE_RATE_LIMIT];
220   /** Rate limit flag */
221   u8_t rate_limit_activated;
222   /** List index for timestamps */
223   u8_t index;
224   /** number of conflicts since startup */
225   u8_t num_conflicts;
226 };
227 
228 struct mdns_host* netif_mdns_data(struct netif *netif);
229 struct udp_pcb* get_mdns_pcb(void);
230 
231 #endif /* LWIP_MDNS_RESPONDER */
232 
233 #ifdef __cplusplus
234 }
235 #endif
236 
237 #endif /* LWIP_HDR_MDNS_PRIV_H */
238