]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Connect to NQPTP control socket on localhost 1793/head
authorKlemens Nanni <kn@openbsd.org>
Sat, 27 Jan 2024 07:27:46 +0000 (08:27 +0100)
committerKlemens Nanni <klemens@posteo.de>
Sat, 27 Jan 2024 17:56:26 +0000 (18:56 +0100)
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

index 958f65420ed39ba6576b9cae194452f32190e0dc..e575996fcda3fae8f89aafdeaa5b6a53a9d372ce 100644 (file)
 #include <sys/mman.h>
 #ifdef COMPILE_FOR_FREEBSD
 #include <netinet/in.h>
-#include <sys/socket.h>
 #endif
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netdb.h>
 #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);