Browse Source

Change to default to ipv4 resolved addresses if possible

Some OSC stuff (plogue bidule?) doesn't seem to support ipv6, so that's
probably not a good thing to have automatically chosen if the user
doesn't specify an address or specifies one that resolves to ipv6.
master
cancel 6 years ago
parent
commit
da25c46d3c
  1. 64
      osc_out.c
  2. 2
      tui_main.c

64
osc_out.c

@ -1,5 +1,6 @@
#include "osc_out.h"
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
@ -8,7 +9,10 @@
struct Oosc_dev {
int fd;
struct addrinfo* addr;
// Just keep the whole list around, since juggling the strict-aliasing
// problems with sockaddr_storage is not worth it.
struct addrinfo* chosen;
struct addrinfo* head;
};
Oosc_udp_create_error oosc_dev_create_udp(Oosc_dev** out_ptr,
@ -20,34 +24,76 @@ Oosc_udp_create_error oosc_dev_create_udp(Oosc_dev** out_ptr,
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = 0;
hints.ai_flags = AI_ADDRCONFIG;
struct addrinfo* addr = NULL;
int err = getaddrinfo(dest_addr, dest_port, &hints, &addr);
struct addrinfo* chosen = NULL;
struct addrinfo* head = NULL;
int err = getaddrinfo(dest_addr, dest_port, &hints, &head);
if (err != 0) {
fprintf(stderr, "Failed to get address info, error: %d\n", errno);
return Oosc_udp_create_error_getaddrinfo_failed;
}
int udpfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
// Special behavior: if no hostname was provided, we'll get loopback(s) from
// getaddrinfo. Which is good. But on systems with both an ipv4 and ipv6
// address, we might get the ipv6 address listed first. And the OSC server,
// for example Plogue Bidule, might not support ipv6. And defaulting to the
// ipv6 loopback wouldn't work, in that case. So if there's no hostname, and
// we find an ipv4 address in the results, prefer to use that.
//
// Actually let's just prefer ipv4 completely for now
#if 0
if (!dest_addr) {
#endif
{
for (struct addrinfo* a = head; a; a = a->ai_next) {
if (a->ai_family != AF_INET)
continue;
chosen = a;
break;
}
}
if (!chosen)
chosen = head;
#if 0
for (struct addrinfo* a = head; a; a = a->ai_next) {
char buff[INET6_ADDRSTRLEN];
char const* str = NULL;
if (a->ai_family == AF_INET) {
str = inet_ntop(AF_INET, &((struct sockaddr_in*)a->ai_addr)->sin_addr,
buff, sizeof(buff));
} else if (a->ai_family == AF_INET6) {
str = inet_ntop(AF_INET6, &((struct sockaddr_in6*)a->ai_addr)->sin6_addr,
buff, sizeof(buff));
}
if (str) {
fprintf(stderr, "ntop name: %s\n", str);
} else {
fprintf(stderr, "inet_ntop error\n");
}
}
#endif
int udpfd =
socket(chosen->ai_family, chosen->ai_socktype, chosen->ai_protocol);
if (udpfd < 0) {
fprintf(stderr, "Failed to open UDP socket, error number: %d\n", errno);
freeaddrinfo(addr);
freeaddrinfo(head);
return Oosc_udp_create_error_couldnt_open_socket;
}
Oosc_dev* dev = malloc(sizeof(Oosc_dev));
dev->fd = udpfd;
dev->addr = addr;
dev->chosen = chosen;
dev->head = head;
*out_ptr = dev;
return Oosc_udp_create_error_ok;
}
void oosc_dev_destroy(Oosc_dev* dev) {
close(dev->fd);
freeaddrinfo(dev->addr);
freeaddrinfo(dev->head);
free(dev);
}
static void oosc_send_datagram(Oosc_dev* dev, char const* data, Usz size) {
ssize_t res =
sendto(dev->fd, data, size, 0, dev->addr->ai_addr, dev->addr->ai_addrlen);
ssize_t res = sendto(dev->fd, data, size, 0, dev->chosen->ai_addr,
dev->chosen->ai_addrlen);
if (res < 0) {
fprintf(stderr, "UDP message send failed\n");
exit(1);

2
tui_main.c

@ -27,7 +27,7 @@ static void usage() {
"OSC/MIDI options:\n"
" --osc-server <hotname>\n"
" Hostname or IP address to send OSC messages to.\n"
" Default: localhost\n"
" Default: loopback (localhost or equivalent)\n"
"\n"
" --osc-port <number or service name>\n"
" UDP port (or service name) to send OSC messages to.\n"

Loading…
Cancel
Save