File: 0018-rtl_tcp-Add-IPv6-support.patch

package info (click to toggle)
rtl-sdr 0.6.0-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,660 kB
  • sloc: ansic: 9,305; python: 102; sh: 86; makefile: 74; xml: 57
file content (147 lines) | stat: -rw-r--r-- 4,681 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
From 8985b45e1fe1a5d50c5e1dc4c7c306705e602445 Mon Sep 17 00:00:00 2001
From: "A. Maitland Bottoms" <bottoms@debian.org>
Date: Sun, 3 Sep 2017 16:22:55 -0400
Subject: [PATCH 18/33] 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.
---
 src/rtl_tcp.c | 72 +++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 55 insertions(+), 17 deletions(-)

diff --git a/src/rtl_tcp.c b/src/rtl_tcp.c
index da6057b..42b90cb 100644
--- a/src/rtl_tcp.c
+++ b/src/rtl_tcp.c
@@ -30,6 +30,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/time.h>
+#include <netdb.h>
 #include <netinet/in.h>
 #include <fcntl.h>
 #else
@@ -371,10 +372,18 @@ static void *command_worker(void *arg)
 int main(int argc, char **argv)
 {
 	int r, opt, i;
-	char* addr = "127.0.0.1";
-	int port = 1234;
+	char *addr = "127.0.0.1";
+	char *port = "1234";
 	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;
 	int dev_index = 0;
 	int dev_given = 0;
@@ -413,10 +422,10 @@ int main(int argc, char **argv)
 			samp_rate = (uint32_t)atofs(optarg);
 			break;
 		case 'a':
-			addr = optarg;
+		        addr = strdup(optarg);
 			break;
 		case 'p':
-			port = atoi(optarg);
+		        port = strdup(optarg);
 			break;
 		case 'b':
 			buf_num = atoi(optarg);
@@ -515,16 +524,42 @@ int main(int argc, char **argv)
 	pthread_cond_init(&cond, NULL);
 	pthread_cond_init(&exit_cond, NULL);
 
-	memset(&local,0,sizeof(local));
-	local.sin_family = AF_INET;
-	local.sin_port = htons(port);
-	local.sin_addr.s_addr = inet_addr(addr);
+	hints.ai_flags  = AI_PASSIVE; /* Server mode. */
+	hints.ai_family = PF_UNSPEC;  /* IPv4 or IPv6. */
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_protocol = IPPROTO_TCP;
+
+	if ((aiErr = getaddrinfo(addr,
+				 port,
+				 &hints,
+				 &aiHead )) != 0)
+	{
+		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));
 
-	listensocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-	r = 1;
-	setsockopt(listensocket, SOL_SOCKET, SO_REUSEADDR, (char *)&r, sizeof(int));
-	setsockopt(listensocket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling));
-	bind(listensocket,(struct sockaddr *)&local,sizeof(local));
+		if (bind(listensocket, (struct sockaddr *)&local, sizeof(local)))
+			fprintf(stderr, "rtl_tcp bind error: %s", strerror(errno));
+		else
+			break;
+	}
 
 #ifdef _WIN32
 	ioctlsocket(listensocket, FIONBIO, &blockmode);
@@ -535,11 +570,11 @@ int main(int argc, char **argv)
 
 	while(1) {
 		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"
 		       "to receive samples in GRC and control "
 		       "rtl_tcp parameters (frequency, gain, ...).\n",
-		       addr, port);
+		       hostinfo, portinfo);
 		listen(listensocket,1);
 
 		while(1) {
@@ -559,7 +594,10 @@ int main(int argc, char **argv)
 
 		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));
 		memcpy(&dongle_info.magic, "RTL0", 4);
-- 
2.30.2