Date: Thu, 16 Apr 2015 00:39:21 +0000 (UTC) From: Garrett Cooper <ngie@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r281578 - user/ngie/more-tests/tests/sys/socket Message-ID: <201504160039.t3G0dLBe094839@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ngie Date: Thu Apr 16 00:39:20 2015 New Revision: 281578 URL: https://svnweb.freebsd.org/changeset/base/281578 Log: Rename unix_sendtorace_test to unix_sendto_race_test Added: user/ngie/more-tests/tests/sys/socket/unix_sendto_race_test.c - copied unchanged from r281516, user/ngie/more-tests/tests/sys/socket/unix_sendtorace_test.c Deleted: user/ngie/more-tests/tests/sys/socket/unix_sendtorace_test.c Modified: user/ngie/more-tests/tests/sys/socket/Makefile Modified: user/ngie/more-tests/tests/sys/socket/Makefile ============================================================================== --- user/ngie/more-tests/tests/sys/socket/Makefile Thu Apr 16 00:39:16 2015 (r281577) +++ user/ngie/more-tests/tests/sys/socket/Makefile Thu Apr 16 00:39:20 2015 (r281578) @@ -32,7 +32,7 @@ TAP_TESTS_SH+= unix_cmsg_test # unix_gc: twosome_drop1: sendfd: before 0 after 0 PLAIN_TESTS_C+= unix_gc_test ATF_TESTS_C+= unix_passfd_test -PLAIN_TESTS_C+= unix_sendtorace_test +PLAIN_TESTS_C+= unix_sendto_race_test # unix_socket: socket(PF_LOCAL, SOCK_RAW, 0): Protocol wrong type for socket PLAIN_TESTS_C+= unix_socket_test PLAIN_TESTS_C+= unix_sorflush_test Copied: user/ngie/more-tests/tests/sys/socket/unix_sendto_race_test.c (from r281516, user/ngie/more-tests/tests/sys/socket/unix_sendtorace_test.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/ngie/more-tests/tests/sys/socket/unix_sendto_race_test.c Thu Apr 16 00:39:20 2015 (r281578, copy of r281516, user/ngie/more-tests/tests/sys/socket/unix_sendtorace_test.c) @@ -0,0 +1,215 @@ +/*- + * Copyright (c) 2006 Robert N. M. Watson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * Attempts to exercise UNIX domain socket races relating to the non-atomic + * connect-and-send properties of sendto(). As the result of such a race is + * a kernel panic, this test simply completes or doesn't. + * + * XXX: Despite implementing support for sendto() on stream sockets with + * implied connect, the appropriate flag isn't set in the FreeBSD kernel so + * it does not work. For now, don't call the stream test. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> + +#include <err.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> + +#define ITERATIONS 1000000 + +static char socket_path[] = "tmp.XXXXXX"; + +static void +stream_server(int listenfd) +{ + int acceptfd; + + while (1) { + acceptfd = accept(listenfd, NULL, NULL); + if (acceptfd < 0) { + warn("stream_server: accept"); + continue; + } + sleep(1); + close(acceptfd); + } +} + +static void +stream_client(void) +{ + struct sockaddr_un sun; + ssize_t len; + char c = 0; + int fd, i; + + bzero(&sun, sizeof(sun)); + sun.sun_len = sizeof(sun); + sun.sun_family = AF_UNIX; + strcpy(sun.sun_path, socket_path); + for (i = 0; i < ITERATIONS; i++) { + fd = socket(PF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + warn("stream_client: socket"); + return; + } + len = sendto(fd, &c, sizeof(c), 0, (struct sockaddr *)&sun, + sizeof(sun)); + if (len < 0) + warn("stream_client: sendto"); + close(fd); + } +} + +static void +stream_test(void) +{ + struct sockaddr_un sun; + pid_t childpid; + int listenfd; + + listenfd = socket(PF_UNIX, SOCK_STREAM, 0); + if (listenfd < 0) + err(-1, "stream_test: socket"); + + bzero(&sun, sizeof(sun)); + sun.sun_len = sizeof(sun); + sun.sun_family = AF_UNIX; + strcpy(sun.sun_path, socket_path); + + if (bind(listenfd, (struct sockaddr *)&sun, sizeof(sun)) < 0) + err(-1, "stream_test: bind"); + + if (listen(listenfd, -1) < 0) + err(-1, "stream_test: listen"); + + childpid = fork(); + if (childpid < 0) + err(-1, "stream_test: fork"); + + if (childpid != 0) { + sleep(1); + stream_client(); + kill(childpid, SIGTERM); + sleep(1); + } else + stream_server(listenfd); + + (void)unlink(socket_path); +} + +static void +datagram_server(int serverfd) +{ + ssize_t len; + char c; + + while (1) { + len = recv(serverfd, &c, sizeof(c), 0); + if (len < 0) + warn("datagram_server: recv"); + } +} + +static void +datagram_client(void) +{ + struct sockaddr_un sun; + ssize_t len; + char c = 0; + int fd, i; + + bzero(&sun, sizeof(sun)); + sun.sun_len = sizeof(sun); + sun.sun_family = AF_UNIX; + strcpy(sun.sun_path, socket_path); + for (i = 0; i < ITERATIONS; i++) { + fd = socket(PF_UNIX, SOCK_DGRAM, 0); + if (fd < 0) { + warn("datagram_client: socket"); + return; + } + len = sendto(fd, &c, sizeof(c), 0, (struct sockaddr *)&sun, + sizeof(sun)); + if (len < 0) + warn("datagram_client: sendto"); + close(fd); + } +} + +static void +datagram_test(void) +{ + struct sockaddr_un sun; + pid_t childpid; + int serverfd; + + serverfd = socket(PF_UNIX, SOCK_DGRAM, 0); + if (serverfd < 0) + err(-1, "datagram_test: socket"); + + bzero(&sun, sizeof(sun)); + sun.sun_len = sizeof(sun); + sun.sun_family = AF_UNIX; + strcpy(sun.sun_path, socket_path); + + if (bind(serverfd, (struct sockaddr *)&sun, sizeof(sun)) < 0) + err(-1, "datagram_test: bind"); + + childpid = fork(); + if (childpid < 0) + err(-1, "datagram_test: fork"); + + if (childpid != 0) { + sleep(1); + datagram_client(); + kill(childpid, SIGTERM); + sleep(1); + } else + datagram_server(serverfd); + + (void)unlink(socket_path); +} + +int +main(void) +{ + + if (mkstemp(socket_path) == -1) + err(1, "mkstemp failed"); + (void)unlink(socket_path); + datagram_test(); + if (0) + stream_test(); + return (0); +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504160039.t3G0dLBe094839>