1\section{MDNS client}
2
3% Short description/overview of module functions
4This module can register DNS resource records on the network via Multicast DNS as either \textbf{\emph{shared}} or \textbf{\emph{unique}} records. Unique records are, as the name implies, unique on the network (the record-name and -type combination is unique) and one single host has claimed the ownership of them. Shared records are records that are not unique on the network, which means multiple hosts can register records with the same record-name and -type combination. For more information on shared and unique resource record sets, see RFC6762.
5
6Unique records are, as it should, defended when somebody else tries to claim the same unique records. When hosts detect such a defense of another host while registering their own records, the conflict will be resolved by choosing another name for the records and another attempt is made to register those new records.
7
8This module only supplies the mechanisms of record registration and resolving on the network, it doesn't parses the contents of them, that's up to the application.
9
10\subsection{pico$\_$mdns$\_$init}
11
12\subsubsection*{Description}
13Initialises the entire mDNS-module and sets the hostname for this machine. Sets up the global mDNS socket properly and calls callback when succeeded. Only when the module is properly initialised, records can be registered on the network.
14\subsubsection*{Function prototype}
15\begin{verbatim}
16int pico_mdns_init( const char *hostname, 
17                    struct pico_ip4 address, 
18                    void (*callback)(pico_mdns_rtree *, char *, void *), 
19                    void *arg );
20\end{verbatim}
21
22\subsubsection*{Parameters}
23\begin{itemize}[noitemsep]
24\item \texttt{hostname} - Hostname to register for this machine. Should end with \'.local\'.
25\item \texttt{address} - IPv4-address of this machines interface to generate a hostname record from.
26\item \texttt{cb$\_$initialised} - Callback-function that is called when the initialisation process is done. This will also get called when asynchronous conflicts occur for successfully registered records during run-time. The mDNS-record tree contains the registered records, the char-buffer contains the registered hostname and the void-pointer contains the passed argument.
27\item \texttt{arg} - Argument for callback supplied by user. This can be used if you want to pass some variable into your callback function.
28\end{itemize}
29
30\subsubsection*{Return value}
31Returns 0 when the module is properly initialised and the host started registering the hostname. Returns something else went the host failed initialising the module or registering the hostname. \texttt{pico$\_$err} is set appropriately.
32
33\subsubsection*{Errors}
34\begin{itemize}[noitemsep]
35\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument
36\item \texttt{PICO$\_$ERR$\_$ENOMEM} - not enough space
37\end{itemize}
38
39\subsubsection*{Example}
40\begin{verbatim}
41pico_mdns_init("host.local", address, &mdns_init_callback, NULL);
42\end{verbatim}
43
44
45\subsection{pico$\_$mdns$\_$get$\_$hostname}
46
47\subsubsection*{Description}
48Get the current hostname for this machine.
49
50\subsubsection*{Function prototype}
51\begin{verbatim}
52const char * pico_mdns_get_hostname( void );
53\end{verbatim}
54
55\subsubsection*{Return value}
56Returns the current hostname for this machine when the module is initialised, returns NULL when the module is not initialised.
57
58\subsubsection*{Errors}
59\begin{itemize}[noitemsep]
60\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument
61\end{itemize}
62
63\subsubsection*{Example}
64\begin{verbatim}
65char *url = pico_mdns_get_hostname();
66\end{verbatim}
67
68
69\subsection{pico$\_$mdns$\_$set$\_$hostname}
70
71\subsubsection*{Description}
72Tries to claim a hostname for this machine. Claims automatically a unique A record with the IPv4-address of this host. The hostname won't be set directly when this functions returns, but only if the claiming of the unique record succeeded. Init-callback specified when initialising the module will be called when the hostname-record is successfully registered.
73
74\subsubsection*{Function prototype}
75\begin{verbatim}
76int pico_mdns_tryclaim_hostname( const char *url, void *arg );
77\end{verbatim}
78
79\subsubsection*{Parameters}
80\begin{itemize}[noitemsep]
81\item \texttt{url} - URL to set the hostname to. Should end with \'.local\'.
82\item \texttt{arg} - Argument for init-callback supplied by user. This can be used if you want to pass some variable into your callback function.
83\end{itemize}
84
85\subsubsection*{Return value}
86Returns 0 when the host started registering the hostname-record successfully, returns something else when it didn't succeed. \texttt{pico$\_$err} is set appropriately.
87
88\subsubsection*{Errors}
89\begin{itemize}[noitemsep]
90\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument
91\item \texttt{PICO$\_$ERR$\_$ENOMEM} - not enough space
92\end{itemize}
93
94\subsubsection*{Example}
95\begin{verbatim}
96int ret = pico_mdns_tryclaim_hostname("device.local", NULL);
97\end{verbatim}
98
99
100\subsection{pico$\_$mdns$\_$claim}
101
102\subsubsection*{Description}
103Claims all different mDNS records in a tree in a single API-call. All records in the mDNS record-tree are registered in a single new claim-session.
104
105\subsubsection*{Function prototype}
106\begin{verbatim}
107int pico_mdns_claim( pico_mdns_rtree record_tree,
108                     void (*callback)(pico_mdns_rtree *,  char *, void *),
109                     void *arg );
110\end{verbatim}
111
112\subsubsection*{Parameters}
113\begin{itemize}[noitemsep]
114\item \texttt{record$\_$tree} - mDNS record-tree with records to register on the network via Multicast DNS. Can contain \textbf{\emph{unique records}} as well as \textbf{\emph{shared records}}. Declare a mDNS record-tree with the macro 'PICO$\_$MDNS$\_$RTREE$\_$DECLARE(name)', which is actually just a pico$\_$tree-struct, with a comparing-function already set. Records can be added with the preprocessor macro 'PICO$\_$MDNS$\_$RTREE$\_$ADD(pico$\_$mdns$\_$rtree *, struct pico$\_$mdns$\_$record *)'. To create mDNS records see 'pico$\_$mdns$\_$record$\_$create'.
115\item \texttt{callback} - Callback function that gets called when \textbf{\emph{ALL}} records in the tree are successfully registered on the network. Records in the returned tree can differ from records originally registered due to conflict-resolution and such.
116\item \texttt{arg} - Argument for callback supplied by user. This can be used if you want to pass some variable into your callback function.
117\end{itemize}
118
119\subsubsection*{Return value}
120Returns 0 when the host started registering the record successfully, returns something else when it didn't succeed. \texttt{pico$\_$err} is set appropriately.
121
122\subsubsection*{Errors}
123\begin{itemize}[noitemsep]
124\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument
125\item \texttt{PICO$\_$ERR$\_$ENOMEM} - not enough space
126\end{itemize}
127
128\subsubsection*{Example}
129\begin{verbatim}
130...
131PICO_MDNS_RTREE_DECLARE(rtree);
132PICO_MDNS_RTREE_ADD(&rtree, &record);
133int ret = pico_mdns_claim(rtree, &claimed_cb, NULL);
134\end{verbatim}
135
136
137\subsection{pico$\_$mdns$\_$getrecord}
138
139\subsubsection*{Description}
140API-call to query a record with a certain URL and type. First checks the cache for this record. If no cache-entry is found, a query will be sent on the wire for this record.
141
142\subsubsection*{Function prototype}
143\begin{verbatim}
144int pico_mdns_getrecord( const char *url, uint16_t type,
145                         void (*callback)(pico_mdns_rtree *, char *, void *),
146                         void *arg );
147\end{verbatim}
148
149\subsubsection*{Parameters}
150\begin{itemize}[noitemsep]
151\item \texttt{url} - URL of the DNS name to query records for.
152\item \texttt{type} - DNS type of the records to query for on the network.
153\item \texttt{callback} - Callback to call when records are found or answers to the query are received. This functions can get called multiple times when multiple answers are possible (e.g. with shared records). It's up to the application to aggregate all these received answers, this is possible with a static variable of the type pico$\_$mdns$\_$rtree.
154\item \texttt{arg} - Argument for callback supplied by user. This can be used if you want to pass some variable into your callback function.
155\end{itemize}
156
157\subsubsection*{Return value}
158Returns 0 when the host started querying for these records successfully or the records are found in the cache. Returns something else when it didn't succeed. \texttt{pico$\_$err} is set appropriately.
159
160\subsubsection*{Errors}
161\begin{itemize}[noitemsep]
162\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument
163\item \texttt{PICO$\_$ERR$\_$ENOMEM} - not enough space
164\end{itemize}
165
166\subsubsection*{Example}
167\begin{verbatim}
168int ret = pico_mdns_getrecord("_ipp._tcp.local", PICO_DNS_TYPE_PTR, &query_cb, NULL);
169\end{verbatim}
170
171
172\subsection{pico$\_$mdns$\_$record$\_$create}
173
174\subsubsection*{Description}
175Creates a single standalone mDNS resource record with given name, type and data to register on the network.
176
177\subsubsection*{Function prototype}
178\begin{verbatim}
179struct pico_mdns_record *pico_mdns_record_create( const char *url,
180                                                  void *_rdata,
181                                                  uint16_t datalen,
182                                                  uint16_t rtype,
183                                                  uint32_t rttl,
184                                                  uint8_t flags );
185\end{verbatim}
186
187\subsubsection*{Parameters}
188\begin{itemize}[noitemsep]
189\item \texttt{url} - DNS resource record name in URL format. Will be converted to DNS name notation format.
190\item \texttt{$\_$rdata} - Memory buffer with data to insert in the resource record. If data of record should contain a DNS name, the name in the databuffer needs to be in URL-format.
191\item \texttt{datalen} - The exact length in bytes of the $\_$rdata-buffer. If data of record should contain a DNS name (f.e. with PICO$\_$DNS$\_$TYPE$\_$PTR), datalen needs to be pico$\_$dns$\_$strlen($\_$rdata).
192\item \texttt{rtype} - DNS type of the resource record to be.
193\item \texttt{ttl} - TTL of the resource record to be when registered on the network. In seconds.
194\item \texttt{flags} - With this parameter, you can specify a record as either a shared record or a unique record with respectively PICO$\_$MDNS$\_$RECORD$\_$SHARED- or PICO$\_$MDNS$\_$RECORD$\_$UNIQUE-preprocessor defines. Records are by default registered as unique.
195\end{itemize}
196
197\subsubsection*{Return value}
198Returns a pointer to the newly created record on success, returns NULL on failure. \texttt{pico$\_$err} is set appropriately.
199
200\subsubsection*{Errors}
201\begin{itemize}[noitemsep]
202\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument
203\item \texttt{PICO$\_$ERR$\_$ENOMEM} - not enough space
204\end{itemize}
205
206\subsubsection*{Example}
207\begin{verbatim}
208pico_ip4 ip = 0;
209pico_string_to_ipv4("10.10.0.5", &(ip.addr));
210struct pico_mdns_record *record = pico_mdns_record_create("foo.local", 
211                                                          &(ip.addr),
212                                                          PICO_SIZE_IP4,
213                                                          PICO_DNS_TYPE_ANY,
214                                                          120,
215                                                    PICO_MDNS_RECORD_UNIQUE);
216\end{verbatim}
217
218
219\subsection{IS$\_$HOSTNAME$\_$RECORD}
220
221\subsubsection*{Description}
222The initialisation-callback can get called multiple times during run-time due to \emph{passive conflict detection}. A passive conflict occurs for unique records when a faulty Multicast DNS-responder doesn't apply conflict resolution after an occurred conflict. A passive conflict can also occur when a peer registers a \textbf{\emph{shared}} record with the same name and type combination as a \textbf{\emph{unique}} record that the local host already successfully registered on the network. Because of that, shared records have priority over unique records, so unfortunately the local host has to apply the conflict resolution-mechanism to it's earlier uniquely verified record. To be able to notify the application of an updated unique record, the callback gets called given in the initialisation-function. But since that callback maybe parses the returned records as the hostname-records and this isn't necessarily the case when a passive conflict occurs, a mechanism is needed to differ hostname-records from other records. This preprocessor-macro allows this.
223
224\subsubsection*{Function prototype}
225\begin{verbatim}
226IS_HOSTNAME_RECORD(record)
227\end{verbatim}
228
229\subsubsection*{Parameters}
230\begin{itemize}[noitemsep]
231\item \texttt{record} - mDNS resource record
232\end{itemize}
233
234\subsubsection*{Return value}
235Returns 1 when this record is a hostname record, returns 0 when it's not or when given pointer is a NULL pointer.