Path: blob/main/tools/regression/sockets/unix_sendtorace/unix_sendtorace.c
48254 views
/*-1* Copyright (c) 2006 Robert N. M. Watson2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*/2526/*27* Attempts to exercise UNIX domain socket races relating to the non-atomic28* connect-and-send properties of sendto(). As the result of such a race is29* a kernel panic, this test simply completes or doesn't.30*31* XXX: Despite implementing support for sendto() on stream sockets with32* implied connect, the appropriate flag isn't set in the FreeBSD kernel so33* it does not work. For now, don't call the stream test.34*/3536#include <sys/types.h>37#include <sys/socket.h>38#include <sys/un.h>3940#include <err.h>41#include <signal.h>42#include <string.h>43#include <unistd.h>4445#define ITERATIONS 10000004647static char socket_path[] = "tmp.XXXXXX";4849static void50stream_server(int listenfd)51{52int acceptfd;5354while (1) {55acceptfd = accept(listenfd, NULL, NULL);56if (acceptfd < 0) {57warn("stream_server: accept");58continue;59}60sleep(1);61close(acceptfd);62}63}6465static void66stream_client(void)67{68struct sockaddr_un sun;69ssize_t len;70char c = 0;71int fd, i;7273bzero(&sun, sizeof(sun));74sun.sun_len = sizeof(sun);75sun.sun_family = AF_UNIX;76strcpy(sun.sun_path, socket_path);77for (i = 0; i < ITERATIONS; i++) {78fd = socket(PF_UNIX, SOCK_STREAM, 0);79if (fd < 0) {80warn("stream_client: socket");81return;82}83len = sendto(fd, &c, sizeof(c), 0, (struct sockaddr *)&sun,84sizeof(sun));85if (len < 0)86warn("stream_client: sendto");87close(fd);88}89}9091static void92stream_test(void)93{94struct sockaddr_un sun;95pid_t childpid;96int listenfd;9798listenfd = socket(PF_UNIX, SOCK_STREAM, 0);99if (listenfd < 0)100err(-1, "stream_test: socket");101102bzero(&sun, sizeof(sun));103sun.sun_len = sizeof(sun);104sun.sun_family = AF_UNIX;105strcpy(sun.sun_path, socket_path);106107if (bind(listenfd, (struct sockaddr *)&sun, sizeof(sun)) < 0)108err(-1, "stream_test: bind");109110if (listen(listenfd, -1) < 0)111err(-1, "stream_test: listen");112113childpid = fork();114if (childpid < 0)115err(-1, "stream_test: fork");116117if (childpid != 0) {118sleep(1);119stream_client();120kill(childpid, SIGTERM);121sleep(1);122} else123stream_server(listenfd);124125(void)unlink(socket_path);126}127128static void129datagram_server(int serverfd)130{131ssize_t len;132char c;133134while (1) {135len = recv(serverfd, &c, sizeof(c), 0);136if (len < 0)137warn("datagram_server: recv");138}139}140141static void142datagram_client(void)143{144struct sockaddr_un sun;145ssize_t len;146char c = 0;147int fd, i;148149bzero(&sun, sizeof(sun));150sun.sun_len = sizeof(sun);151sun.sun_family = AF_UNIX;152strcpy(sun.sun_path, socket_path);153for (i = 0; i < ITERATIONS; i++) {154fd = socket(PF_UNIX, SOCK_DGRAM, 0);155if (fd < 0) {156warn("datagram_client: socket");157return;158}159len = sendto(fd, &c, sizeof(c), 0, (struct sockaddr *)&sun,160sizeof(sun));161if (len < 0)162warn("datagram_client: sendto");163close(fd);164}165}166167static void168datagram_test(void)169{170struct sockaddr_un sun;171pid_t childpid;172int serverfd;173174serverfd = socket(PF_UNIX, SOCK_DGRAM, 0);175if (serverfd < 0)176err(-1, "datagram_test: socket");177178bzero(&sun, sizeof(sun));179sun.sun_len = sizeof(sun);180sun.sun_family = AF_UNIX;181strcpy(sun.sun_path, socket_path);182183if (bind(serverfd, (struct sockaddr *)&sun, sizeof(sun)) < 0)184err(-1, "datagram_test: bind");185186childpid = fork();187if (childpid < 0)188err(-1, "datagram_test: fork");189190if (childpid != 0) {191sleep(1);192datagram_client();193kill(childpid, SIGTERM);194sleep(1);195} else196datagram_server(serverfd);197198(void)unlink(socket_path);199}200201int202main(void)203{204205if (mkstemp(socket_path) == -1)206err(1, "mkstemp failed");207(void)unlink(socket_path);208datagram_test();209if (0)210stream_test();211return (0);212}213214215