| @@ -1,29 +1,31 @@ | | | @@ -1,29 +1,31 @@ |
1 | /* $NetBSD: t_rpc.c,v 1.5 2015/11/06 15:30:47 christos Exp $ */ | | 1 | /* $NetBSD: t_rpc.c,v 1.6 2015/11/08 19:38:04 christos Exp $ */ |
2 | | | 2 | |
3 | #include <sys/cdefs.h> | | 3 | #include <sys/cdefs.h> |
4 | __RCSID("$NetBSD: t_rpc.c,v 1.5 2015/11/06 15:30:47 christos Exp $"); | | 4 | __RCSID("$NetBSD: t_rpc.c,v 1.6 2015/11/08 19:38:04 christos Exp $"); |
5 | | | 5 | |
6 | #include <sys/types.h> | | 6 | #include <sys/types.h> |
7 | #include <sys/socket.h> | | 7 | #include <sys/socket.h> |
8 | #include <rpc/rpc.h> | | 8 | #include <rpc/rpc.h> |
9 | // #include <rpc/raw.h> | | | |
10 | #include <stdlib.h> | | 9 | #include <stdlib.h> |
| | | 10 | #include <string.h> |
11 | #include <err.h> | | 11 | #include <err.h> |
12 | #include <netdb.h> | | 12 | #include <netdb.h> |
13 | #include <stdio.h> | | 13 | #include <stdio.h> |
| | | 14 | #include <errno.h> |
14 | #include <unistd.h> | | 15 | #include <unistd.h> |
15 | | | 16 | |
16 | | | 17 | #define DEBUG |
| | | 18 | #define TEST |
17 | #ifndef TEST | | 19 | #ifndef TEST |
18 | #include <atf-c.h> | | 20 | #include <atf-c.h> |
19 | | | 21 | |
20 | #define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__) | | 22 | #define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__) |
21 | | | 23 | |
22 | #define SKIPX(ev, msg, ...) do { \ | | 24 | #define SKIPX(ev, msg, ...) do { \ |
23 | atf_tc_skip(msg, __VA_ARGS__); \ | | 25 | atf_tc_skip(msg, __VA_ARGS__); \ |
24 | return; \ | | 26 | return; \ |
25 | } while(/*CONSTCOND*/0) | | 27 | } while(/*CONSTCOND*/0) |
26 | | | 28 | |
27 | #else | | 29 | #else |
28 | #define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) | | 30 | #define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) |
29 | #define SKIPX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) | | 31 | #define SKIPX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) |
| @@ -76,43 +78,49 @@ onehost(const char *host, const char *tr | | | @@ -76,43 +78,49 @@ onehost(const char *host, const char *tr |
76 | | | 78 | |
77 | tv.tv_sec = 1; | | 79 | tv.tv_sec = 1; |
78 | tv.tv_usec = 0; | | 80 | tv.tv_usec = 0; |
79 | if (clnt_call(clnt, RPCBPROC_NULL, xdr_void, NULL, xdr_void, NULL, tv) | | 81 | if (clnt_call(clnt, RPCBPROC_NULL, xdr_void, NULL, xdr_void, NULL, tv) |
80 | != RPC_SUCCESS) | | 82 | != RPC_SUCCESS) |
81 | ERRX(EXIT_FAILURE, "clnt_call (%s)", clnt_sperror(clnt, "")); | | 83 | ERRX(EXIT_FAILURE, "clnt_call (%s)", clnt_sperror(clnt, "")); |
82 | clnt_control(clnt, CLGET_SVC_ADDR, (char *) &addr); | | 84 | clnt_control(clnt, CLGET_SVC_ADDR, (char *) &addr); |
83 | reply(NULL, &addr, NULL); | | 85 | reply(NULL, &addr, NULL); |
84 | } | | 86 | } |
85 | | | 87 | |
86 | #define PROGNUM 0x81 | | 88 | #define PROGNUM 0x81 |
87 | #define VERSNUM 0x01 | | 89 | #define VERSNUM 0x01 |
88 | #define PLUSONE 1 | | 90 | #define PLUSONE 1 |
| | | 91 | #define DESTROY 2 |
89 | | | 92 | |
90 | static struct timeval tout = {0, 0}; | | 93 | static struct timeval tout = {1, 0}; |
91 | | | 94 | |
92 | static void | | 95 | static void |
93 | server(struct svc_req *rqstp, SVCXPRT *transp) | | 96 | server(struct svc_req *rqstp, SVCXPRT *transp) |
94 | { | | 97 | { |
95 | int num; | | 98 | int num; |
96 | | | 99 | |
97 | DPRINTF("Starting server\n"); | | 100 | DPRINTF("Starting server\n"); |
98 | | | 101 | |
99 | switch (rqstp->rq_proc) { | | 102 | switch (rqstp->rq_proc) { |
100 | case NULLPROC: | | 103 | case NULLPROC: |
101 | if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL)) | | 104 | if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL)) |
102 | ERRX(EXIT_FAILURE, "svc_sendreply failed %d", 0); | | 105 | ERRX(EXIT_FAILURE, "svc_sendreply failed %d", 0); |
103 | return; | | 106 | return; |
104 | case PLUSONE: | | 107 | case PLUSONE: |
105 | break; | | 108 | break; |
| | | 109 | case DESTROY: |
| | | 110 | if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL)) |
| | | 111 | ERRX(EXIT_FAILURE, "svc_sendreply failed %d", 0); |
| | | 112 | svc_destroy(transp); |
| | | 113 | exit(0); |
106 | default: | | 114 | default: |
107 | svcerr_noproc(transp); | | 115 | svcerr_noproc(transp); |
108 | return; | | 116 | return; |
109 | } | | 117 | } |
110 | | | 118 | |
111 | if (!svc_getargs(transp, (xdrproc_t)xdr_int, (void *)&num)) { | | 119 | if (!svc_getargs(transp, (xdrproc_t)xdr_int, (void *)&num)) { |
112 | svcerr_decode(transp); | | 120 | svcerr_decode(transp); |
113 | return; | | 121 | return; |
114 | } | | 122 | } |
115 | DPRINTF("About to increment\n"); | | 123 | DPRINTF("About to increment\n"); |
116 | num++; | | 124 | num++; |
117 | if (!svc_sendreply(transp, (xdrproc_t)xdr_int, (void *)&num)) | | 125 | if (!svc_sendreply(transp, (xdrproc_t)xdr_int, (void *)&num)) |
118 | ERRX(EXIT_FAILURE, "svc_sendreply failed %d", 1); | | 126 | ERRX(EXIT_FAILURE, "svc_sendreply failed %d", 1); |
| @@ -145,73 +153,132 @@ rawtest(const char *arg) | | | @@ -145,73 +153,132 @@ rawtest(const char *arg) |
145 | rv = clnt_call(clnt, PLUSONE, (xdrproc_t)xdr_int, (void *)&num, | | 153 | rv = clnt_call(clnt, PLUSONE, (xdrproc_t)xdr_int, (void *)&num, |
146 | (xdrproc_t)xdr_int, (void *)&resp, tout); | | 154 | (xdrproc_t)xdr_int, (void *)&resp, tout); |
147 | if (rv != RPC_SUCCESS) | | 155 | if (rv != RPC_SUCCESS) |
148 | ERRX(EXIT_FAILURE, "clnt_call: %s", clnt_sperrno(rv)); | | 156 | ERRX(EXIT_FAILURE, "clnt_call: %s", clnt_sperrno(rv)); |
149 | DPRINTF("Got %d\n", resp); | | 157 | DPRINTF("Got %d\n", resp); |
150 | clnt_destroy(clnt); | | 158 | clnt_destroy(clnt); |
151 | svc_destroy(svc); | | 159 | svc_destroy(svc); |
152 | if (++num != resp) | | 160 | if (++num != resp) |
153 | ERRX(EXIT_FAILURE, "expected %d got %d", num, resp); | | 161 | ERRX(EXIT_FAILURE, "expected %d got %d", num, resp); |
154 | | | 162 | |
155 | return EXIT_SUCCESS; | | 163 | return EXIT_SUCCESS; |
156 | } | | 164 | } |
157 | | | 165 | |
| | | 166 | static int |
| | | 167 | regtest(const char *hostname, const char *transp, const char *arg, int p) |
| | | 168 | { |
| | | 169 | CLIENT *clnt; |
| | | 170 | int num, resp; |
| | | 171 | enum clnt_stat rv; |
| | | 172 | pid_t pid; |
| | | 173 | |
| | | 174 | if (arg) |
| | | 175 | num = atoi(arg); |
| | | 176 | else |
| | | 177 | num = 0; |
| | | 178 | |
| | | 179 | svc_fdset_init(p ? SVC_FDSET_POLL : 0); |
| | | 180 | if (!svc_create(server, PROGNUM, VERSNUM, transp)) |
| | | 181 | ERRX(EXIT_FAILURE, "Can't not create server %d", num); |
| | | 182 | |
| | | 183 | switch ((pid = fork())) { |
| | | 184 | case 0: |
| | | 185 | DPRINTF("Calling svc_run\n"); |
| | | 186 | svc_run(); |
| | | 187 | case -1: |
| | | 188 | ERRX(EXIT_FAILURE, "Fork failed (%s)", strerror(errno)); |
| | | 189 | default: |
| | | 190 | sleep(1); |
| | | 191 | break; |
| | | 192 | } |
| | | 193 | |
| | | 194 | DPRINTF("Initializing client\n"); |
| | | 195 | clnt = clnt_create(hostname, PROGNUM, VERSNUM, transp); |
| | | 196 | if (clnt == NULL) |
| | | 197 | ERRX(EXIT_FAILURE, "%s", |
| | | 198 | clnt_spcreateerror("clnt_raw_create")); |
| | | 199 | rv = clnt_call(clnt, PLUSONE, (xdrproc_t)xdr_int, (void *)&num, |
| | | 200 | (xdrproc_t)xdr_int, (void *)&resp, tout); |
| | | 201 | if (rv != RPC_SUCCESS) |
| | | 202 | ERRX(EXIT_FAILURE, "clnt_call: %s", clnt_sperrno(rv)); |
| | | 203 | DPRINTF("Got %d\n", resp); |
| | | 204 | if (++num != resp) |
| | | 205 | ERRX(EXIT_FAILURE, "expected %d got %d", num, resp); |
| | | 206 | rv = clnt_call(clnt, DESTROY, (xdrproc_t)xdr_void, NULL, |
| | | 207 | (xdrproc_t)xdr_void, NULL, tout); |
| | | 208 | if (rv != RPC_SUCCESS) |
| | | 209 | ERRX(EXIT_FAILURE, "clnt_call: %s", clnt_sperrno(rv)); |
| | | 210 | clnt_destroy(clnt); |
| | | 211 | |
| | | 212 | return EXIT_SUCCESS; |
| | | 213 | } |
| | | 214 | |
158 | | | 215 | |
159 | #ifdef TEST | | 216 | #ifdef TEST |
160 | static void | | 217 | static void |
161 | allhosts(const char *transp) | | 218 | allhosts(const char *transp) |
162 | { | | 219 | { |
163 | enum clnt_stat clnt_stat; | | 220 | enum clnt_stat clnt_stat; |
164 | | | 221 | |
165 | clnt_stat = rpc_broadcast(RPCBPROG, RPCBVERS, RPCBPROC_NULL, | | 222 | clnt_stat = rpc_broadcast(RPCBPROG, RPCBVERS, RPCBPROC_NULL, |
166 | (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void, | | 223 | (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void, |
167 | NULL, (resultproc_t)reply, transp); | | 224 | NULL, (resultproc_t)reply, transp); |
168 | if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) | | 225 | if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) |
169 | ERRX(EXIT_FAILURE, "%s", clnt_sperrno(clnt_stat)); | | 226 | ERRX(EXIT_FAILURE, "%s", clnt_sperrno(clnt_stat)); |
170 | } | | 227 | } |
171 | | | 228 | |
172 | int | | 229 | int |
173 | main(int argc, char *argv[]) | | 230 | main(int argc, char *argv[]) |
174 | { | | 231 | { |
175 | int ch; | | 232 | int ch; |
| | | 233 | int s, p; |
176 | const char *transp = "udp"; | | 234 | const char *transp = "udp"; |
177 | | | 235 | |
178 | | | 236 | p = s = 0; |
179 | while ((ch = getopt(argc, argv, "rtu")) != -1) | | 237 | while ((ch = getopt(argc, argv, "prstu")) != -1) |
180 | switch (ch) { | | 238 | switch (ch) { |
| | | 239 | case 'p': |
| | | 240 | p = 1; |
| | | 241 | break; |
| | | 242 | case 's': |
| | | 243 | s = 1; |
| | | 244 | break; |
181 | case 't': | | 245 | case 't': |
182 | transp = "tcp"; | | 246 | transp = "tcp"; |
183 | break; | | 247 | break; |
184 | case 'u': | | 248 | case 'u': |
185 | transp = "udp"; | | 249 | transp = "udp"; |
186 | break; | | 250 | break; |
187 | case 'r': | | 251 | case 'r': |
188 | transp = NULL; | | 252 | transp = NULL; |
189 | break; | | 253 | break; |
190 | default: | | 254 | default: |
191 | fprintf(stderr, "Usage: %s -[r|t|u] [<hostname>...]\n", | | 255 | fprintf(stderr, |
| | | 256 | "Usage: %s -[r|s|t|u] [<hostname>...]\n", |
192 | getprogname()); | | 257 | getprogname()); |
193 | return EXIT_FAILURE; | | 258 | return EXIT_FAILURE; |
194 | } | | 259 | } |
195 | | | 260 | |
196 | if (argc == optind) { | | 261 | if (argc == optind) { |
197 | if (transp) | | 262 | if (transp) |
198 | allhosts(transp); | | 263 | allhosts(transp); |
199 | else | | 264 | else |
200 | rawtest(NULL); | | 265 | rawtest(NULL); |
201 | } else { | | 266 | } else { |
202 | for (; optind < argc; optind++) { | | 267 | for (; optind < argc; optind++) { |
203 | if (transp) | | 268 | if (transp) |
204 | onehost(argv[optind], transp); | | 269 | s == 0 ? |
| | | 270 | onehost(argv[optind], transp) : |
| | | 271 | regtest(argv[optind], transp, "1", p); |
205 | else | | 272 | else |
206 | rawtest(argv[optind]); | | 273 | rawtest(argv[optind]); |
207 | } | | 274 | } |
208 | } | | 275 | } |
209 | | | 276 | |
210 | return EXIT_SUCCESS; | | 277 | return EXIT_SUCCESS; |
211 | } | | 278 | } |
212 | | | 279 | |
213 | #else | | 280 | #else |
214 | | | 281 | |
215 | ATF_TC(get_svc_addr_tcp); | | 282 | ATF_TC(get_svc_addr_tcp); |
216 | ATF_TC_HEAD(get_svc_addr_tcp, tc) | | 283 | ATF_TC_HEAD(get_svc_addr_tcp, tc) |
217 | { | | 284 | { |
| @@ -238,23 +305,76 @@ ATF_TC_BODY(get_svc_addr_udp, tc) | | | @@ -238,23 +305,76 @@ ATF_TC_BODY(get_svc_addr_udp, tc) |
238 | } | | 305 | } |
239 | | | 306 | |
240 | ATF_TC(raw); | | 307 | ATF_TC(raw); |
241 | ATF_TC_HEAD(raw, tc) | | 308 | ATF_TC_HEAD(raw, tc) |
242 | { | | 309 | { |
243 | atf_tc_set_md_var(tc, "descr", "Checks svc raw"); | | 310 | atf_tc_set_md_var(tc, "descr", "Checks svc raw"); |
244 | } | | 311 | } |
245 | | | 312 | |
246 | ATF_TC_BODY(raw, tc) | | 313 | ATF_TC_BODY(raw, tc) |
247 | { | | 314 | { |
248 | rawtest(NULL); | | 315 | rawtest(NULL); |
249 | | | 316 | |
250 | } | | 317 | } |
| | | 318 | |
| | | 319 | ATF_TC(tcp); |
| | | 320 | ATF_TC_HEAD(tcp, tc) |
| | | 321 | { |
| | | 322 | atf_tc_set_md_var(tc, "descr", "Checks svc tcp (select)"); |
| | | 323 | } |
| | | 324 | |
| | | 325 | ATF_TC_BODY(tcp, tc) |
| | | 326 | { |
| | | 327 | regtest("localhost", "tcp", 1, 0); |
| | | 328 | |
| | | 329 | } |
| | | 330 | |
| | | 331 | ATF_TC(udp); |
| | | 332 | ATF_TC_HEAD(udp, tc) |
| | | 333 | { |
| | | 334 | atf_tc_set_md_var(tc, "descr", "Checks svc udp (select)"); |
| | | 335 | } |
| | | 336 | |
| | | 337 | ATF_TC_BODY(udp, tc) |
| | | 338 | { |
| | | 339 | regtest("localhost", "udp", 1, 0); |
| | | 340 | |
| | | 341 | } |
| | | 342 | |
| | | 343 | ATF_TC(tcp_poll); |
| | | 344 | ATF_TC_HEAD(tcp_poll, tc) |
| | | 345 | { |
| | | 346 | atf_tc_set_md_var(tc, "descr", "Checks svc tcp (poll)"); |
| | | 347 | } |
| | | 348 | |
| | | 349 | ATF_TC_BODY(tcp_poll, tc) |
| | | 350 | { |
| | | 351 | regtest("localhost", "tcp", 1, 1); |
| | | 352 | |
| | | 353 | } |
| | | 354 | |
| | | 355 | ATF_TC(udp_poll); |
| | | 356 | ATF_TC_HEAD(udp_poll, tc) |
| | | 357 | { |
| | | 358 | atf_tc_set_md_var(tc, "descr", "Checks svc udp (poll)"); |
| | | 359 | } |
| | | 360 | |
| | | 361 | ATF_TC_BODY(udp_poll, tc) |
| | | 362 | { |
| | | 363 | regtest("localhost", "udp", 1, 1); |
| | | 364 | |
| | | 365 | } |
| | | 366 | |
251 | ATF_TP_ADD_TCS(tp) | | 367 | ATF_TP_ADD_TCS(tp) |
252 | { | | 368 | { |
253 | ATF_TP_ADD_TC(tp, get_svc_addr_udp); | | 369 | ATF_TP_ADD_TC(tp, get_svc_addr_udp); |
254 | ATF_TP_ADD_TC(tp, get_svc_addr_tcp); | | 370 | ATF_TP_ADD_TC(tp, get_svc_addr_tcp); |
255 | ATF_TP_ADD_TC(tp, raw); | | 371 | ATF_TP_ADD_TC(tp, raw); |
| | | 372 | ATF_TP_ADD_TC(tp, tcp); |
| | | 373 | ATF_TP_ADD_TC(tp, udp); |
| | | 374 | ATF_TP_ADD_TC(tp, tcp_poll); |
| | | 375 | ATF_TP_ADD_TC(tp, udp_poll); |
256 | | | 376 | |
257 | return atf_no_error(); | | 377 | return atf_no_error(); |
258 | } | | 378 | } |
259 | | | 379 | |
260 | #endif | | 380 | #endif |