static int mdns_tinysvcmdns_register(char *apname, int port) { struct ifaddrs *ifalist; struct ifaddrs *ifa; svr = mdnsd_start(); if (svr == NULL) { warn("tinysvcmdns: mdnsd_start() failed"); return -1; } // Thanks to Paul Lietar for this // room for name + .local + NULL char hostname[100 + 6]; gethostname(hostname, 99); // according to POSIX, this may be truncated without a final NULL ! hostname[99] = 0; // will not work if the hostname doesn't end in .local char *hostend = hostname + strlen(hostname); if ((strlen(hostname) < strlen(".local")) || (strcmp(hostend - 6, ".local") != 0)) { strcat(hostname, ".local"); } if (getifaddrs(&ifalist) < 0) { warn("tinysvcmdns: getifaddrs() failed"); return -1; } ifa = ifalist; // Look for an ipv4/ipv6 non-loopback interface to use as the main one. for (ifa = ifalist; ifa != NULL; ifa = ifa->ifa_next) { if (!(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) { uint32_t main_ip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; mdnsd_set_hostname(svr, hostname, main_ip); // TTL should be 120 seconds break; } else if (!(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET6) { struct in6_addr *addr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; mdnsd_set_hostname_v6(svr, hostname, addr); // TTL should be 120 seconds break; } } if (ifa == NULL) { warn("tinysvcmdns: no non-loopback ipv4 or ipv6 interface found"); return -1; } // Skip the first one, it was already added by set_hostname for (ifa = ifa->ifa_next; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_flags & IFF_LOOPBACK) // Skip loop-back interfaces continue; switch (ifa->ifa_addr->sa_family) { case AF_INET: { // ipv4 uint32_t ip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; struct rr_entry *a_e = rr_create_a(create_nlabel(hostname), ip); // TTL should be 120 seconds mdnsd_add_rr(svr, a_e); } break; case AF_INET6: { // ipv6 struct in6_addr *addr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; struct rr_entry *aaaa_e = rr_create_aaaa(create_nlabel(hostname), addr); // TTL should be 120 seconds mdnsd_add_rr(svr, aaaa_e); } break; } } freeifaddrs(ifa); char *txtwithoutmetadata[] = {MDNS_RECORD_WITHOUT_METADATA, NULL}; #ifdef CONFIG_METADATA char *txtwithmetadata[] = {MDNS_RECORD_WITH_METADATA, NULL}; #endif char **txt; #ifdef CONFIG_METADATA if (config.metadata_enabled) txt = txtwithmetadata; else #endif txt = txtwithoutmetadata; struct mdns_service *svc = mdnsd_register_svc(svr, apname, "_raop._tcp.local", port, NULL, (const char **)txt); // TTL should be 75 minutes, i.e. 4500 seconds mdns_service_destroy(svc); return 0; }
static int mdns_tinysvcmdns_register(char *apname, int port) { struct ifaddrs *ifalist; struct ifaddrs *ifa; svr = mdnsd_start(); if (svr == NULL) { warn("tinysvcmdns: mdnsd_start() failed"); return -1; } // room for name + .local + NULL char hostname[100 + 6]; gethostname(hostname, 99); // according to POSIX, this may be truncated without a final NULL ! hostname[99] = 0; // will not work on iOS if the hostname doesn't end in .local strcat(hostname, ".local"); if (getifaddrs(&ifalist) < 0) { warn("tinysvcmdns: getifaddrs() failed"); return -1; } ifa = ifalist; // Look for an ipv4/ipv6 non-loopback interface to use as the main one. for (ifa = ifalist; ifa != NULL; ifa = ifa->ifa_next) { if (!(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) { uint32_t main_ip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; mdnsd_set_hostname(svr, hostname, main_ip); break; } else if (!(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET6) { struct in6_addr *addr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; mdnsd_set_hostname_v6(svr, hostname, addr); break; } } if (ifa == NULL) { warn("tinysvcmdns: no non-loopback ipv4 or ipv6 interface found"); return -1; } // Skip the first one, it was already added by set_hostname for (ifa = ifa->ifa_next; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_flags & IFF_LOOPBACK) // Skip loop-back interfaces continue; switch (ifa->ifa_addr->sa_family) { case AF_INET: { // ipv4 uint32_t ip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; struct rr_entry *a_e = rr_create_a(create_nlabel(hostname), ip); mdnsd_add_rr(svr, a_e); } break; case AF_INET6: { // ipv6 struct in6_addr *addr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; struct rr_entry *aaaa_e = rr_create_aaaa(create_nlabel(hostname), addr); mdnsd_add_rr(svr, aaaa_e); } break; } } freeifaddrs(ifa); const char *txt[] = { MDNS_RECORD, NULL }; struct mdns_service *svc = mdnsd_register_svc(svr, apname, "_raop._tcp.local", port, NULL, txt); mdns_service_destroy(svc); return 0; }