rafael2k / darkice

DarkIce is a live audio streamer. It records audio from an audio interface (e.g. sound card), encodes it and sends it to a streaming server. This is the official development repository of Darkice.
http://www.darkice.org
200 stars 47 forks source link

Cannot connect to IPv6 icecast server #166

Closed nivex closed 2 years ago

nivex commented 3 years ago

When specifying a hostname in my darkice.cfg that only has an AAAA record:

DarkIce: TcpSocket.cpp:226: gethostbyname error [6]

When I look at the noted line, I see it is in the #else clause of a #ifdef HAVE_ADDRINFO. There is no HAVE_ADDRINFO flag that I can find. It looks like HAVE_GETADDRINFO was meant. Unfortunately my attempts at fixing things up still don't get a clean compile:

diff -ur darkice-1.4/src/TcpSocket.cpp darkice-1.4-fix/src/TcpSocket.cpp
--- darkice-1.4/src/TcpSocket.cpp   2020-01-03 12:43:21.000000000 -0500
+++ darkice-1.4-fix/src/TcpSocket.cpp   2021-01-08 23:22:48.478494354 -0500
@@ -194,8 +194,8 @@
 {
     int                     optval;
     socklen_t               optlen;
-#ifdef HAVE_ADDRINFO
-    struct addrinfo         hints
+#ifdef HAVE_GETADDRINFO
+    struct addrinfo         hints;
     struct addrinfo       * ptr;
     struct sockaddr_storage addr;
     char                    portstr[6];
@@ -208,10 +208,10 @@
         return false;
     }

-#ifdef HAVE_ADDRINFO
+#ifdef HAVE_GETADDRINFO
     memset(&hints, 0, sizeof(hints));
     hints.ai_socktype = SOCK_STREAM;
-    hints.ai_family = AF_ANY;
+    hints.ai_family = AF_UNSPEC;
     snprintf(portstr, sizeof(portstr), "%d", port);

     if (getaddrinfo(host , portstr, &hints, &ptr)) {

There's a lot of noise about C++11 deprecations, but I believe this is the relevant error:

TcpSocket.cpp: In member function ‘virtual bool TcpSocket::open()’:
TcpSocket.cpp:221:14: error: cannot convert ‘sockaddr_storage’ to ‘void*’
  221 |     memcpy ( addr, ptr->ai_addr, ptr->ai_addrlen);
      |              ^~~~
      |              |
      |              sockaddr_storage
In file included from TcpSocket.cpp:37:
/usr/include/string.h:43:39: note:   initializing argument 1 of ‘void* memcpy(void*, const void*, size_t)’
   43 | extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
      |                      ~~~~~~~~~~~~~~~~~^~~~~~

This is about the limits of what I remember from C++ in college. Hopefully someone more knowledgeable can take it from here.

nivex commented 3 years ago

ah, it looks like a missing pointer dereference:

-    memcpy ( addr, ptr->ai_addr, ptr->ai_addrlen);
+    memcpy ( &addr, ptr->ai_addr, ptr->ai_addrlen);

It compiles, but now on run I get:

DarkIce: TcpSocket.cpp:251: connect error [97]

Error 97 is "Address family not supported by protocol". There's a hard coded AF_INET on line 235 that seems to be the culprit.