Sun Oct 12 13:48:26 2014 UTC ()
Add the simple unconnected tests too.


(christos)
diff -r1.1 -r1.2 src/tests/net/mcast/t_mcast.c

cvs diff -r1.1 -r1.2 src/tests/net/mcast/Attic/t_mcast.c (expand / switch to unified diff)

--- src/tests/net/mcast/Attic/t_mcast.c 2014/10/11 23:04:42 1.1
+++ src/tests/net/mcast/Attic/t_mcast.c 2014/10/12 13:48:25 1.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: t_mcast.c,v 1.1 2014/10/11 23:04:42 christos Exp $ */ 1/* $NetBSD: t_mcast.c,v 1.2 2014/10/12 13:48:25 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2014 The NetBSD Foundation, Inc. 4 * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas. 8 * by Christos Zoulas.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -19,42 +19,43 @@ @@ -19,42 +19,43 @@
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__RCSID("$NetBSD: t_mcast.c,v 1.1 2014/10/11 23:04:42 christos Exp $"); 32__RCSID("$NetBSD: t_mcast.c,v 1.2 2014/10/12 13:48:25 christos Exp $");
33 33
34#include <sys/types.h> 34#include <sys/types.h>
35#include <sys/socket.h> 35#include <sys/socket.h>
36#include <netinet/in.h> 36#include <netinet/in.h>
37 37
38#include <assert.h> 38#include <assert.h>
39#include <netdb.h> 39#include <netdb.h>
40#include <time.h> 40#include <time.h>
41#include <stdio.h> 41#include <stdio.h>
42#include <string.h> 42#include <string.h>
43#include <stdlib.h> 43#include <stdlib.h>
44#include <unistd.h> 44#include <unistd.h>
45#include <err.h> 45#include <err.h>
46#include <errno.h> 46#include <errno.h>
47#include <poll.h> 47#include <poll.h>
 48#include <stdbool.h>
48 49
49#ifndef TEST 50#ifndef TEST
50#include <atf-c.h> 51#include <atf-c.h>
51 52
52#define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__) 53#define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__)
53 54
54#define SKIPX(ev, msg, ...) do { \ 55#define SKIPX(ev, msg, ...) do { \
55 atf_tc_skip(msg, __VA_ARGS__); \ 56 atf_tc_skip(msg, __VA_ARGS__); \
56 return; \ 57 return; \
57} while(/*CONSTCOND*/0) 58} while(/*CONSTCOND*/0)
58 59
59#else 60#else
60#define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) 61#define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__)
@@ -115,26 +116,35 @@ allowv4mapped(int s, struct addrinfo *ai @@ -115,26 +116,35 @@ allowv4mapped(int s, struct addrinfo *ai
115 struct sockaddr_in6 *s6; 116 struct sockaddr_in6 *s6;
116 int zero = 0; 117 int zero = 0;
117 118
118 if (ai->ai_family != AF_INET6) 119 if (ai->ai_family != AF_INET6)
119 return 0; 120 return 0;
120 121
121 s6 = (void *)ai->ai_addr; 122 s6 = (void *)ai->ai_addr;
122 123
123 if (!IN6_IS_ADDR_V4MAPPED(&s6->sin6_addr)) 124 if (!IN6_IS_ADDR_V4MAPPED(&s6->sin6_addr))
124 return 0; 125 return 0;
125 return setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)); 126 return setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero));
126} 127}
127 128
 129static struct sockaddr_storage ss;
 130static int
 131connector(int fd, const struct sockaddr *sa, socklen_t slen)
 132{
 133 assert(sizeof(ss) > slen);
 134 memcpy(&ss, sa, slen);
 135 return 0;
 136}
 137
