diff options
author | cbdev <cb@cbcdn.com> | 2020-04-27 22:50:47 +0200 |
---|---|---|
committer | cbdev <cb@cbcdn.com> | 2020-04-27 22:50:47 +0200 |
commit | 1d8ed32bf769bc99095cd32ec166e681437607f0 (patch) | |
tree | bc94fd3a0245e91c15659916fc1c3591c7fb44b7 /backends/libmmbackend.c | |
parent | d4714dfdd5c6e2d165d1ad9327fdce69a1b2b85b (diff) | |
parent | c0bb55ff08faf2f89af947090d1c9bc412927d9f (diff) | |
download | midimonster-1d8ed32bf769bc99095cd32ec166e681437607f0.tar.gz midimonster-1d8ed32bf769bc99095cd32ec166e681437607f0.tar.bz2 midimonster-1d8ed32bf769bc99095cd32ec166e681437607f0.zip |
Merge branch 'master' into debian/master
Diffstat (limited to 'backends/libmmbackend.c')
-rw-r--r-- | backends/libmmbackend.c | 94 |
1 files changed, 85 insertions, 9 deletions
diff --git a/backends/libmmbackend.c b/backends/libmmbackend.c index b9513ac..bad048c 100644 --- a/backends/libmmbackend.c +++ b/backends/libmmbackend.c @@ -1,6 +1,77 @@ #include "libmmbackend.h" #define LOGPF(format, ...) fprintf(stderr, "libmmbe\t" format "\n", __VA_ARGS__) +#define LOG(message) fprintf(stderr, "libmmbe\t%s\n", (message)) + +int mmbackend_strdup(char** dest, char* src){ + if(*dest){ + free(*dest); + } + + *dest = strdup(src); + + if(!*dest){ + LOG("Failed to allocate memory"); + return 1; + } + return 0; +} + +char* mmbackend_socket_strerror(int err_no){ + #ifdef _WIN32 + static char error[2048] = ""; + ssize_t u; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, WSAGetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), error, sizeof(error), NULL); + //remove trailing newline that for some reason is included in most of these... + for(u = strlen(error) - 1; u > 0; u--){ + if(!isprint(error[u])){ + error[u] = 0; + } + } + return error; + #else + return strerror(err_no); + #endif +} + +const char* mmbackend_sockaddr_ntop(struct sockaddr* peer, char* buffer, size_t length){ + union { + struct sockaddr* in; + struct sockaddr_in* in4; + struct sockaddr_in6* in6; + } addr; + addr.in = peer; + #ifdef _WIN32 + uint8_t* data = NULL; + #endif + + switch(addr.in->sa_family){ + //inet_ntop has become available in the winapi with vista, but eh. + #ifdef _WIN32 + case AF_INET6: + data = addr.in6->sin6_addr.s6_addr; + snprintf(buffer, length, "%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X", + data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7], + data[8], data[9], data[10], data[11], + data[12], data[13], data[14], data[15]); + return buffer; + case AF_INET: + data = (uint8_t*) &(addr.in4->sin_addr.s_addr); + snprintf(buffer, length, "%d.%d.%d.%d", data[0], data[1], data[2], data[3]); + return buffer; + #else + case AF_INET6: + return inet_ntop(addr.in->sa_family, &(addr.in6->sin6_addr), buffer, length); + case AF_INET: + return inet_ntop(addr.in->sa_family, &(addr.in4->sin_addr), buffer, length); + #endif + default: + snprintf(buffer, length, "Socket family not implemented"); + return buffer; + } +} void mmbackend_parse_hostspec(char* spec, char** host, char** port, char** options){ size_t u = 0; @@ -67,7 +138,7 @@ int mmbackend_parse_sockaddr(char* host, char* port, struct sockaddr_storage* ad return 0; } -int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener, uint8_t mcast){ +int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener, uint8_t mcast, uint8_t dualstack){ int fd = -1, status, yes = 1; struct addrinfo hints = { .ai_family = AF_UNSPEC, @@ -91,19 +162,24 @@ int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener, uin //set required socket options yes = 1; - if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(yes)) < 0){ - LOGPF("Failed to enable SO_REUSEADDR on socket: %s", strerror(errno)); + if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*) &yes, sizeof(yes)) < 0){ + LOGPF("Failed to enable SO_REUSEADDR on socket: %s", mmbackend_socket_strerror(errno)); + } + + yes = dualstack ? 0 : 1; + if(addr_it->ai_family == AF_INET6 && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void*) &yes, sizeof(yes)) < 0){ + LOGPF("Failed to %s dualstack operations on socket: %s", dualstack ? "enable" : "disable", mmbackend_socket_strerror(errno)); } if(mcast){ yes = 1; - if(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (void*)&yes, sizeof(yes)) < 0){ - LOGPF("Failed to enable SO_BROADCAST on socket: %s", strerror(errno)); + if(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (void*) &yes, sizeof(yes)) < 0){ + LOGPF("Failed to enable SO_BROADCAST on socket: %s", mmbackend_socket_strerror(errno)); } yes = 0; - if(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void*)&yes, sizeof(yes)) < 0){ - LOGPF("Failed to disable IP_MULTICAST_LOOP on socket: %s", strerror(errno)); + if(setsockopt(fd, addr_it->ai_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6, addr_it->ai_family == AF_INET ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP, (void*) &yes, sizeof(yes)) < 0){ + LOGPF("Failed to disable IP_MULTICAST_LOOP on socket: %s", mmbackend_socket_strerror(errno)); } } @@ -141,7 +217,7 @@ int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener, uin #else int flags = fcntl(fd, F_GETFL, 0); if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0){ - LOGPF("Failed to set socket nonblocking: %s", strerror(errno)); + LOGPF("Failed to set socket nonblocking: %s", mmbackend_socket_strerror(errno)); close(fd); return -1; } @@ -159,7 +235,7 @@ int mmbackend_send(int fd, uint8_t* data, size_t length){ sent = send(fd, data + total, 1, 0); #endif if(sent < 0){ - LOGPF("Failed to send: %s", strerror(errno)); + LOGPF("Failed to send: %s", mmbackend_socket_strerror(errno)); return 1; } total += sent; |