From 6dd311a1a81a0f1c89521f332f3b1a04b6a752b1 Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Sat, 27 Jan 2024 08:27:46 +0100 Subject: [PATCH] Connect to NQPTP control socket on localhost nqptp.c listens on "localhost", but shairport-sync connectes to the wildcard address 0/0. This apparently works on Linux and FreeBSD, but OpenBSD fails: ``` $ ktrace shairport-sync -v -u [...] 0.000038288 "ptp-utilities.c:243" *fatal error: error sending timing_peer_list to NQPTP 0.000021868 "shairport.c:1728" emergency exit $ kdump [...] 2319 shairport-sync STRU struct sockaddr { AF_INET, 0.0.0.0:9000 } 2319 shairport-sync RET sendto -1 errno 51 Network is unreachable [...] ``` Resolve and connect to "localhost" just like NQPTP does, resulting in 127.0.0.1 or ::1 as socket addresses. This is required to run when configured `--with-airplay-2`. Tested on OpenBSD/amd64 7.4-current with shairport-sync 2.4.3 and nqptp 1.2.5-dev cfa8315 (plus OpenBSD fixes). I expect Linux and FreeBSD to work as before, but have not tested it. --- ptp-utilities.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/ptp-utilities.c b/ptp-utilities.c index 958f65420..e575996fc 100644 --- a/ptp-utilities.c +++ b/ptp-utilities.c @@ -35,8 +35,10 @@ #include #ifdef COMPILE_FOR_FREEBSD #include -#include #endif +#include +#include +#include #define __STDC_FORMAT_MACROS #include "common.h" #include "ptp-utilities.h" @@ -222,28 +224,38 @@ void ptp_send_control_message_string(const char *msg) { msg); debug(2, "Send control message to NQPTP: \"%s\"", full_message); int s; - unsigned short port = htons(NQPTP_CONTROL_PORT); - struct sockaddr_in server; + int ret; + struct addrinfo hints, *info; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE; + + /* nqptp is only controllable via localhost */ + char portstr[20]; + snprintf(portstr, 20, "%d", NQPTP_CONTROL_PORT); + + ret = getaddrinfo("localhost", portstr, &hints, &info); + if (ret) { + die("getaddrinfo: %s", gai_strerror(ret)); + } /* Create a datagram socket in the internet domain and use the * default protocol (UDP). */ - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + if ((s = socket(info->ai_family, info->ai_socktype, 0)) < 0) { die("Can't open a socket to NQPTP"); } - /* Set up the server name */ - server.sin_family = AF_INET; /* Internet Domain */ - server.sin_port = port; /* Server Port */ - server.sin_addr.s_addr = 0; /* Server's Address */ - /* Send the message in buf to the server */ - if (sendto(s, full_message, full_message_size, 0, (struct sockaddr *)&server, sizeof(server)) < + if (sendto(s, full_message, full_message_size, 0, info->ai_addr, info->ai_addrlen) < 0) { die("error sending timing_peer_list to NQPTP"); } /* Deallocate the socket */ close(s); + freeaddrinfo(info); /* deallocate the message string */ free(full_message);