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.