Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix colliding POST_PACKED_STRUCTURE definition #7

Closed
wants to merge 2 commits into from

Conversation

adiknoth
Copy link
Member

@adiknoth adiknoth commented Mar 8, 2012

9f6c65c has introduced a regression,
effectively breaking jackd on Linux.

The culprit were colliding definitions of POST_PACKED_STRUCTURE.

This commit changes the missing bits, though the code still violates the
DRY principle.

adiknoth added 2 commits March 8, 2012 20:19
9f6c65c has introduced a regression,
effectively breaking jackd on Linux.

The culprit were colliding definitions of POST_PACKED_STRUCTURE.

This commit changes the missing bits, though the code still violates the
DRY principle.
When jack_connect is called without any argument, it causes a segfault
in

                snprintf( portA, sizeof(portA), "%s", argv[argc-1] );
                snprintf( portB, sizeof(portB), "%s", argv[argc-2] );

Reported in http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=662199
@sletz
Copy link
Member

sletz commented Mar 8, 2012

This JACK_32_64 issue needs a bit more of work. I will probably just remove it from all targets and just compile with JACK_32_64 always on.

@adiknoth
Copy link
Member Author

adiknoth commented Mar 9, 2012

Fixed in 5869625

@adiknoth adiknoth closed this Mar 9, 2012
shaun-tierney pushed a commit to shaun-tierney/jack2 that referenced this pull request Dec 14, 2015
7890 added a commit that referenced this pull request Feb 8, 2019
Branch netjack_squashed_interface_selection_plus_ipv6

Original PR:
#27
by rufferson, first comment Mar 3, 2013

Commits on Mar 12, 2017

    Add interface selection for NetJack components

@rufferson
rufferson committed on Mar 3, 2013

 * Multicast interface selection to UnixSocket - added methods
   Bind and JoinMCastGroup with <char *if_name> argument
 * Interface handling to NetInterface class tree - new field and
   its initialization/usage in Slave branch.
 * Multicast interface selection to NetSlaves (Adapter/Driver)
   and NetMaster, where master can now listen all interfaces.

Commits on Mar 15, 2017

    Add IPv6 support to UnixSocket and NetInterfaces

@rufferson
rufferson committed on Feb 21, 2013

 * Cleaned up direct references to sockaddr_in
 * Changed fRecvAddr & fSendAddr to sockaddr_storage
 * Added field fFamily indicating current probed AF.
 * Added protected method ProbeAF accepting IP to probe
   and addr to fill in. As well as final call to test
   which should be either connect or bind.
 * Reworked protocol specific methods to act on fFamily
 * IsLocal now checks assigned interface addresses
 * Introduced internal state tracker to avoid double bind
 * Workaround for GLIBC bug returning wrong order of AFs
   http://sourceware.org/bugzilla/show_bug.cgi?id=14967
 * Corrected interface selection for Slaves - only one
   interface could be used to multicast the packet
 * Retab changes

This branch has conflicts that must be resolved
to resolve conflicts before continuing.
Conflicting files
common/JackNetDriver.h
posix/JackNetUnixSocket.cpp

wget https://github.com/jackaudio/jack2/pull/27.diff

$ patch -p 1 < 27.diff
patching file common/JackNetAdapter.cpp
patching file common/JackNetDriver.cpp
patching file common/JackNetDriver.h
Hunk #1 FAILED at 79.
1 out of 1 hunk FAILED -- saving rejects to file common/JackNetDriver.h.rej
patching file common/JackNetInterface.cpp
patching file common/JackNetInterface.h
patching file common/JackNetManager.cpp
patching file common/JackNetManager.h
patching file common/JackNetTool.h
patching file posix/JackNetUnixSocket.cpp
Hunk #4 FAILED at 229.
Hunk #5 succeeded at 281 (offset -8 lines).
Hunk #6 succeeded at 303 (offset -8 lines).
Hunk #7 succeeded at 325 (offset -8 lines).
Hunk #8 succeeded at 363 (offset -8 lines).
Hunk #9 succeeded at 486 (offset -8 lines).
Hunk #10 succeeded at 508 (offset -8 lines).
Hunk #11 succeeded at 537 (offset -8 lines).
Hunk #12 succeeded at 586 (offset -8 lines).
Hunk #13 succeeded at 607 (offset -8 lines).
Hunk #14 succeeded at 615 (offset -8 lines).
Hunk #15 succeeded at 644 (offset -8 lines).
Hunk #16 succeeded at 673 (offset -8 lines).
1 out of 16 hunks FAILED -- saving rejects to file posix/JackNetUnixSocket.cpp.rej

 find|grep rej
./posix/JackNetUnixSocket.cpp.rej
./common/JackNetDriver.h.rej

--- posix/JackNetUnixSocket.cpp
+++ posix/JackNetUnixSocket.cpp
@@ -229,58 +311,117 @@
     {
         if (strcmp(ip, "127.0.0.1") == 0) {
             return true;
-        }
+        } else if(!strcmp(ip,"::1"))
+            return true;

-        char host_name[32];
-        gethostname(host_name, sizeof(host_name));
+        struct ifaddrs *ifas, *ifa;
+        socklen_t len;