128static int 138static int
129getsocket(const char *host, const char *port, 139getsocket(const char *host, const char *port,
130 int (*f)(int, const struct sockaddr *, socklen_t)) 140 int (*f)(int, const struct sockaddr *, socklen_t))
131{ 141{
132 int e, s; 142 int e, s;
133 struct addrinfo hints, *ai0, *ai; 143 struct addrinfo hints, *ai0, *ai;
134 const char *cause = "?"; 144 const char *cause = "?";
135 145
136 memset(&hints, 0, sizeof(hints)); 146 memset(&hints, 0, sizeof(hints));
137 hints.ai_family = AF_UNSPEC; 147 hints.ai_family = AF_UNSPEC;
138 hints.ai_socktype = SOCK_DGRAM; 148 hints.ai_socktype = SOCK_DGRAM;
139 e = getaddrinfo(host, port, &hints, &ai0); 149 e = getaddrinfo(host, port, &hints, &ai0);
140 if (e) 150 if (e)
@@ -146,174 +156,219 @@ getsocket(const char *host, const char * @@ -146,174 +156,219 @@ getsocket(const char *host, const char *
146 s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); 156 s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
147 if (s == -1) { 157 if (s == -1) {
148 cause = "socket"; 158 cause = "socket";
149 continue; 159 continue;
150 } 160 }
151 if (allowv4mapped(s, ai) == -1) { 161 if (allowv4mapped(s, ai) == -1) {
152 cause = "allow v4 mapped"; 162 cause = "allow v4 mapped";
153 goto out; 163 goto out;
154 } 164 }
155 if ((*f)(s, ai->ai_addr, ai->ai_addrlen) == -1) { 165 if ((*f)(s, ai->ai_addr, ai->ai_addrlen) == -1) {
156 cause = f == bind ? "bind" : "connect"; 166 cause = f == bind ? "bind" : "connect";
157 goto out; 167 goto out;
158 } 168 }
159 if (f == bind && addmc(s, ai) == -1) { 169 if ((f == bind || f == connector) && addmc(s, ai) == -1) {
160 cause = "join group"; 170 cause = "join group";
161 goto out; 171 goto out;
162 } 172 }
163 break; 173 break;
164out: 174out:
165 close(s); 175 close(s);
166 s = -1; 176 s = -1;
167 continue; 177 continue;
168 } 178 }
169 freeaddrinfo(ai0); 179 freeaddrinfo(ai0);
170 if (s == -1) 180 if (s == -1)
171 ERRX(1, "%s (%s)", cause, strerror(errno)); 181 ERRX(1, "%s (%s)", cause, strerror(errno));
172 return s; 182 return s;
173} 183}
174 184
175static void 185static void
176sender(const char *host, const char *port, size_t n) 186sender(const char *host, const char *port, size_t n, bool conn)
177{ 187{
178 int s; 188 int s;
179 ssize_t l; 189 ssize_t l;
180 size_t seq; 190 size_t seq;
181 char buf[64]; 191 char buf[64];
182 192
183 s = getsocket(host, port, connect); 193 s = getsocket(host, port, conn ? connect : connector);
184 for (seq = 0; seq < n; seq++) { 194 for (seq = 0; seq < n; seq++) {
185 time_t t = time(&t); 195 time_t t = time(&t);
186 snprintf(buf, sizeof(buf), "%zu: %-24.24s", seq, ctime(&t)); 196 snprintf(buf, sizeof(buf), "%zu: %-24.24s", seq, ctime(&t));
187 if (debug) 197 if (debug)
188 printf("sending: %s\n", buf); 198 printf("sending: %s\n", buf);
189 l = send(s, buf, sizeof(buf), 0); 199 l = conn ? send(s, buf, sizeof(buf), 0) :
 200 sendto(s, buf, sizeof(buf), 0, (void *)&ss, ss.ss_len);
190 if (l == -1) 201 if (l == -1)
191 ERRX(EXIT_FAILURE, "send (%s)", strerror(errno)); 202 ERRX(EXIT_FAILURE, "send (%s)", strerror(errno));
192 usleep(100); 203 usleep(100);
193 } 204 }
194} 205}
195 206
196static void 207static void
197receiver(const char *host, const char *port, size_t n) 208receiver(const char *host, const char *port, size_t n, bool conn)
198{ 209{
199 int s; 210 int s;
200 ssize_t l; 211 ssize_t l;
201 size_t seq; 212 size_t seq;
202 char buf[64]; 213 char buf[64];
203 struct pollfd pfd; 214 struct pollfd pfd;
 215 socklen_t slen;
204 216
205 s = getsocket(host, port, bind); 217 s = getsocket(host, port, conn ? bind : connector);
206 pfd.fd = s; 218 pfd.fd = s;
207 pfd.events = POLLIN; 219 pfd.events = POLLIN;
208 for (seq = 0; seq < n; seq++) { 220 for (seq = 0; seq < n; seq++) {
209 if (poll(&pfd, 1, 1000) == -1) 221 if (poll(&pfd, 1, 1000) == -1)
210 ERRX(EXIT_FAILURE, "poll (%s)", strerror(errno)); 222 ERRX(EXIT_FAILURE, "poll (%s)", strerror(errno));
211 l = recv(s, buf, sizeof(buf), 0); 223 slen = ss.ss_len;
 224 l = conn ? recv(s, buf, sizeof(buf), 0) :
 225 recvfrom(s, buf, sizeof(buf), 0, (void *)&ss, &slen);
212 if (l == -1) 226 if (l == -1)
213 ERRX(EXIT_FAILURE, "recv (%s)", strerror(errno)); 227 ERRX(EXIT_FAILURE, "recv (%s)", strerror(errno));
214 if (debug) 228 if (debug)
215 printf("got: %s\n", buf); 229 printf("got: %s\n", buf);
216 } 230 }
217} 231}
218 232
219static void 233static void
220run(const char *host, const char *port, size_t n) 234run(const char *host, const char *port, size_t n, bool conn)
221{ 235{
222 switch (fork()) { 236 switch (fork()) {
223 case 0: 237 case 0:
224 receiver(host, port, n); 238 receiver(host, port, n, conn);
225 return; 239 return;
226 case -1: 240 case -1:
227 ERRX(EXIT_FAILURE, "fork (%s)", strerror(errno)); 241 ERRX(EXIT_FAILURE, "fork (%s)", strerror(errno));
228 default: 242 default:
229 usleep(100); 243 usleep(100);
230 sender(host, port, n); 244 sender(host, port, n, conn);
231 return; 245 return;
232 } 246 }
233} 247}
234 248
235#ifdef TEST 249#ifdef TEST
236int 250int
237main(int argc, char *argv[]) 251main(int argc, char *argv[])
238{ 252{
239 const char *host, *port; 253 const char *host, *port;
240 int c; 254 int c;
241 size_t n; 255 size_t n;
 256 bool conn;
242 257
243 host = HOST_V4; 258 host = HOST_V4;
244 port = PORT_V4; 259 port = PORT_V4;
245 n = TOTAL; 260 n = TOTAL;
 261 conn = false;
246 262
247 while ((c = getopt(argc, argv, "46dmn:")) != -1) 263 while ((c = getopt(argc, argv, "46cdmn:")) != -1)
248 switch (c) { 264 switch (c) {
249 case '4': 265 case '4':
250 host = HOST_V4; 266 host = HOST_V4;
251 port = PORT_V4; 267 port = PORT_V4;
252 break; 268 break;
253 case '6': 269 case '6':
254 host = HOST_V6; 270 host = HOST_V6;
255 port = PORT_V6; 271 port = PORT_V6;
256 break; 272 break;
 273 case 'c':
 274 conn = true;
 275 break;
257 case 'd': 276 case 'd':
258 debug++; 277 debug++;
259 break; 278 break;
260 case 'm': 279 case 'm':
261 host = HOST_V4MAPPED; 280 host = HOST_V4MAPPED;
262 port = PORT_V4MAPPED; 281 port = PORT_V4MAPPED;
263 break; 282 break;
264 case 'n': 283 case 'n':
265 n = atoi(optarg); 284 n = atoi(optarg);
266 break; 285 break;
267 default: 286 default:
268 fprintf(stderr, "Usage: %s [-dm46] [-n <tot>]", 287 fprintf(stderr, "Usage: %s [-cdm46] [-n <tot>]",
269 getprogname()); 288 getprogname());
270 return 1; 289 return 1;
271 } 290 }
272 291
273 run(host, port, n); 292 run(host, port, n, conn);
274 return 0; 293 return 0;
275} 294}
276#else 295#else
277 296
278ATF_TC(inet4); 297ATF_TC(conninet4);
279ATF_TC_HEAD(inet4, tc) 298ATF_TC_HEAD(conninet4, tc)
 299{
 300 atf_tc_set_md_var(tc, "descr", "Checks connected multicast for ipv4");
 301}
 302
 303ATF_TC_BODY(conninet4, tc)
 304{
 305 run(HOST_V4, PORT_V4, TOTAL, true);
 306}
 307
 308ATF_TC(connmappedinet4);
 309ATF_TC_HEAD(connmappedinet4, tc)
 310{
 311 atf_tc_set_md_var(tc, "descr", "Checks connected multicast for mapped ipv4");
 312}
 313
 314ATF_TC_BODY(connmappedinet4, tc)
 315{
 316 run(HOST_V4MAPPED, PORT_V4MAPPED, TOTAL, true);
 317}
 318
 319ATF_TC(conninet6);
 320ATF_TC_HEAD(conninet6, tc)
 321{
 322 atf_tc_set_md_var(tc, "descr", "Checks connected multicast for ipv6");
 323}
 324
 325ATF_TC_BODY(conninet6, tc)
 326{
 327 run(HOST_V6, PORT_V6, TOTAL, true);
 328}
 329
 330ATF_TC(unconninet4);
 331ATF_TC_HEAD(unconninet4, tc)
