mDNS Service
Overview
mDNS is a multicast UDP service that is used to provide local network service and host discovery.
mDNS is installed by default on most operating systems or is available as separate package. On Mac OS
it is installed by default and is called Bonjour
. Apple releases an installer for Windows
that can be found on Apple’s support page. On Linux
, mDNS is provided by avahi and is usually installed by default.
mDNS Properties
hostname
: the hostname that the device will respond to. If not set, thehostname
will be read from the interface. Example:my-esp32s2
will resolve tomy-esp32s2.local
default_instance
: friendly name for your device, likeJhon's ESP32-S2 Thing
. If not set,hostname
will be used.
Example method to start mDNS for the STA interface and set hostname
and default_instance
:
void start_mdns_service()
{
//initialize mDNS service
esp_err_t err = mdns_init();
if (err) {
printf("MDNS Init failed: %d\n", err);
return;
}
//set hostname
mdns_hostname_set("my-esp32s2");
//set default instance
mdns_instance_name_set("Jhon's ESP32-S2 Thing");
}
mDNS Services
mDNS can advertise information about network services that your device offers. Each service is defined by a few properties.
instance_name
: friendly name for your service, likeJhon's EESP32-S2 Web Server
. If not defined,default_instance
will be used.
service_type
: (required) service type, prepended with underscore. Some common types can be found here.
proto
: (required) protocol that the service runs on, prepended with underscore. Example:_tcp
or_udp
port
: (required) network port that the service runs on
txt
:{var, val}
array of strings, used to define properties for your service
Example method to add a few services and different properties:
void add_mdns_services()
{
//add our services
mdns_service_add(NULL, "_http", "_tcp", 80, NULL, 0);
mdns_service_add(NULL, "_arduino", "_tcp", 3232, NULL, 0);
mdns_service_add(NULL, "_myservice", "_udp", 1234, NULL, 0);
//NOTE: services must be added before their properties can be set
//use custom instance for the web server
mdns_service_instance_name_set("_http", "_tcp", "Jhon's ESP32-S2 Web Server");
mdns_txt_item_t serviceTxtData[3] = {
{"board","{esp32s2}"},
{"u","user"},
{"p","password"}
};
//set txt data for service (will free and replace current data)
mdns_service_txt_set("_http", "_tcp", serviceTxtData, 3);
//change service port
mdns_service_port_set("_myservice", "_udp", 4321);
}
mDNS Query
mDNS provides methods for browsing for services and resolving host’s IP/IPv6 addresses.
Results for services are returned as a linked list of mdns_result_t
objects.
Example method to resolve host IPs:
void resolve_mdns_host(const char * host_name)
{
printf("Query A: %s.local", host_name);
struct ip4_addr addr;
addr.addr = 0;
esp_err_t err = mdns_query_a(host_name, 2000, &addr);
if(err){
if(err == ESP_ERR_NOT_FOUND){
printf("Host was not found!");
return;
}
printf("Query Failed");
return;
}
printf(IPSTR, IP2STR(&addr));
}
Example method to resolve local services:
static const char * if_str[] = {"STA", "AP", "ETH", "MAX"};
static const char * ip_protocol_str[] = {"V4", "V6", "MAX"};
void mdns_print_results(mdns_result_t * results){
mdns_result_t * r = results;
mdns_ip_addr_t * a = NULL;
int i = 1, t;
while(r){
printf("%d: Interface: %s, Type: %s\n", i++, if_str[r->tcpip_if], ip_protocol_str[r->ip_protocol]);
if(r->instance_name){
printf(" PTR : %s\n", r->instance_name);
}
if(r->hostname){
printf(" SRV : %s.local:%u\n", r->hostname, r->port);
}
if(r->txt_count){
printf(" TXT : [%u] ", r->txt_count);
for(t=0; t<r->txt_count; t++){
printf("%s=%s; ", r->txt[t].key, r->txt[t].value);
}
printf("\n");
}
a = r->addr;
while(a){
if(a->addr.type == IPADDR_TYPE_V6){
printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6));
} else {
printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4)));
}
a = a->next;
}
r = r->next;
}
}
void find_mdns_service(const char * service_name, const char * proto)
{
ESP_LOGI(TAG, "Query PTR: %s.%s.local", service_name, proto);
mdns_result_t * results = NULL;
esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20, &results);
if(err){
ESP_LOGE(TAG, "Query Failed");
return;
}
if(!results){
ESP_LOGW(TAG, "No results found!");
return;
}
mdns_print_results(results);
mdns_query_results_free(results);
}
Example of using the methods above:
void my_app_some_method(){
//search for esp32s2-mdns.local
resolve_mdns_host("esp32s2-mdns");
//search for HTTP servers
find_mdns_service("_http", "_tcp");
//or file servers
find_mdns_service("_smb", "_tcp"); //windows sharing
find_mdns_service("_afpovertcp", "_tcp"); //apple sharing
find_mdns_service("_nfs", "_tcp"); //NFS server
find_mdns_service("_ftp", "_tcp"); //FTP server
//or networked printer
find_mdns_service("_printer", "_tcp");
find_mdns_service("_ipp", "_tcp");
}
Application Example
mDNS server/scanner example: protocols/mdns.
API Reference
Header File
Functions
-
esp_err_t mdns_init(void)
Initialize mDNS on given interface.
- Returns
ESP_OK on success
ESP_ERR_INVALID_STATE when failed to register event handler
ESP_ERR_NO_MEM on memory error
ESP_FAIL when failed to start mdns task
-
void mdns_free(void)
Stop and free mDNS server.
-
esp_err_t mdns_hostname_set(const char *hostname)
Set the hostname for mDNS server required if you want to advertise services.
- Parameters
hostname – Hostname to set
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_delegate_hostname_add(const char *hostname, const mdns_ip_addr_t *address_list)
Adds a hostname and address to be delegated A/AAAA queries will be replied for the hostname and services can be added to this host.
- Parameters
hostname – Hostname to add
address_list – The IP address list of the host
- Returns
ESP_OK success
ESP_ERR_INVALID_STATE mDNS is not running
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_delegate_hostname_remove(const char *hostname)
Remove a delegated hostname All the services added to this host will also be removed.
- Parameters
hostname – Hostname to remove
- Returns
ESP_OK success
ESP_ERR_INVALID_STATE mDNS is not running
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NO_MEM memory error
-
bool mdns_hostname_exists(const char *hostname)
Query whether a hostname has been added.
- Parameters
hostname – Hostname to query
- Returns
true The hostname has been added.
false The hostname has not been added.
-
esp_err_t mdns_instance_name_set(const char *instance_name)
Set the default instance name for mDNS server.
- Parameters
instance_name – Instance name to set
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_add(const char *instance_name, const char *service_type, const char *proto, uint16_t port, mdns_txt_item_t txt[], size_t num_items)
Add service to mDNS server.
Note
The value length of txt items will be automatically decided by strlen
- Parameters
instance_name – instance name to set. If NULL, global instance name or hostname will be used. Note that MDNS_MULTIPLE_INSTANCE config option needs to be enabled for adding multiple instances with the same instance type.
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
port – service port
txt – string array of TXT data (eg. {{“var”,”val”},{“other”,”2”}})
num_items – number of items in TXT data
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NO_MEM memory error
ESP_FAIL failed to add service
-
esp_err_t mdns_service_add_for_host(const char *instance_name, const char *service_type, const char *proto, const char *hostname, uint16_t port, mdns_txt_item_t txt[], size_t num_items)
Add service to mDNS server with a delegated hostname.
Note
The value length of txt items will be automatically decided by strlen
- Parameters
instance_name – instance name to set. If NULL, global instance name or hostname will be used Note that MDNS_MULTIPLE_INSTANCE config option needs to be enabled for adding multiple instances with the same instance type.
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
hostname – service hostname. If NULL, local hostname will be used.
port – service port
txt – string array of TXT data (eg. {{“var”,”val”},{“other”,”2”}})
num_items – number of items in TXT data
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NO_MEM memory error
ESP_FAIL failed to add service
-
bool mdns_service_exists(const char *service_type, const char *proto, const char *hostname)
Check whether a service has been added.
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
hostname – service hostname. If NULL, checks for the local hostname.
- Returns
true Correspondding service has been added.
false Service not found.
-
bool mdns_service_exists_with_instance(const char *instance, const char *service_type, const char *proto, const char *hostname)
Check whether a service has been added.
- Parameters
instance – instance name
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
hostname – service hostname. If NULL, checks for the local hostname.
- Returns
true Correspondding service has been added.
false Service not found.
-
esp_err_t mdns_service_remove(const char *service_type, const char *proto)
Remove service from mDNS server.
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Service not found
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_remove_for_host(const char *service_type, const char *proto, const char *hostname)
Remove service from mDNS server with hostname.
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
hostname – service hostname. If NULL, local hostname will be used.
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Service not found
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_instance_name_set(const char *service_type, const char *proto, const char *instance_name)
Set instance name for service.
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
instance_name – instance name to set
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Service not found
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_instance_name_set_for_host(const char *service_type, const char *proto, const char *hostname, const char *instance_name)
Set instance name for service with hostname.
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
hostname – service hostname. If NULL, local hostname will be used.
instance_name – instance name to set
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Service not found
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_port_set(const char *service_type, const char *proto, uint16_t port)
Set service port.
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
port – service port
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Service not found
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_port_set_for_host(const char *service_type, const char *proto, const char *hostname, uint16_t port)
Set service port with hostname.
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
hostname – service hostname. If NULL, local hostname will be used.
port – service port
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Service not found
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_txt_set(const char *service_type, const char *proto, mdns_txt_item_t txt[], uint8_t num_items)
Replace all TXT items for service.
Note
The value length of txt items will be automatically decided by strlen
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
txt – array of TXT data (eg. {{“var”,”val”},{“other”,”2”}})
num_items – number of items in TXT data
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Service not found
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_txt_set_for_host(const char *service_type, const char *proto, const char *hostname, mdns_txt_item_t txt[], uint8_t num_items)
Replace all TXT items for service with hostname.
Note
The value length of txt items will be automatically decided by strlen
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
hostname – service hostname. If NULL, local hostname will be used.
txt – array of TXT data (eg. {{“var”,”val”},{“other”,”2”}})
num_items – number of items in TXT data
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Service not found
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_txt_item_set(const char *service_type, const char *proto, const char *key, const char *value)
Set/Add TXT item for service TXT record.
Note
The value length will be automatically decided by strlen
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
key – the key that you want to add/update
value – the new value of the key
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Service not found
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_txt_item_set_with_explicit_value_len(const char *service_type, const char *proto, const char *key, const char *value, uint8_t value_len)
Set/Add TXT item for service TXT record.
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
key – the key that you want to add/update
value – the new value of the key
value_len – the length of the value
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Service not found
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_txt_item_set_for_host(const char *service_type, const char *proto, const char *hostname, const char *key, const char *value)
Set/Add TXT item for service TXT record with hostname.
Note
The value length will be automatically decided by strlen
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
hostname – service hostname. If NULL, local hostname will be used.
key – the key that you want to add/update
value – the new value of the key
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Service not found
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_txt_item_set_for_host_with_explicit_value_len(const char *service_type, const char *proto, const char *hostname, const char *key, const char *value, uint8_t value_len)
Set/Add TXT item for service TXT record with hostname and txt value length.
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
hostname – service hostname. If NULL, local hostname will be used.
key – the key that you want to add/update
value – the new value of the key
value_len – the length of the value
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Service not found
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_txt_item_remove(const char *service_type, const char *proto, const char *key)
Remove TXT item for service TXT record.
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
key – the key that you want to remove
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Service not found
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_txt_item_remove_for_host(const char *service_type, const char *proto, const char *hostname, const char *key)
Remove TXT item for service TXT record with hostname.
- Parameters
service_type – service type (_http, _ftp, etc)
proto – service protocol (_tcp, _udp)
hostname – service hostname. If NULL, local hostname will be used.
key – the key that you want to remove
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
ESP_ERR_NOT_FOUND Service not found
ESP_ERR_NO_MEM memory error
-
esp_err_t mdns_service_remove_all(void)
Remove and free all services from mDNS server.
- Returns
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
-
esp_err_t mdns_query_async_delete(mdns_search_once_t *search)
Deletes the finished query. Call this only after the search has ended!
- Parameters
search – pointer to search object
- Returns
ESP_OK success
ESP_ERR_INVALID_STATE search has not finished
ESP_ERR_INVALID_ARG pointer to search object is NULL
-
bool mdns_query_async_get_results(mdns_search_once_t *search, uint32_t timeout, mdns_result_t **results)
Get results from search pointer. Results available as a pointer to the output parameter. Pointer to search object has to be deleted via
mdns_query_async_delete
once the query has finished. The results although have to be freed manually.- Parameters
search – pointer to search object
timeout – time in milliseconds to wait for answers
results – pointer to the results of the query
- Returns
True if search has finished before or at timeout False if search timeout is over
-
mdns_search_once_t *mdns_query_async_new(const char *name, const char *service_type, const char *proto, uint16_t type, uint32_t timeout, size_t max_results, mdns_query_notify_t notifier)
Query mDNS for host or service asynchronousely. Search has to be tested for progress and deleted manually!
- Parameters
name – service instance or host name (NULL for PTR queries)
service_type – service type (_http, _arduino, _ftp etc.) (NULL for host queries)
proto – service protocol (_tcp, _udp, etc.) (NULL for host queries)
type – type of query (MDNS_TYPE_*)
timeout – time in milliseconds during which mDNS query is active
max_results – maximum results to be collected
notifier – Notification function to be called when the result is ready, can be NULL
- Returns
mdns_search_once_s pointer to new search object if query initiated successfully. NULL otherwise.
-
esp_err_t mdns_query(const char *name, const char *service_type, const char *proto, uint16_t type, uint32_t timeout, size_t max_results, mdns_result_t **results)
Query mDNS for host or service All following query methods are derived from this one.
- Parameters
name – service instance or host name (NULL for PTR queries)
service_type – service type (_http, _arduino, _ftp etc.) (NULL for host queries)
proto – service protocol (_tcp, _udp, etc.) (NULL for host queries)
type – type of query (MDNS_TYPE_*)
timeout – time in milliseconds to wait for answers.
max_results – maximum results to be collected
results – pointer to the results of the query results must be freed using mdns_query_results_free below
- Returns
ESP_OK success
ESP_ERR_INVALID_STATE mDNS is not running
ESP_ERR_NO_MEM memory error
ESP_ERR_INVALID_ARG timeout was not given
-
void mdns_query_results_free(mdns_result_t *results)
Free query results.
- Parameters
results – linked list of results to be freed
-
esp_err_t mdns_query_ptr(const char *service_type, const char *proto, uint32_t timeout, size_t max_results, mdns_result_t **results)
Query mDNS for service.
- Parameters
service_type – service type (_http, _arduino, _ftp etc.)
proto – service protocol (_tcp, _udp, etc.)
timeout – time in milliseconds to wait for answer.
max_results – maximum results to be collected
results – pointer to the results of the query
- Returns
ESP_OK success
ESP_ERR_INVALID_STATE mDNS is not running
ESP_ERR_NO_MEM memory error
ESP_ERR_INVALID_ARG parameter error
-
esp_err_t mdns_query_srv(const char *instance_name, const char *service_type, const char *proto, uint32_t timeout, mdns_result_t **result)
Query mDNS for SRV record.
- Parameters
instance_name – service instance name
service_type – service type (_http, _arduino, _ftp etc.)
proto – service protocol (_tcp, _udp, etc.)
timeout – time in milliseconds to wait for answer.
result – pointer to the result of the query
- Returns
ESP_OK success
ESP_ERR_INVALID_STATE mDNS is not running
ESP_ERR_NO_MEM memory error
ESP_ERR_INVALID_ARG parameter error
-
esp_err_t mdns_query_txt(const char *instance_name, const char *service_type, const char *proto, uint32_t timeout, mdns_result_t **result)
Query mDNS for TXT record.
- Parameters
instance_name – service instance name
service_type – service type (_http, _arduino, _ftp etc.)
proto – service protocol (_tcp, _udp, etc.)
timeout – time in milliseconds to wait for answer.
result – pointer to the result of the query
- Returns
ESP_OK success
ESP_ERR_INVALID_STATE mDNS is not running
ESP_ERR_NO_MEM memory error
ESP_ERR_INVALID_ARG parameter error
-
esp_err_t mdns_query_a(const char *host_name, uint32_t timeout, esp_ip4_addr_t *addr)
Query mDNS for A record.
- Parameters
host_name – host name to look for
timeout – time in milliseconds to wait for answer.
addr – pointer to the resulting IP4 address
- Returns
ESP_OK success
ESP_ERR_INVALID_STATE mDNS is not running
ESP_ERR_NO_MEM memory error
ESP_ERR_INVALID_ARG parameter error
-
esp_err_t mdns_query_aaaa(const char *host_name, uint32_t timeout, esp_ip6_addr_t *addr)
Query mDNS for A record.
Please note that hostname must not contain domain name, as mDNS uses ‘.local’ domain.
- Parameters
host_name – host name to look for
timeout – time in milliseconds to wait for answer. If 0, max_results needs to be defined
addr – pointer to the resulting IP6 address
- Returns
ESP_OK success
ESP_ERR_INVALID_STATE mDNS is not running
ESP_ERR_NO_MEM memory error
ESP_ERR_INVALID_ARG parameter error
-
esp_err_t mdns_handle_system_event(void *ctx, system_event_t *event)
System event handler This method controls the service state on all active interfaces and applications are required to call it from the system event handler for normal operation of mDNS service.
Please note that hostname must not contain domain name, as mDNS uses ‘.local’ domain.
- Parameters
ctx – The system event context
event – The system event
Structures
-
struct mdns_txt_item_t
mDNS basic text item structure Used in mdns_service_add()
-
struct mdns_ip_addr_s
mDNS query linked list IP item
Public Members
-
esp_ip_addr_t addr
IP address
-
struct mdns_ip_addr_s *next
next IP, or NULL for the last IP in the list
-
esp_ip_addr_t addr
-
struct mdns_result_s
mDNS query result structure
Public Members
-
struct mdns_result_s *next
next result, or NULL for the last result in the list
-
uint32_t ttl
time to live
-
mdns_ip_protocol_t ip_protocol
ip_protocol type of the interface (v4/v6)
-
char *instance_name
instance name
-
char *service_type
service type
-
char *proto
srevice protocol
-
char *hostname
hostname
-
uint16_t port
service port
-
mdns_txt_item_t *txt
txt record
-
uint8_t *txt_value_len
array of txt value len of each record
-
size_t txt_count
number of txt items
-
mdns_ip_addr_t *addr
linked list of IP addresses found
-
struct mdns_result_s *next
Macros
-
MDNS_TYPE_A
-
MDNS_TYPE_PTR
-
MDNS_TYPE_TXT
-
MDNS_TYPE_AAAA
-
MDNS_TYPE_SRV
-
MDNS_TYPE_OPT
-
MDNS_TYPE_NSEC
-
MDNS_TYPE_ANY
Type Definitions
-
typedef struct mdns_search_once_s mdns_search_once_t
Asynchronous query handle.
-
typedef struct mdns_ip_addr_s mdns_ip_addr_t
mDNS query linked list IP item
-
typedef enum mdns_if_internal mdns_if_t
-
typedef struct mdns_result_s mdns_result_t
mDNS query result structure
-
typedef void (*mdns_query_notify_t)(mdns_search_once_t *search)