-        struct hostent* host = gethostbyname(host_name);
-        if (host) {
-            for (int i = 0; host->h_addr_list[i] != 0; ++i) {
-                struct in_addr addr;
-                memcpy(&addr, host->h_addr_list[i], sizeof(struct in_addr));
-                if (strcmp(inet_ntoa(addr), ip) == 0) {
-                    return true;
-                }
-            }
-            return false;
-        } else {
-            return false;
+        if (getifaddrs(&ifas) == -1) {
+                jack_error("JackNetUnixSocket::IsLocal error in getifaddrs");
+                return false;
         }
+        for (ifa = ifas; ifa != NULL; ifa = ifa->ifa_next) {
+                if (ifa->ifa_addr == NULL)
+                    continue; // Address is mandatory
+                len = (ifa->ifa_addr->sa_family==AF_INET)?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6);
+                if(!getnameinfo(ifa->ifa_addr, len, f_addr_buff, INET6_ADDRSTRLEN, NULL,0, NI_NUMERICSERV | NI_DGRAM | NI_NUMERICHOST))
+                    if(!strcmp(f_addr_buff,ip))
+                        break;
+        }
+        freeifaddrs(ifas);
+        return (ifa != NULL);
     }

     int JackNetUnixSocket::Bind()
     {
-        return bind(fSockfd, reinterpret_cast<socket_address_t*>(&fRecvAddr), sizeof(socket_address_t));
+        int yes=1;
+        if(fState & JNS_BOUND) return 0;
+        // Multicast is incompatible with V4MAPPED or V4COMPAT addresses, if probe detected MC we need V6ONLY
+        if(fFamily == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED(&_sock6(fRecvAddr).sin6_addr) && fState & JNS_MCAST)
+            if(SetOption(IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes))) return SOCKET_ERROR;
+        if(bind(fSockfd, reinterpret_cast<struct sockaddr*>(&fRecvAddr), sizeof(fRecvAddr))) return SOCKET_ERROR;
+        fState |= JNS_BOUND;
+        return 0;
+    }
+    int JackNetUnixSocket::Bind(const char *if_name)
+    {
+        int ret = Bind();
+        if(!ret && strcmp(if_name,"any")) {
+            if(fFamily == AF_INET) {
+                // 'all' for this case will lead to 'last valid interface', which is not that one might expect
+                if(strcmp(if_name,"all"))
+                    ret = BindMCastIface(if_name, IP_MULTICAST_IF, &_sock4(fSendAddr).sin_addr);
+                else
+                    jack_error("Multicast Interface all not found, sending from default");
+            } else if(fFamily == AF_INET6) {
+                struct if_nameindex *if_ni = if_nameindex(); // In V6 world we do everything differently.
+                if(if_ni) {
+                    int i;
+                    for (i=0; if_ni[i].if_index > 0; i++) {
+                        if(if_ni[i].if_index == 1)
+                            continue; // Skip loopback
+                        if(!strcmp(if_ni[i].if_name,if_name)) {
+                            ret = SetOption(IPPROTO_IPV6, IPV6_MULTICAST_IF, &if_ni[i].if_index, sizeof(if_ni[i].if_index));
+                            jack_log("JackNetUnixSocket::Bind Multicasting from %s",if_ni[i].if_name);
+                            break;
+                        }
+                    }
+                    if(if_ni[i].if_index == 0) jack_error("Multicast Interface %s not found, sending from default",if_name);
+                    if_freenameindex(if_ni);
+                }
+            }
+        }
+        return ret;
     }

     int JackNetUnixSocket::BindWith(const char* ip)
     {
-        int addr_conv = inet_aton(ip, &fRecvAddr.sin_addr);
-        if (addr_conv < 0) {
-            return addr_conv;
+        if(fFamily == AF_UNSPEC) {
+            if(!fPort) return SOCKET_ERROR;
+            if(ProbeAF(ip,&fRecvAddr,&bind)<0) return SOCKET_ERROR;
+            fState |= JNS_BOUND;
+            return 0;
+        } else {
+            if(SetRecvIP(ip)==-1) return SOCKET_ERROR;
+            return Bind();
         }
-        return Bind();
     }

     int JackNetUnixSocket::BindWith(int port)
     {
-        fRecvAddr.sin_port = htons(port);
-        return Bind();
+        if(fFamily == AF_UNSPEC) {
+            fPort = port;
+            if(ProbeAF(NULL,&fRecvAddr,&bind)<0) return SOCKET_ERROR;
+            fState |= JNS_BOUND;
+            return 0;
+        } else {
+            SetPort(port);
+            return Bind();
+        }
     }

     int JackNetUnixSocket::Connect()
     {
-        return connect(fSockfd, reinterpret_cast<socket_address_t*>(&fSendAddr), sizeof(socket_address_t));
+        if(fFamily != AF_UNSPEC)
+            return connect(fSockfd, (struct sockaddr*)&fSendAddr,sizeof(fSendAddr));
+        jack_error("JackNetUnixSocket::Connect Family not initialized");
+        return SOCKET_ERROR;
     }

     int JackNetUnixSocket::ConnectTo(const char* ip)
     {
-        int addr_conv = inet_aton(ip, &fSendAddr.sin_addr);
-        if (addr_conv < 0) {
-            return addr_conv;
+        socklen_t l=sizeof(fRecvAddr);
+        if(fPort==0) return SOCKET_ERROR;
+        if(fState & JNS_PROBED) {
+            Reset();
+            fFamily=AF_UNSPEC;
         }
-        return Connect();
+        if(fSockfd)
+            Close();
+        if(ProbeAF(ip,&fSendAddr,&connect)<0) return SOCKET_ERROR;
+        fState |= JNS_CONNCD;
+        return getsockname(fSockfd, (struct sockaddr *)&fRecvAddr, &l);
     }

     void JackNetUnixSocket::Close()

--- common/JackNetDriver.h
+++ common/JackNetDriver.h
@@ -79,7 +79,7 @@
         public:

             JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table,
-                        const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports,
+                        const char* ip, int port, const char* mcif, int mtu, int midi_input_ports, int midi_output_ports,
                         char* net_name, uint transport_sync, int network_latency, int celt_encoding,
                         int opus_encoding, bool auto_save);
             virtual ~JackNetDriver();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants