rtl_tcp: Add IPv6 support

I've prepared this patch in response to Debian bug #870804
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=870804

It passes the text from the -a and -p options through
getaddrinfo() and uses the first result that has a valid
socket with a successful bind.

While not a complete bind to all possible valid names, it
does appear to address the use case of the bug submitter
without completely changing the program flow.
This commit is contained in:
A. Maitland Bottoms 2017-09-03 16:22:55 -04:00 committed by Steve Markgraf
parent b281473156
commit 8985b45e1f

View File

@ -30,6 +30,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/time.h> #include <sys/time.h>
#include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <fcntl.h> #include <fcntl.h>
#else #else
@ -371,10 +372,18 @@ static void *command_worker(void *arg)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int r, opt, i; int r, opt, i;
char* addr = "127.0.0.1"; char *addr = "127.0.0.1";
int port = 1234; char *port = "1234";
uint32_t frequency = 100000000, samp_rate = 2048000; uint32_t frequency = 100000000, samp_rate = 2048000;
struct sockaddr_in local, remote; struct sockaddr_storage local, remote;
struct addrinfo *ai;
struct addrinfo *aiHead;
struct addrinfo hints;
char hostinfo[NI_MAXHOST];
char portinfo[NI_MAXSERV];
char remhostinfo[NI_MAXHOST];
char remportinfo[NI_MAXSERV];
int aiErr;
uint32_t buf_num = 0; uint32_t buf_num = 0;
int dev_index = 0; int dev_index = 0;
int dev_given = 0; int dev_given = 0;
@ -413,10 +422,10 @@ int main(int argc, char **argv)
samp_rate = (uint32_t)atofs(optarg); samp_rate = (uint32_t)atofs(optarg);
break; break;
case 'a': case 'a':
addr = optarg; addr = strdup(optarg);
break; break;
case 'p': case 'p':
port = atoi(optarg); port = strdup(optarg);
break; break;
case 'b': case 'b':
buf_num = atoi(optarg); buf_num = atoi(optarg);
@ -515,16 +524,42 @@ int main(int argc, char **argv)
pthread_cond_init(&cond, NULL); pthread_cond_init(&cond, NULL);
pthread_cond_init(&exit_cond, NULL); pthread_cond_init(&exit_cond, NULL);
memset(&local,0,sizeof(local)); hints.ai_flags = AI_PASSIVE; /* Server mode. */
local.sin_family = AF_INET; hints.ai_family = PF_UNSPEC; /* IPv4 or IPv6. */
local.sin_port = htons(port); hints.ai_socktype = SOCK_STREAM;
local.sin_addr.s_addr = inet_addr(addr); hints.ai_protocol = IPPROTO_TCP;
listensocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if ((aiErr = getaddrinfo(addr,
r = 1; port,
setsockopt(listensocket, SOL_SOCKET, SO_REUSEADDR, (char *)&r, sizeof(int)); &hints,
setsockopt(listensocket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling)); &aiHead )) != 0)
bind(listensocket,(struct sockaddr *)&local,sizeof(local)); {
fprintf(stderr, "local address %s ERROR - %s.\n",
addr, gai_strerror(aiErr));
return(-1);
}
memcpy(&local, aiHead->ai_addr, aiHead->ai_addrlen);
for (ai = aiHead; ai != NULL; ai = ai->ai_next) {
aiErr = getnameinfo((struct sockaddr *)ai->ai_addr, ai->ai_addrlen,
hostinfo, NI_MAXHOST,
portinfo, NI_MAXSERV, NI_NUMERICSERV | NI_NUMERICHOST);
if (aiErr)
fprintf( stderr, "getnameinfo ERROR - %s.\n",hostinfo);
listensocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (listensocket < 0)
continue;
r = 1;
setsockopt(listensocket, SOL_SOCKET, SO_REUSEADDR, (char *)&r, sizeof(int));
setsockopt(listensocket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling));
if (bind(listensocket, (struct sockaddr *)&local, sizeof(local)))
fprintf(stderr, "rtl_tcp bind error: %s", strerror(errno));
else
break;
}
#ifdef _WIN32 #ifdef _WIN32
ioctlsocket(listensocket, FIONBIO, &blockmode); ioctlsocket(listensocket, FIONBIO, &blockmode);
@ -535,11 +570,11 @@ int main(int argc, char **argv)
while(1) { while(1) {
printf("listening...\n"); printf("listening...\n");
printf("Use the device argument 'rtl_tcp=%s:%d' in OsmoSDR " printf("Use the device argument 'rtl_tcp=%s:%s' in OsmoSDR "
"(gr-osmosdr) source\n" "(gr-osmosdr) source\n"
"to receive samples in GRC and control " "to receive samples in GRC and control "
"rtl_tcp parameters (frequency, gain, ...).\n", "rtl_tcp parameters (frequency, gain, ...).\n",
addr, port); hostinfo, portinfo);
listen(listensocket,1); listen(listensocket,1);
while(1) { while(1) {
@ -559,7 +594,10 @@ int main(int argc, char **argv)
setsockopt(s, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling)); setsockopt(s, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling));
printf("client accepted!\n"); getnameinfo((struct sockaddr *)&remote, rlen,
remhostinfo, NI_MAXHOST,
remportinfo, NI_MAXSERV, NI_NUMERICSERV);
printf("client accepted! %s %s\n", remhostinfo, remportinfo);
memset(&dongle_info, 0, sizeof(dongle_info)); memset(&dongle_info, 0, sizeof(dongle_info));
memcpy(&dongle_info.magic, "RTL0", 4); memcpy(&dongle_info.magic, "RTL0", 4);