1
1
#define BACKEND_NAME "rtpmidi"
2
- #define DEBUG
2
+ // #define DEBUG
3
3
4
4
#include <string.h>
5
5
#include <errno.h>
15
15
#include <iphlpapi.h>
16
16
#else
17
17
#include <arpa/inet.h>
18
+ #include <net/if.h>
18
19
#include <sys/types.h>
19
20
#include <ifaddrs.h>
20
21
#endif
@@ -47,6 +48,10 @@ static struct /*_rtpmidi_global*/ {
47
48
48
49
char * mdns_name ;
49
50
char * mdns_interface ;
51
+ #ifdef _WIN32
52
+ unsigned mdns_adapter ;
53
+ unsigned mdns6_adapter ;
54
+ #endif
50
55
51
56
uint8_t detect ;
52
57
uint64_t last_service ;
@@ -283,6 +288,13 @@ static int rtpmidi_announce_addrs(){
283
288
continue ;
284
289
}
285
290
291
+ //for exact matches, use exactly this interface for multicasts
292
+ if (!strcmp (iface , cfg .mdns_interface )){
293
+ LOGPF ("Using interface %s for mDNS discovery" , iface );
294
+ cfg .mdns_adapter = iter -> IfIndex ;
295
+ cfg .mdns6_adapter = iter -> Ipv6IfIndex ;
296
+ }
297
+
286
298
for (unicast_addr = (IP_ADAPTER_UNICAST_ADDRESS_LH * ) iter -> FirstUnicastAddress ; unicast_addr ; unicast_addr = unicast_addr -> Next ){
287
299
addr .in = unicast_addr -> Address .lpSockaddr ;
288
300
#else
@@ -1437,7 +1449,7 @@ static int rtpmidi_apple_peermatch(uint8_t* session_raw, struct sockaddr* peer,
1437
1449
for (n = 0 ; n < cfg .invite [u ].invites ; n ++ ){
1438
1450
if (!strcmp (cfg .invite [u ].name [n ], "*" )){
1439
1451
done = 1 ;
1440
- DBGPF ("Peer %.* s implicitly invited on instance %s, converting to explicit invitation" , session_name [ 0 ], session_name + 1 , cfg .invite [u ].inst -> name );
1452
+ DBGPF ("Peer %s implicitly invited on instance %s, converting to explicit invitation" , session_name , cfg .invite [u ].inst -> name );
1441
1453
if (rtpmidi_push_invite (cfg .invite [u ].inst , session_name )){
1442
1454
return 1 ;
1443
1455
}
@@ -1524,6 +1536,9 @@ static int rtpmidi_handle_mdns(int fd){
1524
1536
ssize_t bytes = 0 ;
1525
1537
struct sockaddr_storage peer_addr ;
1526
1538
socklen_t peer_len = sizeof (peer_addr );
1539
+ #ifdef DEBUG
1540
+ char peer_name [INET6_ADDRSTRLEN + 1 ];
1541
+ #endif
1527
1542
1528
1543
for (bytes = recvfrom (fd , buffer , sizeof (buffer ), 0 , (struct sockaddr * ) & peer_addr , & peer_len );
1529
1544
bytes > 0 ;
@@ -1542,10 +1557,11 @@ static int rtpmidi_handle_mdns(int fd){
1542
1557
//rfc6762 18.3: opcode != 0 -> ignore
1543
1558
//rfc6762 18.11: response code != 0 -> ignore
1544
1559
1545
- DBGPF ("%" PRIsize_t " bytes on v%c, ID %d, Opcode %d, %s, %d questions, %d answers, %d servers, %d additional" ,
1560
+ DBGPF ("%" PRIsize_t " bytes on v%c, ID %d, Opcode %d, %s, %d questions, %d answers, %d servers, %d additional, src %s " ,
1546
1561
bytes , (fd == cfg .mdns_fd ? '6' : '4' ), hdr -> id ,
1547
1562
DNS_OPCODE (hdr -> flags [0 ]), DNS_RESPONSE (hdr -> flags [0 ]) ? "response" : "query" ,
1548
- hdr -> questions , hdr -> answers , hdr -> servers , hdr -> additional );
1563
+ hdr -> questions , hdr -> answers , hdr -> servers , hdr -> additional ,
1564
+ mmbackend_sockaddr_ntop ((struct sockaddr * ) & peer_addr , peer_name , sizeof (peer_name )));
1549
1565
rtpmidi_parse_announce (buffer , bytes , hdr , & name , & host , (struct sockaddr * ) & peer_addr , peer_len );
1550
1566
1551
1567
peer_len = sizeof (peer_addr );
@@ -1605,9 +1621,15 @@ static int rtpmidi_handle(size_t num, managed_fd* fds){
1605
1621
}
1606
1622
1607
1623
static int rtpmidi_start_mdns (){
1624
+ //use ip_mreqn where possible, but that renames the interface member
1625
+ #ifdef _WIN32
1608
1626
struct ip_mreq mcast_req = {
1609
- .imr_multiaddr .s_addr = htobe32 (((uint32_t ) 0xe00000fb )),
1610
- .imr_interface .s_addr = INADDR_ANY
1627
+ .imr_interface .s_addr = INADDR_ANY ,
1628
+ #else
1629
+ struct ip_mreqn mcast_req = {
1630
+ .imr_address .s_addr = INADDR_ANY ,
1631
+ #endif
1632
+ .imr_multiaddr .s_addr = htobe32 (((uint32_t ) 0xe00000fb ))
1611
1633
};
1612
1634
1613
1635
struct ipv6_mreq mcast6_req = {
@@ -1623,6 +1645,16 @@ static int rtpmidi_start_mdns(){
1623
1645
return 0 ;
1624
1646
}
1625
1647
1648
+ if (cfg .mdns_interface ){
1649
+ #ifdef _WIN32
1650
+ mcast6_req .ipv6mr_interface = cfg .mdns6_adapter ;
1651
+ mcast_req .imr_interface .s_addr = htobe32 (cfg .mdns_adapter );
1652
+ #else
1653
+ mcast6_req .ipv6mr_interface = if_nametoindex (cfg .mdns_interface );
1654
+ mcast_req .imr_ifindex = if_nametoindex (cfg .mdns_interface );
1655
+ #endif
1656
+ }
1657
+
1626
1658
//FIXME might try passing NULL as host here to work around possible windows ipv6 handicaps
1627
1659
cfg .mdns_fd = mmbackend_socket (RTPMIDI_DEFAULT_HOST , RTPMIDI_MDNS_PORT , SOCK_DGRAM , 1 , 1 , 0 );
1628
1660
cfg .mdns4_fd = mmbackend_socket (RTPMIDI_DEFAULT4_HOST , RTPMIDI_MDNS_PORT , SOCK_DGRAM , 1 , 1 , 0 );
0 commit comments