Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
mdns: WIP make networking decoupled from _mdns_server
  • Loading branch information
david-cermak authored and antmak committed Dec 13, 2022
commit b278ebf87ef7da2a0277bd0f25f8278ee6e976b4
23 changes: 12 additions & 11 deletions components/mdns/mdns.c
Original file line number Diff line number Diff line change
Expand Up @@ -1252,7 +1252,7 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an
} else if (answer->type == MDNS_TYPE_A) {
if (answer->host == &_mdns_self_host) {
esp_netif_ip_info_t if_ip_info;
if (!_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].state != PCB_DUP) {
if (!mdns_is_netif_ready(tcpip_if, MDNS_IP_PROTOCOL_V4) && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].state != PCB_DUP) {
return 0;
}
if (esp_netif_get_ip_info(_mdns_get_esp_netif(tcpip_if), &if_ip_info)) {
Expand Down Expand Up @@ -1280,7 +1280,7 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an
else if (answer->type == MDNS_TYPE_AAAA) {
if (answer->host == &_mdns_self_host) {
struct esp_ip6_addr if_ip6;
if (!_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].state != PCB_DUP) {
if (!mdns_is_netif_ready(tcpip_if, MDNS_IP_PROTOCOL_V6) && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].state != PCB_DUP) {
return 0;
}
if (esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(tcpip_if), &if_ip6)) {
Expand Down Expand Up @@ -2152,7 +2152,7 @@ static void _mdns_send_bye(mdns_srv_item_t **services, size_t len, bool include_

for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
for (j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
if (_mdns_server->interfaces[i].pcbs[j].pcb && _mdns_server->interfaces[i].pcbs[j].state == PCB_RUNNING) {
if (mdns_is_netif_ready(i, j) && _mdns_server->interfaces[i].pcbs[j].state == PCB_RUNNING) {
_mdns_pcb_send_bye((mdns_if_t)i, (mdns_ip_protocol_t)j, services, len, include_ip);
}
}
Expand All @@ -2166,7 +2166,7 @@ static void _mdns_announce_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protoco
{
mdns_pcb_t *_pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
size_t i;
if (_pcb->pcb) {
if (mdns_is_netif_ready(tcpip_if, ip_protocol)) {
if (PCB_STATE_IS_PROBING(_pcb)) {
_mdns_init_pcb_probe(tcpip_if, ip_protocol, services, len, include_ip);
} else if (PCB_STATE_IS_ANNOUNCING(_pcb)) {
Expand Down Expand Up @@ -2210,7 +2210,7 @@ static void _mdns_probe_all_pcbs(mdns_srv_item_t **services, size_t len, bool pr
uint8_t i, j;
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
for (j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
if (_mdns_server->interfaces[i].pcbs[j].pcb) {
if (mdns_is_netif_ready(i, j)) {
mdns_pcb_t *_pcb = &_mdns_server->interfaces[i].pcbs[j];
if (clear_old_probe) {
free(_pcb->probe_services);
Expand Down Expand Up @@ -2505,7 +2505,7 @@ static void _mdns_remove_scheduled_service_packets(mdns_service_t *service)


mdns_pcb_t *_pcb = &_mdns_server->interfaces[q->tcpip_if].pcbs[q->ip_protocol];
if (_pcb->pcb) {
if (mdns_is_netif_ready(q->tcpip_if, q->ip_protocol)) {
if (PCB_STATE_IS_PROBING(_pcb)) {
uint8_t i;
//check if we are probing this service
Expand Down Expand Up @@ -2717,9 +2717,9 @@ static void _mdns_dup_interface(mdns_if_t tcpip_if)
return; // no other interface found
}
for (i = 0; i < MDNS_IP_PROTOCOL_MAX; i++) {
if (_mdns_server->interfaces[other_if].pcbs[i].pcb) {
if (mdns_is_netif_ready(other_if, i)) {
//stop this interface and mark as dup
if (_mdns_server->interfaces[tcpip_if].pcbs[i].pcb) {
if (mdns_is_netif_ready(tcpip_if, i)) {
_mdns_clear_pcb_tx_queue_head(tcpip_if, i);
_mdns_pcb_deinit(tcpip_if, i);
}
Expand Down Expand Up @@ -3820,8 +3820,9 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
*/
void _mdns_enable_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (!_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
if (!mdns_is_netif_ready(tcpip_if, ip_protocol)) {
if (_mdns_pcb_init(tcpip_if, ip_protocol)) {
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].failed_probes = 0;
return;
}
}
Expand All @@ -3835,7 +3836,7 @@ void _mdns_disable_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
_mdns_clean_netif_ptr(tcpip_if);

if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
if (mdns_is_netif_ready(tcpip_if, ip_protocol)) {
_mdns_clear_pcb_tx_queue_head(tcpip_if, ip_protocol);
_mdns_pcb_deinit(tcpip_if, ip_protocol);
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
Expand Down Expand Up @@ -4454,7 +4455,7 @@ static mdns_tx_packet_t *_mdns_create_search_packet(mdns_search_once_t *search,
static void _mdns_search_send_pcb(mdns_search_once_t *search, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_tx_packet_t *packet = NULL;
if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb && _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].state > PCB_INIT) {
if (mdns_is_netif_ready(tcpip_if, ip_protocol) && _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].state > PCB_INIT) {
packet = _mdns_create_search_packet(search, tcpip_if, ip_protocol);
if (!packet) {
return;
Expand Down
112 changes: 54 additions & 58 deletions components/mdns/mdns_networking_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,18 @@
#include <net/if.h>
#endif

extern mdns_server_t *_mdns_server;
//extern mdns_server_t * _mdns_server;
enum interface_protocol {
PROTO_IPV4 = 1 << MDNS_IP_PROTOCOL_V4,
PROTO_IPV6 = 1 << MDNS_IP_PROTOCOL_V6
};

typedef struct interfaces {
int sock;
int proto;
} interfaces_t;

static interfaces_t s_interfaces[MDNS_MAX_INTERFACES];

static const char *TAG = "MDNS_Networking";
static bool s_run_sock_recv_task = false;
Expand All @@ -52,23 +63,9 @@ static void delete_socket(int sock)
close(sock);
}

static struct udp_pcb *sock_to_pcb(int sock)
{
if (sock < 0) {
return NULL;
}
// Note: sock=0 is a valid descriptor, so save it as +1 ("1" is a valid pointer)
intptr_t sock_plus_one = sock + 1;
return (struct udp_pcb *)sock_plus_one;
}

static int pcb_to_sock(struct udp_pcb *pcb)
bool mdns_is_netif_ready(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (pcb == NULL) {
return -1;
}
intptr_t sock_plus_one = (intptr_t)pcb;
return sock_plus_one - 1;
return s_interfaces[tcpip_if].proto & (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
}

void *_mdns_get_packet_data(mdns_rx_packet_t *packet)
Expand All @@ -90,23 +87,19 @@ void _mdns_packet_free(mdns_rx_packet_t *packet)

esp_err_t _mdns_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
struct udp_pcb *pcb = _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb;
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb = NULL;
if (_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb == NULL &&
_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb == NULL) {
// if the interface for both protocol uninitialized, close the interface socket
int sock = pcb_to_sock(pcb);
if (sock >= 0) {
delete_socket(sock);
s_interfaces[tcpip_if].proto &= ~(ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
if (s_interfaces[tcpip_if].proto == 0) {
// if the interface for both protocols uninitialized, close the interface socket
if (s_interfaces[tcpip_if].sock >= 0) {
delete_socket(s_interfaces[tcpip_if].sock);
}
}

for (int i = 0; i < MDNS_MAX_INTERFACES; i++) {
for (int j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
if (_mdns_server->interfaces[i].pcbs[j].pcb)
// If any of the interfaces/protocol initialized
if (s_interfaces[i].sock >= 0) {
// If any of the interfaces initialized
{
return ESP_OK;
return ESP_OK;
}
}
}
Expand Down Expand Up @@ -191,7 +184,10 @@ static inline size_t espaddr_to_inet(const esp_ip_addr_t *addr, const uint16_t p

size_t _mdns_udp_pcb_write(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const esp_ip_addr_t *ip, uint16_t port, uint8_t *data, size_t len)
{
int sock = pcb_to_sock(_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb);
if (!(s_interfaces[tcpip_if].proto & (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6))) {
return 0;
}
int sock = s_interfaces[tcpip_if].sock;
if (sock < 0) {
return 0;
}
Expand Down Expand Up @@ -250,12 +246,10 @@ void sock_recv_task(void *arg)
FD_ZERO(&rfds);
int max_sock = -1;
for (int i = 0; i < MDNS_MAX_INTERFACES; i++) {
for (int j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
int sock = pcb_to_sock(_mdns_server->interfaces[i].pcbs[j].pcb);
if (sock >= 0) {
FD_SET(sock, &rfds);
max_sock = MAX(max_sock, sock);
}
int sock = s_interfaces[i].sock;
if (sock >= 0) {
FD_SET(sock, &rfds);
max_sock = MAX(max_sock, sock);
}
}
if (max_sock < 0) {
Expand All @@ -270,11 +264,7 @@ void sock_recv_task(void *arg)
break;
} else if (s > 0) {
for (int tcpip_if = 0; tcpip_if < MDNS_MAX_INTERFACES; tcpip_if++) {
// Both protocols share once socket
int sock = pcb_to_sock(_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb);
if (sock < 0) {
sock = pcb_to_sock(_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb);
}
int sock = s_interfaces[tcpip_if].sock;
if (sock < 0) {
continue;
}
Expand Down Expand Up @@ -323,7 +313,7 @@ void sock_recv_task(void *arg)
packet->dest.type = packet->src.type;
packet->ip_protocol =
packet->src.type == ESP_IPADDR_TYPE_V4 ? MDNS_IP_PROTOCOL_V4 : MDNS_IP_PROTOCOL_V6;
if (!_mdns_server || !_mdns_server->action_queue || _mdns_send_rx_action(packet) != ESP_OK) {
if (_mdns_send_rx_action(packet) != ESP_OK) {
ESP_LOGE(TAG, "_mdns_send_rx_action failed!");
free(packet->pb->payload);
free(packet->pb);
Expand All @@ -339,46 +329,52 @@ void sock_recv_task(void *arg)
static void mdns_networking_init(void)
{
if (s_run_sock_recv_task == false) {
for (int i = 0; i < sizeof(s_interfaces)/sizeof(s_interfaces[0]); ++i) {
s_interfaces[i].sock = -1;
s_interfaces[i].proto = 0;
}
s_run_sock_recv_task = true;
xTaskCreate( sock_recv_task, "mdns recv task", 3 * 1024, NULL, 5, NULL );
}
}

static struct udp_pcb *create_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static bool create_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
return _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb;
if (s_interfaces[tcpip_if].proto & (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6)) {
return true;
}
mdns_ip_protocol_t other_ip_proto = ip_protocol == MDNS_IP_PROTOCOL_V4 ? MDNS_IP_PROTOCOL_V6 : MDNS_IP_PROTOCOL_V4;
int sock = s_interfaces[tcpip_if].sock;
esp_netif_t *netif = _mdns_get_esp_netif(tcpip_if);
if (_mdns_server->interfaces[tcpip_if].pcbs[other_ip_proto].pcb) {
struct udp_pcb *other_pcb = _mdns_server->interfaces[tcpip_if].pcbs[other_ip_proto].pcb;
int err = join_mdns_multicast_group(pcb_to_sock(other_pcb), netif, ip_protocol);
if (sock >= 0) {
mdns_ip_protocol_t other_ip_proto = ip_protocol==MDNS_IP_PROTOCOL_V4 ? MDNS_IP_PROTOCOL_V6 : MDNS_IP_PROTOCOL_V4;
int err = join_mdns_multicast_group(sock, netif, other_ip_proto);
if (err < 0) {
ESP_LOGE(TAG, "Failed to add ipv6 multicast group for protocol %d", ip_protocol);
return NULL;
return false;
}
return other_pcb;
s_interfaces[tcpip_if].proto |= (other_ip_proto == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
return true;
}
int sock = create_socket(netif);
sock = create_socket(netif);
if (sock < 0) {
ESP_LOGE(TAG, "Failed to create the socket!");
return NULL;
return false;
}
int err = join_mdns_multicast_group(sock, netif, ip_protocol);
if (err < 0) {
ESP_LOGE(TAG, "Failed to add ipv6 multicast group for protocol %d", ip_protocol);
}
return sock_to_pcb(sock);
s_interfaces[tcpip_if].proto |= (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
return true;
}

esp_err_t _mdns_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
ESP_LOGI(TAG, "_mdns_pcb_init(tcpip_if=%d, ip_protocol=%d)", tcpip_if, ip_protocol);
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb = create_pcb(tcpip_if, ip_protocol);
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].failed_probes = 0;

mdns_networking_init();
ESP_LOGI(TAG, "_mdns_pcb_init(tcpip_if=%d, ip_protocol=%d)", tcpip_if, ip_protocol);
if (!create_pcb(tcpip_if, ip_protocol)) {
return ESP_FAIL;
}
return ESP_OK;
}

Expand Down
2 changes: 2 additions & 0 deletions components/mdns/private_include/mdns_networking.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
*/
esp_err_t _mdns_send_rx_action(mdns_rx_packet_t *packet);

bool mdns_is_netif_ready(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);

/**
* @brief Start PCB
*/
Expand Down
1 change: 0 additions & 1 deletion components/mdns/private_include/mdns_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,6 @@ typedef struct mdns_tx_packet_s {

typedef struct {
mdns_pcb_state_t state;
struct udp_pcb *pcb;
mdns_srv_item_t **probe_services;
uint8_t probe_services_len;
uint8_t probe_ip;
Expand Down