xref: /illumos-gate/usr/src/test/os-tests/tests/sockfs/conn.c (revision f012ee0c3db17469b492c2cf757226f3d7b1ebbc)
1*f012ee0cSGordon Ross /*
2*f012ee0cSGordon Ross  * Copyright 2016 Jeremy Allison
3*f012ee0cSGordon Ross  *
4*f012ee0cSGordon Ross  * Permission is hereby granted, free of charge, to any person obtaining a
5*f012ee0cSGordon Ross  * copy of this software and associated documentation files (the "Software"),
6*f012ee0cSGordon Ross  * to deal in the Software without restriction, including without limitation
7*f012ee0cSGordon Ross  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*f012ee0cSGordon Ross  * and/or sell copies of the Software, and to permit persons to whom the
9*f012ee0cSGordon Ross  * Software is furnished to do so, subject to the following conditions:
10*f012ee0cSGordon Ross  *
11*f012ee0cSGordon Ross  * The above copyright notice and this permission notice shall be included
12*f012ee0cSGordon Ross  * in all copies or substantial portions of the Software.
13*f012ee0cSGordon Ross  *
14*f012ee0cSGordon Ross  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*f012ee0cSGordon Ross  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*f012ee0cSGordon Ross  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17*f012ee0cSGordon Ross  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18*f012ee0cSGordon Ross  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19*f012ee0cSGordon Ross  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20*f012ee0cSGordon Ross  * DEALINGS IN THE SOFTWARE.
21*f012ee0cSGordon Ross  */
22*f012ee0cSGordon Ross 
23*f012ee0cSGordon Ross #include <sys/param.h>
24*f012ee0cSGordon Ross #include <sys/types.h>
25*f012ee0cSGordon Ross #include <sys/stat.h>
26*f012ee0cSGordon Ross #include <sys/socket.h>
27*f012ee0cSGordon Ross #include <sys/un.h>
28*f012ee0cSGordon Ross #include <stdio.h>
29*f012ee0cSGordon Ross #include <unistd.h>
30*f012ee0cSGordon Ross #include <string.h>
31*f012ee0cSGordon Ross #include <errno.h>
32*f012ee0cSGordon Ross #include <stdint.h>
33*f012ee0cSGordon Ross #include <stdlib.h>
34*f012ee0cSGordon Ross #include <pthread.h>
35*f012ee0cSGordon Ross 
36*f012ee0cSGordon Ross extern const char *__progname;
37*f012ee0cSGordon Ross 
38*f012ee0cSGordon Ross static void *
39*f012ee0cSGordon Ross server(void *varg)
40*f012ee0cSGordon Ross {
41*f012ee0cSGordon Ross 	int ret;
42*f012ee0cSGordon Ross 	int sock = (int)varg;
43*f012ee0cSGordon Ross 	unsigned int i;
44*f012ee0cSGordon Ross 
45*f012ee0cSGordon Ross 	for (i = 0; i < 5; i++) {
46*f012ee0cSGordon Ross 		struct iovec iov;
47*f012ee0cSGordon Ross 		struct msghdr msg;
48*f012ee0cSGordon Ross 		uint8_t buf[4096];
49*f012ee0cSGordon Ross 
50*f012ee0cSGordon Ross 		iov = (struct iovec) {
51*f012ee0cSGordon Ross 			.iov_base = buf,
52*f012ee0cSGordon Ross 			.iov_len = sizeof (buf)
53*f012ee0cSGordon Ross 		};
54*f012ee0cSGordon Ross 
55*f012ee0cSGordon Ross 		msg = (struct msghdr) {
56*f012ee0cSGordon Ross 			.msg_iov = &iov,
57*f012ee0cSGordon Ross 			.msg_iovlen = 1,
58*f012ee0cSGordon Ross 		};
59*f012ee0cSGordon Ross 
60*f012ee0cSGordon Ross 		ret = recvmsg(sock, &msg, 0);
61*f012ee0cSGordon Ross 		if (ret == -1) {
62*f012ee0cSGordon Ross 			fprintf(stderr, "server - recvmsg fail %s\n",
63*f012ee0cSGordon Ross 			    strerror(errno));
64*f012ee0cSGordon Ross 			exit(1);
65*f012ee0cSGordon Ross 		}
66*f012ee0cSGordon Ross 
67*f012ee0cSGordon Ross 		printf("SERVER:%s\n", (char *)msg.msg_iov->iov_base);
68*f012ee0cSGordon Ross 		fflush(stdout);
69*f012ee0cSGordon Ross 	}
70*f012ee0cSGordon Ross 
71*f012ee0cSGordon Ross 	exit(0);
72*f012ee0cSGordon Ross }
73*f012ee0cSGordon Ross 
74*f012ee0cSGordon Ross static void *
75*f012ee0cSGordon Ross listener(void *varg)
76*f012ee0cSGordon Ross {
77*f012ee0cSGordon Ross 	struct sockaddr_un *addr = varg;
78*f012ee0cSGordon Ross 	int ret;
79*f012ee0cSGordon Ross 	int lsock;
80*f012ee0cSGordon Ross 	int asock;
81*f012ee0cSGordon Ross 
82*f012ee0cSGordon Ross 	/* Child. */
83*f012ee0cSGordon Ross 	lsock = socket(AF_UNIX, SOCK_STREAM, 0);
84*f012ee0cSGordon Ross 	if (lsock == -1) {
85*f012ee0cSGordon Ross 		fprintf(stderr, "listener - socket fail %s\n", strerror(errno));
86*f012ee0cSGordon Ross 		exit(1);
87*f012ee0cSGordon Ross 	}
88*f012ee0cSGordon Ross 
89*f012ee0cSGordon Ross 	ret = bind(lsock, (struct sockaddr *)addr, sizeof (*addr));
90*f012ee0cSGordon Ross 	if (ret == -1) {
91*f012ee0cSGordon Ross 		fprintf(stderr, "listener - bind fail %s\n", strerror(errno));
92*f012ee0cSGordon Ross 		exit(1);
93*f012ee0cSGordon Ross 	}
94*f012ee0cSGordon Ross 
95*f012ee0cSGordon Ross 	ret = listen(lsock, 5);
96*f012ee0cSGordon Ross 	if (ret == -1) {
97*f012ee0cSGordon Ross 		fprintf(stderr, "listener - listen fail %s\n", strerror(errno));
98*f012ee0cSGordon Ross 		exit(1);
99*f012ee0cSGordon Ross 	}
100*f012ee0cSGordon Ross 
101*f012ee0cSGordon Ross 	for (;;) {
102*f012ee0cSGordon Ross 		asock = accept(lsock, NULL, 0);
103*f012ee0cSGordon Ross 		if (asock == -1) {
104*f012ee0cSGordon Ross 			fprintf(stderr, "listener - accept fail %s\n",
105*f012ee0cSGordon Ross 			    strerror(errno));
106*f012ee0cSGordon Ross 			exit(1);
107*f012ee0cSGordon Ross 		}
108*f012ee0cSGordon Ross 
109*f012ee0cSGordon Ross 		/* start worker */
110*f012ee0cSGordon Ross 		ret = pthread_create(NULL, NULL, server, (void *)asock);
111*f012ee0cSGordon Ross 		if (ret == -1) {
112*f012ee0cSGordon Ross 			fprintf(stderr, "%s - thread create fail %s\n",
113*f012ee0cSGordon Ross 			    __progname, strerror(errno));
114*f012ee0cSGordon Ross 			exit(1);
115*f012ee0cSGordon Ross 		}
116*f012ee0cSGordon Ross 	}
117*f012ee0cSGordon Ross 
118*f012ee0cSGordon Ross 	exit(0);
119*f012ee0cSGordon Ross }
120*f012ee0cSGordon Ross 
121*f012ee0cSGordon Ross /*
122*f012ee0cSGordon Ross  * This should be a place only root is allowed to write.
123*f012ee0cSGordon Ross  * The test will create and destroy this directory.
124*f012ee0cSGordon Ross  */
125*f012ee0cSGordon Ross char testdir[100] = "/var/run/os-tests-sockfs";
126*f012ee0cSGordon Ross struct sockaddr_un addr;
127*f012ee0cSGordon Ross int test_uid = UID_NOBODY;
128*f012ee0cSGordon Ross 
129*f012ee0cSGordon Ross int
130*f012ee0cSGordon Ross main(int argc, char **argv)
131*f012ee0cSGordon Ross {
132*f012ee0cSGordon Ross 	int ret;
133*f012ee0cSGordon Ross 	int sock;
134*f012ee0cSGordon Ross 	unsigned int i;
135*f012ee0cSGordon Ross 
136*f012ee0cSGordon Ross 	if (argc > 1) {
137*f012ee0cSGordon Ross 		ret = strlcpy(testdir, argv[1], sizeof (testdir));
138*f012ee0cSGordon Ross 		if (ret >= sizeof (testdir)) {
139*f012ee0cSGordon Ross 			fprintf(stderr, "%s: too long\n", argv[1]);
140*f012ee0cSGordon Ross 			exit(1);
141*f012ee0cSGordon Ross 		}
142*f012ee0cSGordon Ross 	}
143*f012ee0cSGordon Ross 
144*f012ee0cSGordon Ross 	addr.sun_family = AF_UNIX;
145*f012ee0cSGordon Ross 	(void) sprintf(addr.sun_path, "%s/s", testdir);
146*f012ee0cSGordon Ross 
147*f012ee0cSGordon Ross 	if (mkdir(testdir, 0700) != 0) {
148*f012ee0cSGordon Ross 		switch (errno) {
149*f012ee0cSGordon Ross 		case EEXIST:
150*f012ee0cSGordon Ross 		case EISDIR:
151*f012ee0cSGordon Ross 			break;
152*f012ee0cSGordon Ross 		default:
153*f012ee0cSGordon Ross 			perror(testdir);
154*f012ee0cSGordon Ross 			exit(1);
155*f012ee0cSGordon Ross 		}
156*f012ee0cSGordon Ross 	}
157*f012ee0cSGordon Ross 	(void) unlink(addr.sun_path);
158*f012ee0cSGordon Ross 
159*f012ee0cSGordon Ross 	/* Set up the listener. */
160*f012ee0cSGordon Ross 	ret = pthread_create(NULL, NULL, listener, &addr);
161*f012ee0cSGordon Ross 	if (ret == -1) {
162*f012ee0cSGordon Ross 		fprintf(stderr, "%s - thread create fail %s\n",
163*f012ee0cSGordon Ross 		    argv[0], strerror(errno));
164*f012ee0cSGordon Ross 		exit(1);
165*f012ee0cSGordon Ross 	}
166*f012ee0cSGordon Ross 
167*f012ee0cSGordon Ross 	sleep(1);
168*f012ee0cSGordon Ross 
169*f012ee0cSGordon Ross 	/* Create and connect the socket endpoint. */
170*f012ee0cSGordon Ross 
171*f012ee0cSGordon Ross 	sock = socket(AF_UNIX, SOCK_STREAM, 0);
172*f012ee0cSGordon Ross 	if (sock == -1) {
173*f012ee0cSGordon Ross 		fprintf(stderr, "%s - socket fail %s\n",
174*f012ee0cSGordon Ross 		    argv[0], strerror(errno));
175*f012ee0cSGordon Ross 		exit(1);
176*f012ee0cSGordon Ross 	}
177*f012ee0cSGordon Ross 
178*f012ee0cSGordon Ross 	ret = connect(sock, (struct sockaddr *)&addr, sizeof (addr));
179*f012ee0cSGordon Ross 	if (ret == -1) {
180*f012ee0cSGordon Ross 		fprintf(stderr, "%s - connect fail %s\n",
181*f012ee0cSGordon Ross 		    argv[0], strerror(errno));
182*f012ee0cSGordon Ross 		exit(1);
183*f012ee0cSGordon Ross 	}
184*f012ee0cSGordon Ross 
185*f012ee0cSGordon Ross 	/* Send some messages */
186*f012ee0cSGordon Ross 	for (i = 0; i < 5; i++) {
187*f012ee0cSGordon Ross 		struct iovec iov;
188*f012ee0cSGordon Ross 		struct msghdr msg;
189*f012ee0cSGordon Ross 		uint8_t buf[4096];
190*f012ee0cSGordon Ross 
191*f012ee0cSGordon Ross 		memcpy(buf, "TEST0", sizeof ("TEST0"));
192*f012ee0cSGordon Ross 		buf[4] = '0' + i;
193*f012ee0cSGordon Ross 
194*f012ee0cSGordon Ross 		printf("CLIENT:%s\n", buf);
195*f012ee0cSGordon Ross 
196*f012ee0cSGordon Ross 		iov = (struct iovec) {
197*f012ee0cSGordon Ross 			.iov_base = buf,
198*f012ee0cSGordon Ross 			.iov_len = sizeof (buf),
199*f012ee0cSGordon Ross 		};
200*f012ee0cSGordon Ross 
201*f012ee0cSGordon Ross 		msg = (struct msghdr) {
202*f012ee0cSGordon Ross 			.msg_iov = &iov,
203*f012ee0cSGordon Ross 			.msg_iovlen = 1,
204*f012ee0cSGordon Ross 		};
205*f012ee0cSGordon Ross 
206*f012ee0cSGordon Ross 		ret = sendmsg(sock, &msg, 0);
207*f012ee0cSGordon Ross 
208*f012ee0cSGordon Ross 		if (ret == -1) {
209*f012ee0cSGordon Ross 			fprintf(stderr, "%s - sendmsg fail %s\n",
210*f012ee0cSGordon Ross 			    argv[0], strerror(errno));
211*f012ee0cSGordon Ross 			exit(1);
212*f012ee0cSGordon Ross 		}
213*f012ee0cSGordon Ross 
214*f012ee0cSGordon Ross 		fflush(stdout);
215*f012ee0cSGordon Ross 		sleep(1);
216*f012ee0cSGordon Ross 	}
217*f012ee0cSGordon Ross 
218*f012ee0cSGordon Ross 	close(sock);
219*f012ee0cSGordon Ross 	return (0);
220*f012ee0cSGordon Ross }
221