Network interface of the incoming mDNS request

  1. How to respond to mDNS A record queries on the interface that the request arrived? For example if I have WiFi AP and Ethernet interfaces connected to 2 different networks, what interface IP address is in the A record response? How do I tell the multicast nodes on the network my IP address (A record).
  2. I am using ESP32 hardware with the dns-sd library from github, and mos 2.17.0
  3. if WiFi is turned on, the mDNS A record responses from mgos indicate the IP address of the WiFi AP, not the interface that received the request.
  4. Is there any way to know the interface that the request arrived on? Is there a way to extract the interface identifer from the struct mg_connection pointer of the received packet? Could this be cached when the IP address is acquired and used elsewhere in the code?

Here is my hacked up version of add_a_record() in mgos_dns_sd.c, but it doesn’t handle properly requests from a multicast address. It only works for unicast.

static void add_a_record(struct mg_connection *nc, struct mg_dns_reply *reply, 
                         struct mg_str name, bool naive_client, int ttl, struct mbuf *rdata) {
  in_addr_t addr = 0;
  struct mgos_net_ip_info ip_info;
  char str_ip[16];
  (void) str_ip;
  // check from which interface the request came
#ifdef MGOS_HAVE_ETHERNET
  if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_ETHERNET, 0, &ip_info)) {
    LOG(LL_DEBUG,
        ("Ethernet address %08x, mask %08x", ip_info.ip.sin_addr.s_addr,
         ip_info.netmask.sin_addr.s_addr));
    LOG(LL_DEBUG, ("ip_info.ip %s", mgos_net_ip_to_str(&ip_info.ip, str_ip)));
    if ((ip_info.ip.sin_addr.s_addr & ip_info.netmask.sin_addr.s_addr) ==
        (nc->sa.sin.sin_addr.s_addr & ip_info.netmask.sin_addr.s_addr)) {
      addr = ip_info.ip.sin_addr.s_addr;
    }
  }
#endif
#ifdef MGOS_HAVE_WIFI
  if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_WIFI, MGOS_NET_IF_WIFI_STA,
                           &ip_info) &&
      (addr == 0)) {
    LOG(LL_DEBUG,
        ("WiFi STA address %08x, mask %08x", ip_info.ip.sin_addr.s_addr,
         ip_info.netmask.sin_addr.s_addr));
    LOG(LL_DEBUG, ("ip_info.ip %s", mgos_net_ip_to_str(&ip_info.ip, str_ip)));
    if ((ip_info.ip.sin_addr.s_addr & ip_info.netmask.sin_addr.s_addr) ==
        (nc->sa.sin.sin_addr.s_addr & ip_info.netmask.sin_addr.s_addr)) {
      addr = ip_info.ip.sin_addr.s_addr;
    }
  }
  if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_WIFI, MGOS_NET_IF_WIFI_AP,
                           &ip_info) &&
      (addr == 0)) {
    LOG(LL_DEBUG,
        ("WiFi AP address %08x, mask %08x", ip_info.ip.sin_addr.s_addr,
         ip_info.netmask.sin_addr.s_addr));
    LOG(LL_DEBUG, ("ip_info.ip %s", mgos_net_ip_to_str(&ip_info.ip, str_ip)));
    if ((ip_info.ip.sin_addr.s_addr & ip_info.netmask.sin_addr.s_addr) ==
        (nc->sa.sin.sin_addr.s_addr & ip_info.netmask.sin_addr.s_addr)) {
      addr = ip_info.ip.sin_addr.s_addr;
    }
  }
#endif
  if (addr != 0) {
    struct mg_dns_resource_record rr =
        make_dns_rr(MG_DNS_A_RECORD,
                    (naive_client ? RCLASS_IN_NOFLUSH : RCLASS_IN_FLUSH), ttl);
    mg_dns_encode_record(reply->io, &rr, name.p, name.len, &addr, sizeof(addr));
    LOG(LL_WARN, ("    %d: %.*s A %d %08x", reply->msg->num_answers,
                   (int) name.len, name.p, ttl, (unsigned int) addr));
    reply->msg->num_answers++;
  }
  (void) rdata;
}