mdnssvc
mdnssvc copied to clipboard
airplay service cannot be discovered
I use this library to register the airplay service, but it cannot be discovered using a Mac computer. Are there any restrictions?
I found that a crash occurs when adding a txt record
Can you share your code?
I just do some update in climdnssvc.c,this is my code: `int main(int argc, char argv[]) { // const char* txt = NULL; struct in_addr host; char hostname[256],* arg, * identity = NULL, * type = NULL, * addr = NULL; int port = 0; bool verbose = false;
// if (argc <= 2) {
// print_usage();
// exit(0);
// }
#ifdef _WIN32 winsock_init(); #endif
signal(SIGINT, sighandler);
signal(SIGTERM, sighandler);
#if defined(SIGPIPE) signal(SIGPIPE, SIG_IGN); #endif #if defined(SIGQUIT) signal(SIGQUIT, sighandler); #endif #if defined(SIGHUP) signal(SIGHUP, sighandler); #endif
// while ((arg = *++argv) != NULL) {
// if (!strcasecmp(arg, "-o") || !strcasecmp(arg, "host")) {
// addr = *++argv;
// argc -= 2;
// } else if (!strcasecmp(arg, "-p")) {
// port = atoi(*++argv);
// } else if (!strcasecmp(arg, "-v")) {
// verbose = true;
// } else if (!strcasecmp(arg, "-t")) {
// (void)! asprintf(&type, "%s.local", *++argv);
// } else if (!strcasecmp(arg, "-i")) {
// identity = *++argv;
// } else {
// // nothing let's try to be smart and handle legacy crap
// if (!identity) identity = *argv;
// else if (!type) (void) !asprintf(&type, "%s.local", *argv);
// else if (!port) port = atoi(*argv);
// else {
// txt = (const char**) malloc((argc + 1) * sizeof(char**));
// memcpy(txt, argv, argc * sizeof(char**));
// txt[argc] = NULL;
// break;
// }
// argc--;
// }
// }
char* identity_raop="cc3d825f7ed1@mdnslib";
char* type_raop="_raop._tcp.local";
short port_raop=6012;
const char* txt_raop[]= {NULL, "tp=UDP", "sm=false", "sv=false", "ek=1",
"et=0,1", "md=0,1,2", "cn=0,1", "ch=2",
"ss=16", "sr=44100", "vn=3", "txtvers=1",
NULL
};
gethostname(hostname, sizeof(hostname));
strcat(hostname, ".local");
host = get_interface(addr);
svr = mdnsd_start(host, verbose);
if (svr) {
printf("host: %s\nidentity: %s\ntype: %s\nip: %s\nport: %u\n", hostname, identity, type, inet_ntoa(host), port);
mdnsd_set_hostname(svr, hostname, host);
svc_raop = mdnsd_register_svc(svr, identity_raop, type_raop, port_raop, NULL, txt_raop);
// mdns_service_destroy(svc);
#ifdef _WIN32 Sleep(INFINITE); #else pause(); #endif mdns_service_remove(svr, svc_raop); mdnsd_stop(svr); } else { printf("Can't start server"); print_usage(); }
free(type);
if (txt_raop) free(txt_raop);
#ifdef _WIN32 winsock_close(); #endif
return 0;
} `
I found it could not create a TXT record in mdnsd_register_svc,it may not enter this branch.
when I use it with removing the first NULL element in txt, it can enter the branch,but a segfault occurred during runtime. const char* txt_raop[]= { "tp=UDP", "sm=false", "sv=false", "ek=1", "et=0,1", "md=0,1,2", "cn=0,1", "ch=2", "ss=16", "sr=44100", "vn=3", "txtvers=1" };
I think you misunderstood the syntax of TXT. It's an array of pointers and a NULL indicates the last item. If you put NULL first, nothing will be taken into account. If you forget the NULL at the end, the parser will runaway everywhere and crash
But it also crashed if I only placed NULL at the end.
You either don't set a TXT at all (the txt parameter in the function call is NULL) or it includes at least one element and then finishes by NULL. You can't obviously send an array with just NULL inside, you send a NULL array instead.
yes,I just update with this,it also crash. const char* txt_raop[]= {"tp=UDP", "sm=false", "sv=false", "ek=1", "et=0,1", "md=0,1,2", "cn=0,1", "ch=2", "ss=16", "sr=44100", "vn=3", "txtvers=1", NULL }; if I don't set TXT record,the service may not discover.Can you give me some example?
You can look at my AirConnect project and see how I'm using it
I look the libraop project in AirConnect,it show txt code like this:https://github.com/philippe44/libraop/blob/master/src/raop_server.c
I think it register service without txt record.
No, I do use services w/ TXT, it would not work otherwise, AirPlay would not work. What you probably missed is that the leading NULL is replaced a few lines below by a dynamically generated string.
// set model
(void)!asprintf(&(txt[0]), "am=%s", model);