280{ 332{
281 atf_tc_set_md_var(tc, "descr", "Checks multicast for ipv4"); 333 atf_tc_set_md_var(tc, "descr", "Checks unconnected multicast for ipv4");
282} 334}
283 335
284ATF_TC_BODY(inet4, tc) 336ATF_TC_BODY(unconninet4, tc)
285{ 337{
286 run(HOST_V4, PORT_V4, TOTAL); 338 run(HOST_V4, PORT_V4, TOTAL, false);
287} 339}
288 340
289ATF_TC(mappedinet4); 341ATF_TC(unconnmappedinet4);
290ATF_TC_HEAD(mappedinet4, tc) 342ATF_TC_HEAD(unconnmappedinet4, tc)
291{ 343{
292 atf_tc_set_md_var(tc, "descr", "Checks multicast for mapped ipv4"); 344 atf_tc_set_md_var(tc, "descr", "Checks unconnected multicast for mapped ipv4");
293} 345}
294 346
295ATF_TC_BODY(mappedinet4, tc) 347ATF_TC_BODY(unconnmappedinet4, tc)
296{ 348{
297 run(HOST_V4MAPPED, PORT_V4MAPPED, TOTAL); 349 run(HOST_V4MAPPED, PORT_V4MAPPED, TOTAL, false);
298} 350}
299 351
300ATF_TC(inet6); 352ATF_TC(unconninet6);
301ATF_TC_HEAD(inet6, tc) 353ATF_TC_HEAD(unconninet6, tc)
302{ 354{
303 atf_tc_set_md_var(tc, "descr", "Checks multicast for ipv6"); 355 atf_tc_set_md_var(tc, "descr", "Checks unconnected multicast for ipv6");
304} 356}
305 357
306ATF_TC_BODY(inet6, tc) 358ATF_TC_BODY(unconninet6, tc)
307{ 359{
308 run(HOST_V6, PORT_V6, TOTAL); 360 run(HOST_V6, PORT_V6, TOTAL, false);
309} 361}
310 362
311ATF_TP_ADD_TCS(tp) 363ATF_TP_ADD_TCS(tp)
312{ 364{
313 ATF_TP_ADD_TC(tp, inet4); 365 ATF_TP_ADD_TC(tp, conninet4);
314 ATF_TP_ADD_TC(tp, mappedinet4); 366 ATF_TP_ADD_TC(tp, connmappedinet4);
315 ATF_TP_ADD_TC(tp, inet6); 367 ATF_TP_ADD_TC(tp, conninet6);
 368 ATF_TP_ADD_TC(tp, unconninet4);
 369 ATF_TP_ADD_TC(tp, unconnmappedinet4);
 370 ATF_TP_ADD_TC(tp, unconninet6);
316 371
317 return atf_no_error(); 372 return atf_no_error();
318} 373}
319#endif 374#endif