]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/netbsd-tests/lib/libc/rpc/t_rpc.c
MFC r305358,r305449,r305451,r306367,r306397,r309474:
[FreeBSD/stable/10.git] / contrib / netbsd-tests / lib / libc / rpc / t_rpc.c
1 /*      $NetBSD: t_rpc.c,v 1.9 2015/11/27 13:59:40 christos Exp $       */
2
3 #include <sys/cdefs.h>
4 __RCSID("$NetBSD: t_rpc.c,v 1.9 2015/11/27 13:59:40 christos Exp $");
5
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <rpc/rpc.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <err.h>
12 #include <netdb.h>
13 #include <stdio.h>
14 #include <errno.h>
15 #include <unistd.h>
16
17 #ifndef TEST
18 #include <atf-c.h>
19
20 #define ERRX(ev, msg, ...)      ATF_REQUIRE_MSG(0, msg, __VA_ARGS__)
21
22 #define SKIPX(ev, msg, ...)     do {                    \
23         atf_tc_skip(msg, __VA_ARGS__);                  \
24         return;                                         \
25 } while(/*CONSTCOND*/0)
26
27 #ifdef __FreeBSD__
28 #define SKIPXI(ev, msg, ...)    do {                    \
29         atf_tc_skip(msg, __VA_ARGS__);                  \
30         return ev;                                      \
31 } while(/*CONSTCOND*/0)
32 #endif
33
34 #else
35 #define ERRX(ev, msg, ...)      errx(ev, msg, __VA_ARGS__)
36 #define SKIPX(ev, msg, ...)     errx(ev, msg, __VA_ARGS__)
37 #endif
38
39 #ifdef DEBUG
40 #define DPRINTF(...)    printf(__VA_ARGS__)
41 #else
42 #define DPRINTF(...)
43 #endif
44
45
46 #define RPCBPROC_NULL 0
47
48 static int
49 reply(caddr_t replyp, struct netbuf * raddrp, struct netconfig * nconf)
50 {
51         char host[NI_MAXHOST];
52         struct sockaddr *sock = raddrp->buf;
53         int error;
54
55
56         error = getnameinfo(sock, sock->sa_len, host, sizeof(host), NULL, 0, 0);
57         if (error)
58                 warnx("Cannot resolve address (%s)", gai_strerror(error));
59         else
60                 printf("response from: %s\n", host);
61         return 0;
62 }
63
64 #ifdef __FreeBSD__
65 #define __rpc_control   rpc_control
66 #endif
67
68 extern bool_t __rpc_control(int, void *);
69
70 static void
71 onehost(const char *host, const char *transp)
72 {
73         CLIENT         *clnt;
74         struct netbuf   addr;
75         struct timeval  tv;
76
77         /*
78          * Magic!
79          */
80         tv.tv_sec = 0;
81         tv.tv_usec = 500000;
82 #define CLCR_SET_RPCB_TIMEOUT   2
83         __rpc_control(CLCR_SET_RPCB_TIMEOUT, &tv);
84
85         if ((clnt = clnt_create(host, RPCBPROG, RPCBVERS, transp)) == NULL)
86                 SKIPX(EXIT_FAILURE, "clnt_create (%s)", clnt_spcreateerror(""));
87
88         tv.tv_sec = 1;
89         tv.tv_usec = 0;
90 #ifdef __FreeBSD__
91         if (clnt_call(clnt, RPCBPROC_NULL, (xdrproc_t)xdr_void, NULL,
92             (xdrproc_t)xdr_void, NULL, tv)
93             != RPC_SUCCESS)
94 #else
95         if (clnt_call(clnt, RPCBPROC_NULL, xdr_void, NULL, xdr_void, NULL, tv)
96             != RPC_SUCCESS)
97 #endif
98                 ERRX(EXIT_FAILURE, "clnt_call (%s)", clnt_sperror(clnt, ""));
99         clnt_control(clnt, CLGET_SVC_ADDR, (char *) &addr);
100         reply(NULL, &addr, NULL);
101 }
102
103 #define PROGNUM 0x81
104 #define VERSNUM 0x01
105 #define PLUSONE 1
106 #define DESTROY 2
107
108 static struct timeval   tout = {1, 0};
109
110 static void
111 server(struct svc_req *rqstp, SVCXPRT *transp)
112 {
113         int num;
114
115         DPRINTF("Starting server\n");
116
117         switch (rqstp->rq_proc) {
118         case NULLPROC:
119                 if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL))
120                         ERRX(EXIT_FAILURE, "svc_sendreply failed %d", 0);
121                 return;
122         case PLUSONE:
123                 break;
124         case DESTROY:
125                 if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL))
126                         ERRX(EXIT_FAILURE, "svc_sendreply failed %d", 0);
127                 svc_destroy(transp);
128                 exit(0);
129         default:
130                 svcerr_noproc(transp);
131                 return;
132         }
133
134         if (!svc_getargs(transp, (xdrproc_t)xdr_int, (void *)&num)) {
135                 svcerr_decode(transp);
136                 return;
137         }
138         DPRINTF("About to increment\n");
139         num++;
140         if (!svc_sendreply(transp, (xdrproc_t)xdr_int, (void *)&num))
141                 ERRX(EXIT_FAILURE, "svc_sendreply failed %d", 1);
142         DPRINTF("Leaving server procedure.\n");
143 }
144
145 static int
146 rawtest(const char *arg)
147 {
148         CLIENT         *clnt;
149         SVCXPRT        *svc;
150         int             num, resp;
151         enum clnt_stat  rv;
152
153         if (arg)
154                 num = atoi(arg);
155         else
156                 num = 0;
157
158         svc = svc_raw_create();
159         if (svc == NULL)
160                 ERRX(EXIT_FAILURE, "Cannot create server %d", num);
161         if (!svc_reg(svc, PROGNUM, VERSNUM, server, NULL))
162                 ERRX(EXIT_FAILURE, "Cannot register server %d", num);
163
164         clnt = clnt_raw_create(PROGNUM, VERSNUM);
165         if (clnt == NULL)
166                 ERRX(EXIT_FAILURE, "%s",
167                     clnt_spcreateerror("clnt_raw_create"));
168         rv = clnt_call(clnt, PLUSONE, (xdrproc_t)xdr_int, (void *)&num,
169             (xdrproc_t)xdr_int, (void *)&resp, tout);
170         if (rv != RPC_SUCCESS)
171                 ERRX(EXIT_FAILURE, "clnt_call: %s", clnt_sperrno(rv));
172         DPRINTF("Got %d\n", resp);
173         clnt_destroy(clnt);
174         svc_destroy(svc);
175         if (++num != resp)
176                 ERRX(EXIT_FAILURE, "expected %d got %d", num, resp);
177
178         return EXIT_SUCCESS;
179 }
180
181 static int
182 regtest(const char *hostname, const char *transp, const char *arg, int p)
183 {
184         CLIENT         *clnt;
185         int             num, resp;
186         enum clnt_stat  rv;
187         pid_t           pid;
188
189         if (arg)
190                 num = atoi(arg);
191         else
192                 num = 0;
193
194 #ifdef __NetBSD__
195         svc_fdset_init(p ? SVC_FDSET_POLL : 0);
196 #endif
197         if (!svc_create(server, PROGNUM, VERSNUM, transp))
198 #ifdef __NetBSD__
199                 ERRX(EXIT_FAILURE, "Cannot create server %d", num);
200 #else
201         {
202                 SKIPXI(EXIT_FAILURE, "Cannot create server %d", num);
203         }
204 #endif
205
206         switch ((pid = fork())) {
207         case 0:
208                 DPRINTF("Calling svc_run\n");
209                 svc_run();
210                 ERRX(EXIT_FAILURE, "svc_run returned %d!", num);
211         case -1:
212                 ERRX(EXIT_FAILURE, "Fork failed (%s)", strerror(errno));
213         default:
214                 sleep(1);
215                 break;
216         }
217
218         DPRINTF("Initializing client\n");
219         clnt = clnt_create(hostname, PROGNUM, VERSNUM, transp);
220         if (clnt == NULL)
221                 ERRX(EXIT_FAILURE, "%s",
222                     clnt_spcreateerror("clnt_raw_create"));
223         rv = clnt_call(clnt, PLUSONE, (xdrproc_t)xdr_int, (void *)&num,
224             (xdrproc_t)xdr_int, (void *)&resp, tout);
225         if (rv != RPC_SUCCESS)
226                 ERRX(EXIT_FAILURE, "clnt_call: %s", clnt_sperrno(rv));
227         DPRINTF("Got %d\n", resp);
228         if (++num != resp)
229                 ERRX(EXIT_FAILURE, "expected %d got %d", num, resp);
230         rv = clnt_call(clnt, DESTROY, (xdrproc_t)xdr_void, NULL,
231             (xdrproc_t)xdr_void, NULL, tout);
232         if (rv != RPC_SUCCESS)
233                 ERRX(EXIT_FAILURE, "clnt_call: %s", clnt_sperrno(rv));
234         clnt_destroy(clnt);
235
236         return EXIT_SUCCESS;
237 }
238
239
240 #ifdef TEST
241 static void
242 allhosts(const char *transp)
243 {
244         enum clnt_stat  clnt_stat;
245
246         clnt_stat = rpc_broadcast(RPCBPROG, RPCBVERS, RPCBPROC_NULL,
247             (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void,
248             NULL, (resultproc_t)reply, transp);
249         if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT)
250                 ERRX(EXIT_FAILURE, "%s", clnt_sperrno(clnt_stat));
251 }
252
253 int
254 main(int argc, char *argv[])
255 {
256         int             ch;
257         int             s, p;
258         const char     *transp = "udp";
259
260         p = s = 0;
261         while ((ch = getopt(argc, argv, "prstu")) != -1)
262                 switch (ch) {
263                 case 'p':
264                         p = 1;
265                         break;
266                 case 's':
267                         s = 1;
268                         break;
269                 case 't':
270                         transp = "tcp";
271                         break;
272                 case 'u':
273                         transp = "udp";
274                         break;
275                 case 'r':
276                         transp = NULL;
277                         break;
278                 default:
279                         fprintf(stderr,
280                             "Usage: %s -[r|s|t|u] [<hostname>...]\n",
281                             getprogname());
282                         return EXIT_FAILURE;
283                 }
284
285         if (argc == optind) {
286                 if  (transp)
287                         allhosts(transp);
288                 else
289                         rawtest(NULL);
290         } else {
291                 for (; optind < argc; optind++) {
292                         if (transp)
293                                 s == 0 ?
294                                     onehost(argv[optind], transp) :
295                                     regtest(argv[optind], transp, "1", p);
296                         else
297                                 rawtest(argv[optind]);
298                 }
299         }
300
301         return EXIT_SUCCESS;
302 }
303
304 #else
305
306 ATF_TC(get_svc_addr_tcp);
307 ATF_TC_HEAD(get_svc_addr_tcp, tc)
308 {
309         atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for tcp");
310
311 }
312
313 ATF_TC_BODY(get_svc_addr_tcp, tc)
314 {
315         onehost("localhost", "tcp");
316
317 }
318
319 ATF_TC(get_svc_addr_udp);
320 ATF_TC_HEAD(get_svc_addr_udp, tc)
321 {
322         atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for udp");
323 }
324
325 ATF_TC_BODY(get_svc_addr_udp, tc)
326 {
327         onehost("localhost", "udp");
328
329 }
330
331 ATF_TC(raw);
332 ATF_TC_HEAD(raw, tc)
333 {
334         atf_tc_set_md_var(tc, "descr", "Checks svc raw");
335 }
336
337 ATF_TC_BODY(raw, tc)
338 {
339 #ifdef __FreeBSD__
340         atf_tc_expect_fail("fails with: clnt_call: "
341             "RPC: Can't decode result -- PR # 211804");
342 #endif
343         rawtest(NULL);
344
345 }
346
347 ATF_TC(tcp);
348 ATF_TC_HEAD(tcp, tc)
349 {
350         atf_tc_set_md_var(tc, "descr", "Checks svc tcp (select)");
351 #ifdef __FreeBSD__
352         atf_tc_set_md_var(tc, "require.user", "root");
353 #endif
354 }
355
356 ATF_TC_BODY(tcp, tc)
357 {
358         regtest("localhost", "tcp", "1", 0);
359
360 }
361
362 ATF_TC(udp);
363 ATF_TC_HEAD(udp, tc)
364 {
365         atf_tc_set_md_var(tc, "descr", "Checks svc udp (select)");
366 #ifdef __FreeBSD__
367         atf_tc_set_md_var(tc, "require.user", "root");
368 #endif
369 }
370
371 ATF_TC_BODY(udp, tc)
372 {
373         regtest("localhost", "udp", "1", 0);
374
375 }
376
377 ATF_TC(tcp_poll);
378 ATF_TC_HEAD(tcp_poll, tc)
379 {
380         atf_tc_set_md_var(tc, "descr", "Checks svc tcp (poll)");
381 #ifdef __FreeBSD__
382         atf_tc_set_md_var(tc, "require.user", "root");
383 #endif
384 }
385
386 ATF_TC_BODY(tcp_poll, tc)
387 {
388         regtest("localhost", "tcp", "1", 1);
389
390 }
391
392 ATF_TC(udp_poll);
393 ATF_TC_HEAD(udp_poll, tc)
394 {
395         atf_tc_set_md_var(tc, "descr", "Checks svc udp (poll)");
396 #ifdef __FreeBSD__
397         atf_tc_set_md_var(tc, "require.user", "root");
398 #endif
399 }
400
401 ATF_TC_BODY(udp_poll, tc)
402 {
403         regtest("localhost", "udp", "1", 1);
404
405 }
406
407 ATF_TP_ADD_TCS(tp)
408 {
409         ATF_TP_ADD_TC(tp, get_svc_addr_udp);
410         ATF_TP_ADD_TC(tp, get_svc_addr_tcp);
411         ATF_TP_ADD_TC(tp, raw);
412         ATF_TP_ADD_TC(tp, tcp);
413         ATF_TP_ADD_TC(tp, udp);
414         ATF_TP_ADD_TC(tp, tcp_poll);
415         ATF_TP_ADD_TC(tp, udp_poll);
416
417         return atf_no_error();
418 }
419
420 #endif