aboutsummaryrefslogtreecommitdiffhomepage
path: root/backends/rtpmidi.c
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2020-04-23 23:38:36 +0200
committercbdev <cb@cbcdn.com>2020-04-23 23:38:36 +0200
commita8be76f20b3eaa20b53e1cda7686845a08cef32b (patch)
treeba2b3680d9d01730ef2cd4e07f58b6c3f052417e /backends/rtpmidi.c
parentbc275e10defe27e6d288ccf9125fe9b915168240 (diff)
downloadmidimonster-a8be76f20b3eaa20b53e1cda7686845a08cef32b.tar.gz
midimonster-a8be76f20b3eaa20b53e1cda7686845a08cef32b.tar.bz2
midimonster-a8be76f20b3eaa20b53e1cda7686845a08cef32b.zip
Split mDNS socket into v4/v6
Diffstat (limited to 'backends/rtpmidi.c')
-rw-r--r--backends/rtpmidi.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/backends/rtpmidi.c b/backends/rtpmidi.c
index 7df8563..eb08e8d 100644
--- a/backends/rtpmidi.c
+++ b/backends/rtpmidi.c
@@ -1,5 +1,5 @@
#define BACKEND_NAME "rtpmidi"
-//#define DEBUG
+#define DEBUG
#include <string.h>
#include <errno.h>
@@ -25,7 +25,6 @@
//TODO for some reason, the announce packet generates an exception in the wireshark dns dissector
//TODO rename and document most functions
//TODO timeout non-responsive peers (connected = 0) to allow discovery to reconnect them
-//TODO ipv6-mapped-ipv4 creates problems when connecting on a ipv4-bound instance
/*
* CAVEAT EMPTOR: This is one of the largest backends yet, due to the
@@ -42,7 +41,10 @@
*/
static struct /*_rtpmidi_global*/ {
+ //mdns is split into v6 and v4 to avoid having to translate ipv6-mapped-ipv4 source addresses
int mdns_fd;
+ int mdns4_fd;
+
char* mdns_name;
char* mdns_interface;
@@ -56,6 +58,7 @@ static struct /*_rtpmidi_global*/ {
rtpmidi_invite* invite;
} cfg = {
.mdns_fd = -1,
+ .mdns4_fd = -1,
.mdns_name = NULL,
.mdns_interface = NULL,
@@ -370,7 +373,7 @@ static int rtpmidi_bind_instance(instance* inst, rtpmidi_instance_data* data, ch
char control_port[32];
//bind to random port if none supplied
- data->fd = mmbackend_socket(host, port ? port : "0", SOCK_DGRAM, 1, 0);
+ data->fd = mmbackend_socket(host, port ? port : "0", SOCK_DGRAM, 1, 0, 1);
if(data->fd < 0){
return 1;
}
@@ -384,7 +387,7 @@ static int rtpmidi_bind_instance(instance* inst, rtpmidi_instance_data* data, ch
if(data->mode == apple){
data->control_port = be16toh(((struct sockaddr_in*) &sock_addr)->sin_port) - 1;
snprintf(control_port, sizeof(control_port), "%d", data->control_port);
- data->control_fd = mmbackend_socket(host, control_port, SOCK_DGRAM, 1, 0);
+ data->control_fd = mmbackend_socket(host, control_port, SOCK_DGRAM, 1, 0, 1);
if(data->control_fd < 0){
LOGPF("Failed to bind control port %s for instance %s", control_port, inst->name);
return 1;
@@ -1135,9 +1138,8 @@ static int rtpmidi_mdns_broadcast(uint8_t* frame, size_t len){
};
//send to ipv4 and ipv6 mcasts
- //FIXME much as it pains me, this should probably be split into two descriptors, one for ipv4 and one for ipv6
sendto(cfg.mdns_fd, frame, len, 0, (struct sockaddr*) &mcast6, sizeof(mcast6));
- sendto(cfg.mdns_fd, frame, len, 0, (struct sockaddr*) &mcast, sizeof(mcast));
+ sendto(cfg.mdns4_fd, frame, len, 0, (struct sockaddr*) &mcast, sizeof(mcast));
return 0;
}
@@ -1329,7 +1331,7 @@ static int rtpmidi_service(){
if(data->mode == apple){
//mdns discovery
- if(cfg.mdns_fd >= 0
+ if((cfg.mdns_fd >= 0 || cfg.mdns4_fd >= 0)
&& (!data->last_announce || mm_timestamp() - data->last_announce > RTPMIDI_ANNOUNCE_INTERVAL)){
rtpmidi_mdns_announce(inst[u]);
}
@@ -1513,7 +1515,7 @@ static int rtpmidi_parse_announce(uint8_t* buffer, size_t length, dns_header* hd
return 0;
}
-static int rtpmidi_handle_mdns(){
+static int rtpmidi_handle_mdns(int fd){
uint8_t buffer[RTPMIDI_PACKET_BUFFER];
dns_header* hdr = (dns_header*) buffer;
dns_name name = {
@@ -1523,9 +1525,9 @@ static int rtpmidi_handle_mdns(){
struct sockaddr_storage peer_addr;
socklen_t peer_len = sizeof(peer_addr);
- for(bytes = recvfrom(cfg.mdns_fd, buffer, sizeof(buffer), 0, (struct sockaddr*) &peer_addr, &peer_len);
+ for(bytes = recvfrom(fd, buffer, sizeof(buffer), 0, (struct sockaddr*) &peer_addr, &peer_len);
bytes > 0;
- bytes = recvfrom(cfg.mdns_fd, buffer, sizeof(buffer), 0, (struct sockaddr*) &peer_addr, &peer_len)){
+ bytes = recvfrom(fd, buffer, sizeof(buffer), 0, (struct sockaddr*) &peer_addr, &peer_len)){
if(bytes < sizeof(dns_header)){
continue;
}
@@ -1540,7 +1542,10 @@ static int rtpmidi_handle_mdns(){
//rfc6762 18.3: opcode != 0 -> ignore
//rfc6762 18.11: response code != 0 -> ignore
- DBGPF("%" PRIsize_t " bytes, ID %d, Opcode %d, %s, %d questions, %d answers, %d servers, %d additional", bytes, hdr->id, DNS_OPCODE(hdr->flags[0]), DNS_RESPONSE(hdr->flags[0]) ? "response" : "query", hdr->questions, hdr->answers, hdr->servers, hdr->additional);
+ DBGPF("%" PRIsize_t " bytes on v%c, ID %d, Opcode %d, %s, %d questions, %d answers, %d servers, %d additional",
+ bytes, (fd == cfg.mdns_fd ? '6' : '4'), hdr->id,
+ DNS_OPCODE(hdr->flags[0]), DNS_RESPONSE(hdr->flags[0]) ? "response" : "query",
+ hdr->questions, hdr->answers, hdr->servers, hdr->additional);
rtpmidi_parse_announce(buffer, bytes, hdr, &name, &host, (struct sockaddr*) &peer_addr, peer_len);
peer_len = sizeof(peer_addr);
@@ -1578,7 +1583,7 @@ static int rtpmidi_handle(size_t num, managed_fd* fds){
for(u = 0; u < num; u++){
if(!fds[u].impl){
//handle mDNS discovery input
- rtpmidi_handle_mdns();
+ rtpmidi_handle_mdns(fds[u].fd);
}
else{
//handle rtp/control input
@@ -1619,24 +1624,25 @@ static int rtpmidi_start_mdns(){
}
//FIXME might try passing NULL as host here to work around possible windows ipv6 handicaps
- cfg.mdns_fd = mmbackend_socket(RTPMIDI_DEFAULT_HOST, RTPMIDI_MDNS_PORT, SOCK_DGRAM, 1, 1);
- if(cfg.mdns_fd < 0){
- LOG("Failed to create requested mDNS descriptor");
+ cfg.mdns_fd = mmbackend_socket(RTPMIDI_DEFAULT_HOST, RTPMIDI_MDNS_PORT, SOCK_DGRAM, 1, 1, 0);
+ cfg.mdns4_fd = mmbackend_socket(RTPMIDI_DEFAULT4_HOST, RTPMIDI_MDNS_PORT, SOCK_DGRAM, 1, 1, 0);
+ if(cfg.mdns_fd < 0 && cfg.mdns4_fd < 0){
+ LOG("Failed to create requested mDNS descriptors");
return 1;
}
//join ipv4 multicast group
- if(setsockopt(cfg.mdns_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (uint8_t*) &mcast_req, sizeof(mcast_req))){
+ if(cfg.mdns4_fd >= 0 && setsockopt(cfg.mdns4_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (uint8_t*) &mcast_req, sizeof(mcast_req))){
LOGPF("Failed to join IPv4 multicast group for mDNS, discovery may be impaired: %s", mmbackend_socket_strerror(errno));
}
//join ipv6 multicast group
- if(setsockopt(cfg.mdns_fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (uint8_t*) &mcast6_req, sizeof(mcast6_req))){
+ if(cfg.mdns_fd >= 0 && setsockopt(cfg.mdns_fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (uint8_t*) &mcast6_req, sizeof(mcast6_req))){
LOGPF("Failed to join IPv6 multicast group for mDNS, discovery may be impaired: %s", mmbackend_socket_strerror(errno));
}
//register mdns fd to core
- return mm_manage_fd(cfg.mdns_fd, BACKEND_NAME, 1, NULL);
+ return mm_manage_fd(cfg.mdns_fd, BACKEND_NAME, 1, NULL) | mm_manage_fd(cfg.mdns4_fd, BACKEND_NAME, 1, NULL);
}
static int rtpmidi_start(size_t n, instance** inst){
@@ -1686,7 +1692,7 @@ static int rtpmidi_start(size_t n, instance** inst){
LOG("Failed to set up mDNS discovery, instances may not show up on remote hosts and may not find remote peers");
}
else if(mdns_requested){
- fds++;
+ fds += 2;
}
LOGPF("Registered %" PRIsize_t " descriptors to core", fds);
@@ -1700,7 +1706,7 @@ static int rtpmidi_shutdown(size_t n, instance** inst){
for(u = 0; u < n; u++){
data = (rtpmidi_instance_data*) inst[u]->impl;
- if(cfg.mdns_fd >= 0 && data->mode == apple){
+ if((cfg.mdns_fd >= 0 || cfg.mdns4_fd >= 0) && data->mode == apple){
rtpmidi_mdns_detach(inst[u]);
}
@@ -1743,6 +1749,9 @@ static int rtpmidi_shutdown(size_t n, instance** inst){
if(cfg.mdns_fd >= 0){
close(cfg.mdns_fd);
}
+ if(cfg.mdns4_fd >= 0){
+ close(cfg.mdns4_fd);
+ }
LOG("Backend shut down");
return 0;