Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2018 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/stdinc.h"
7 : : #include "spdk/thread.h"
8 : : #include "spdk/env.h"
9 : : #include "spdk/event.h"
10 : : #include "spdk/log.h"
11 : : #include "spdk/string.h"
12 : :
13 : : #include "spdk/sock.h"
14 : : #include "spdk/hexlify.h"
15 : : #include "spdk/nvmf.h"
16 : :
17 : : #define ACCEPT_TIMEOUT_US 1000
18 : : #define CLOSE_TIMEOUT_US 1000000
19 : : #define BUFFER_SIZE 1024
20 : : #define ADDR_STR_LEN INET6_ADDRSTRLEN
21 : :
22 : : static bool g_is_running;
23 : :
24 : : static char *g_host;
25 : : static char *g_sock_impl_name;
26 : : static int g_port;
27 : : static bool g_is_server;
28 : : static int g_zcopy;
29 : : static int g_ktls;
30 : : static int g_tls_version;
31 : : static bool g_verbose;
32 : : static uint8_t g_psk_key[SPDK_TLS_PSK_MAX_LEN];
33 : : static uint32_t g_psk_key_size;
34 : : static char *g_psk_identity;
35 : :
36 : : /*
37 : : * We'll use this struct to gather housekeeping hello_context to pass between
38 : : * our events and callbacks.
39 : : */
40 : : struct hello_context_t {
41 : : bool is_server;
42 : : char *host;
43 : : const char *sock_impl_name;
44 : : int port;
45 : : int zcopy;
46 : : int ktls;
47 : : int tls_version;
48 : : uint8_t *psk_key;
49 : : uint32_t psk_key_size;
50 : : char *psk_identity;
51 : :
52 : : bool verbose;
53 : : int bytes_in;
54 : : int bytes_out;
55 : :
56 : : struct spdk_sock *sock;
57 : :
58 : : struct spdk_sock_group *group;
59 : : void *buf;
60 : : struct spdk_poller *poller_in;
61 : : struct spdk_poller *poller_out;
62 : : struct spdk_poller *time_out;
63 : :
64 : : int rc;
65 : : ssize_t n;
66 : : };
67 : :
68 : : /*
69 : : * Usage function for printing parameters that are specific to this application
70 : : */
71 : : static void
72 : 0 : hello_sock_usage(void)
73 : : {
74 [ # # ]: 0 : printf(" -E psk_key Default PSK KEY in hexadecimal digits, e.g. 1234567890ABCDEF (only applies when sock_impl == ssl)\n");
75 [ # # ]: 0 : printf(" -H host_addr host address\n");
76 [ # # ]: 0 : printf(" -I psk_id Default PSK ID, e.g. psk.spdk.io (only applies when sock_impl == ssl)\n");
77 [ # # ]: 0 : printf(" -P port port number\n");
78 [ # # ]: 0 : printf(" -N sock_impl socket implementation, e.g., -N posix or -N uring\n");
79 [ # # ]: 0 : printf(" -S start in server mode\n");
80 [ # # ]: 0 : printf(" -T tls_ver TLS version, e.g., -T 12 or -T 13. If omitted, auto-negotiation will take place\n");
81 [ # # ]: 0 : printf(" -k disable KTLS for the given sock implementation (default)\n");
82 [ # # ]: 0 : printf(" -K enable KTLS for the given sock implementation\n");
83 [ # # ]: 0 : printf(" -V print out additional information\n");
84 [ # # ]: 0 : printf(" -z disable zero copy send for the given sock implementation\n");
85 [ # # ]: 0 : printf(" -Z enable zero copy send for the given sock implementation\n");
86 : 0 : }
87 : :
88 : : /*
89 : : * This function is called to parse the parameters that are specific to this application
90 : : */
91 : : static int
92 : 112 : hello_sock_parse_arg(int ch, char *arg)
93 : : {
94 : : char *unhexlified;
95 : :
96 [ + + + + : 112 : switch (ch) {
+ + - + +
- + + - ]
97 : 16 : case 'E':
98 [ - + ]: 16 : g_psk_key_size = strlen(arg) / 2;
99 [ - + ]: 16 : if (g_psk_key_size > SPDK_TLS_PSK_MAX_LEN) {
100 [ # # ]: 0 : fprintf(stderr, "Invalid PSK: too long (%"PRIu32")\n", g_psk_key_size);
101 : 0 : return -EINVAL;
102 : : }
103 : 16 : unhexlified = spdk_unhexlify(arg);
104 [ - + ]: 16 : if (unhexlified == NULL) {
105 [ # # ]: 0 : fprintf(stderr, "Invalid PSK: not in a hex format\n");
106 : 0 : return -EINVAL;
107 : : }
108 [ - + ]: 16 : memcpy(g_psk_key, unhexlified, g_psk_key_size);
109 : 16 : free(unhexlified);
110 : 16 : break;
111 : 22 : case 'H':
112 : 22 : g_host = arg;
113 : 22 : break;
114 : 16 : case 'I':
115 : 16 : g_psk_identity = arg;
116 : 16 : break;
117 : 22 : case 'N':
118 : 22 : g_sock_impl_name = arg;
119 : 22 : break;
120 : 22 : case 'P':
121 : 22 : g_port = spdk_strtol(arg, 10);
122 [ - + ]: 22 : if (g_port < 0) {
123 [ # # ]: 0 : fprintf(stderr, "Invalid port ID\n");
124 : 0 : return g_port;
125 : : }
126 : 22 : break;
127 : 4 : case 'S':
128 : 4 : g_is_server = 1;
129 : 4 : break;
130 : 0 : case 'K':
131 : 0 : g_ktls = 1;
132 : 0 : break;
133 : 2 : case 'k':
134 : 2 : g_ktls = 0;
135 : 2 : break;
136 : 4 : case 'T':
137 : 4 : g_tls_version = spdk_strtol(arg, 10);
138 [ - + ]: 4 : if (g_tls_version < 0) {
139 [ # # ]: 0 : fprintf(stderr, "Invalid TLS version\n");
140 : 0 : return g_tls_version;
141 : : }
142 : 4 : break;
143 : 0 : case 'V':
144 : 0 : g_verbose = true;
145 : 0 : break;
146 : 2 : case 'Z':
147 : 2 : g_zcopy = 1;
148 : 2 : break;
149 : 2 : case 'z':
150 : 2 : g_zcopy = 0;
151 : 2 : break;
152 : 0 : default:
153 : 0 : return -EINVAL;
154 : : }
155 : 112 : return 0;
156 : : }
157 : :
158 : : static int
159 : 20 : hello_sock_close_timeout_poll(void *arg)
160 : : {
161 : 20 : struct hello_context_t *ctx = arg;
162 : 20 : SPDK_NOTICELOG("Connection closed\n");
163 : :
164 : 20 : spdk_poller_unregister(&ctx->time_out);
165 : 20 : spdk_poller_unregister(&ctx->poller_in);
166 : 20 : spdk_sock_close(&ctx->sock);
167 : 20 : spdk_sock_group_close(&ctx->group);
168 : :
169 : 20 : spdk_app_stop(ctx->rc);
170 : 20 : return SPDK_POLLER_BUSY;
171 : : }
172 : :
173 : : static int
174 : 4016 : hello_sock_quit(struct hello_context_t *ctx, int rc)
175 : : {
176 : 4016 : ctx->rc = rc;
177 : 4016 : spdk_poller_unregister(&ctx->poller_out);
178 [ + + ]: 4016 : if (!ctx->time_out) {
179 : 20 : ctx->time_out = SPDK_POLLER_REGISTER(hello_sock_close_timeout_poll, ctx,
180 : : CLOSE_TIMEOUT_US);
181 : : }
182 : 4016 : return 0;
183 : : }
184 : :
185 : : static int
186 : 8393171 : hello_sock_recv_poll(void *arg)
187 : : {
188 : 8393171 : struct hello_context_t *ctx = arg;
189 : : int rc;
190 : 0 : char buf_in[BUFFER_SIZE];
191 : :
192 : : /*
193 : : * Get response
194 : : */
195 : 8393171 : rc = spdk_sock_recv(ctx->sock, buf_in, sizeof(buf_in) - 1);
196 : :
197 [ + + ]: 8393171 : if (rc <= 0) {
198 [ + + - + ]: 8393159 : if (errno == EAGAIN || errno == EWOULDBLOCK) {
199 : 5714800 : return SPDK_POLLER_IDLE;
200 : : }
201 : :
202 : : /* This poller drains recv buffer until hello_sock_close_timeout_poll()
203 : : * runs out. Which starts when hello_sock_quit() is called.
204 : : * Quit the application just once, then patiently await the unregister. */
205 [ + + ]: 2678359 : if (ctx->rc == 0) {
206 : 2 : hello_sock_quit(ctx, -1);
207 : : }
208 [ + + - + ]: 2678359 : SPDK_ERRLOG_RATELIMIT("spdk_sock_recv() failed, errno %d: %s\n",
209 : : errno, spdk_strerror(errno));
210 : 2678359 : return SPDK_POLLER_BUSY;
211 : : }
212 : :
213 [ + - ]: 12 : if (rc > 0) {
214 : 12 : ctx->bytes_in += rc;
215 : 12 : buf_in[rc] = '\0';
216 : 12 : printf("%s", buf_in);
217 : : }
218 : :
219 : 12 : return SPDK_POLLER_BUSY;
220 : : }
221 : :
222 : : static int
223 : 525 : hello_sock_writev_poll(void *arg)
224 : : {
225 : 525 : struct hello_context_t *ctx = arg;
226 : 525 : int rc = 0;
227 : 0 : struct iovec iov;
228 : : ssize_t n;
229 : :
230 : : /* If previously we could not send any bytes, we should try again with the same buffer. */
231 [ + + ]: 525 : if (ctx->n != 0) {
232 : 503 : iov.iov_base = ctx->buf;
233 : 503 : iov.iov_len = ctx->n;
234 : 503 : errno = 0;
235 : 503 : rc = spdk_sock_writev(ctx->sock, &iov, 1);
236 [ + + ]: 503 : if (rc < 0) {
237 [ + + ]: 497 : if (errno == EAGAIN) {
238 : 495 : return SPDK_POLLER_BUSY;
239 : : }
240 : 2 : SPDK_ERRLOG("Write to socket failed. Closing connection...\n");
241 : 2 : hello_sock_quit(ctx, -1);
242 : 2 : return SPDK_POLLER_IDLE;
243 : : }
244 : 6 : ctx->bytes_out += rc;
245 : 6 : ctx->n = 0;
246 : : }
247 : :
248 : 28 : n = read(STDIN_FILENO, ctx->buf, BUFFER_SIZE);
249 [ + + - + : 28 : if (n == 0 || !g_is_running) {
- + ]
250 : : /* EOF */
251 : 12 : SPDK_NOTICELOG("Closing connection...\n");
252 : 12 : hello_sock_quit(ctx, 0);
253 : 12 : return SPDK_POLLER_IDLE;
254 : : }
255 [ + - ]: 16 : if (n > 0) {
256 : : /*
257 : : * Send message to the server
258 : : */
259 : 16 : iov.iov_base = ctx->buf;
260 : 16 : iov.iov_len = n;
261 : 16 : errno = 0;
262 : 16 : rc = spdk_sock_writev(ctx->sock, &iov, 1);
263 [ + + ]: 16 : if (rc < 0) {
264 [ + - ]: 10 : if (errno == EAGAIN) {
265 : 10 : ctx->n = n;
266 : : } else {
267 : 0 : SPDK_ERRLOG("Write to socket failed. Closing connection...\n");
268 : 0 : hello_sock_quit(ctx, -1);
269 : 0 : return SPDK_POLLER_IDLE;
270 : : }
271 : : }
272 [ + + ]: 16 : if (rc > 0) {
273 : 6 : ctx->bytes_out += rc;
274 : : }
275 : : }
276 : :
277 : 16 : return rc > 0 ? SPDK_POLLER_BUSY : SPDK_POLLER_IDLE;
278 : : }
279 : :
280 : : static int
281 : 18 : hello_sock_connect(struct hello_context_t *ctx)
282 : : {
283 : : int rc;
284 : 0 : char saddr[ADDR_STR_LEN], caddr[ADDR_STR_LEN];
285 : 0 : uint16_t cport, sport;
286 : 0 : struct spdk_sock_impl_opts impl_opts;
287 : 18 : size_t impl_opts_size = sizeof(impl_opts);
288 : 0 : struct spdk_sock_opts opts;
289 : :
290 : 18 : spdk_sock_impl_get_opts(ctx->sock_impl_name, &impl_opts, &impl_opts_size);
291 : 18 : impl_opts.enable_ktls = ctx->ktls;
292 : 18 : impl_opts.tls_version = ctx->tls_version;
293 : 18 : impl_opts.psk_identity = ctx->psk_identity;
294 : 18 : impl_opts.tls_cipher_suites = "TLS_AES_128_GCM_SHA256";
295 : 18 : impl_opts.psk_key = ctx->psk_key;
296 : 18 : impl_opts.psk_key_size = ctx->psk_key_size;
297 : :
298 : 18 : opts.opts_size = sizeof(opts);
299 : 18 : spdk_sock_get_default_opts(&opts);
300 : 18 : opts.zcopy = ctx->zcopy;
301 : 18 : opts.impl_opts = &impl_opts;
302 : 18 : opts.impl_opts_size = sizeof(impl_opts);
303 : :
304 : 18 : SPDK_NOTICELOG("Connecting to the server on %s:%d with sock_impl(%s)\n", ctx->host, ctx->port,
305 : : ctx->sock_impl_name);
306 : :
307 : 18 : ctx->sock = spdk_sock_connect_ext(ctx->host, ctx->port, ctx->sock_impl_name, &opts);
308 [ + + ]: 18 : if (ctx->sock == NULL) {
309 : 2 : SPDK_ERRLOG("connect error(%d): %s\n", errno, spdk_strerror(errno));
310 : 2 : return -1;
311 : : }
312 : :
313 : 16 : rc = spdk_sock_getaddr(ctx->sock, saddr, sizeof(saddr), &sport, caddr, sizeof(caddr), &cport);
314 [ - + ]: 16 : if (rc < 0) {
315 : 0 : SPDK_ERRLOG("Cannot get connection addresses\n");
316 : 0 : goto err;
317 : : }
318 : :
319 : 16 : SPDK_NOTICELOG("Connection accepted from (%s, %hu) to (%s, %hu)\n", caddr, cport, saddr, sport);
320 : :
321 : 16 : rc = fcntl(STDIN_FILENO, F_GETFL);
322 [ - + ]: 16 : if (rc == -1) {
323 : 0 : SPDK_ERRLOG("Getting file status flag failed: %s\n", strerror(errno));
324 : 0 : goto err;
325 : : }
326 : :
327 [ - + ]: 16 : if (fcntl(STDIN_FILENO, F_SETFL, rc | O_NONBLOCK) == -1) {
328 : 0 : SPDK_ERRLOG("Setting file status flag failed: %s\n", strerror(errno));
329 : 0 : goto err;
330 : : }
331 : :
332 : 16 : g_is_running = true;
333 : 16 : ctx->poller_in = SPDK_POLLER_REGISTER(hello_sock_recv_poll, ctx, 0);
334 : 16 : ctx->poller_out = SPDK_POLLER_REGISTER(hello_sock_writev_poll, ctx, 0);
335 : :
336 : 16 : return 0;
337 : 0 : err:
338 : 0 : spdk_sock_close(&ctx->sock);
339 : 0 : return -1;
340 : : }
341 : :
342 : : static void
343 : 37 : hello_sock_cb(void *arg, struct spdk_sock_group *group, struct spdk_sock *sock)
344 : : {
345 : : int rc;
346 : 37 : struct hello_context_t *ctx = arg;
347 : 37 : struct iovec iov = {};
348 : : ssize_t n;
349 : 0 : void *user_ctx;
350 : :
351 : 37 : rc = spdk_sock_recv_next(sock, &iov.iov_base, &user_ctx);
352 [ + + ]: 37 : if (rc < 0) {
353 [ + + - + ]: 17 : if (errno == EAGAIN || errno == EWOULDBLOCK) {
354 : 21 : return;
355 : : }
356 : :
357 [ - + - - ]: 6 : if (errno != ENOTCONN && errno != ECONNRESET) {
358 : 0 : SPDK_ERRLOG("spdk_sock_recv_zcopy() failed, errno %d: %s\n",
359 : : errno, spdk_strerror(errno));
360 : : }
361 : : }
362 : :
363 [ + + ]: 26 : if (rc > 0) {
364 : 10 : iov.iov_len = rc;
365 : 10 : ctx->bytes_in += iov.iov_len;
366 : 10 : n = spdk_sock_writev(sock, &iov, 1);
367 [ + - ]: 10 : if (n > 0) {
368 [ - + ]: 10 : assert(n == rc);
369 : 10 : ctx->bytes_out += n;
370 : : }
371 : :
372 : 10 : spdk_sock_group_provide_buf(ctx->group, iov.iov_base, BUFFER_SIZE, NULL);
373 : 10 : return;
374 : : }
375 : :
376 : : /* Connection closed */
377 : 16 : SPDK_NOTICELOG("Connection closed\n");
378 : 16 : spdk_sock_group_remove_sock(group, sock);
379 : 16 : spdk_sock_close(&sock);
380 : : }
381 : :
382 : : static int
383 : 22921 : hello_sock_accept_poll(void *arg)
384 : : {
385 : 22921 : struct hello_context_t *ctx = arg;
386 : 0 : struct spdk_sock *sock;
387 : : int rc;
388 : 22921 : int count = 0;
389 : 0 : char saddr[ADDR_STR_LEN], caddr[ADDR_STR_LEN];
390 : 0 : uint16_t cport, sport;
391 : :
392 [ - + + + ]: 22921 : if (!g_is_running) {
393 : 4000 : hello_sock_quit(ctx, 0);
394 : 4000 : return SPDK_POLLER_IDLE;
395 : : }
396 : :
397 : : while (1) {
398 : 18937 : sock = spdk_sock_accept(ctx->sock);
399 [ + + ]: 18937 : if (sock != NULL) {
400 : 16 : rc = spdk_sock_getaddr(sock, saddr, sizeof(saddr), &sport, caddr, sizeof(caddr), &cport);
401 [ - + ]: 16 : if (rc < 0) {
402 : 0 : SPDK_ERRLOG("Cannot get connection addresses\n");
403 : 0 : spdk_sock_close(&sock);
404 : 0 : return SPDK_POLLER_IDLE;
405 : : }
406 : :
407 : 16 : SPDK_NOTICELOG("Accepting a new connection from (%s, %hu) to (%s, %hu)\n",
408 : : caddr, cport, saddr, sport);
409 : :
410 : 16 : rc = spdk_sock_group_add_sock(ctx->group, sock,
411 : : hello_sock_cb, ctx);
412 : :
413 [ - + ]: 16 : if (rc < 0) {
414 : 0 : spdk_sock_close(&sock);
415 : 0 : SPDK_ERRLOG("failed\n");
416 : 0 : break;
417 : : }
418 : :
419 : 16 : count++;
420 : : } else {
421 [ - + - - ]: 18921 : if (errno != EAGAIN && errno != EWOULDBLOCK) {
422 : 0 : SPDK_ERRLOG("accept error(%d): %s\n", errno, spdk_strerror(errno));
423 : : }
424 : 18921 : break;
425 : : }
426 : : }
427 : :
428 : 18921 : return count > 0 ? SPDK_POLLER_BUSY : SPDK_POLLER_IDLE;
429 : : }
430 : :
431 : : static int
432 : 12351937 : hello_sock_group_poll(void *arg)
433 : : {
434 : 12351937 : struct hello_context_t *ctx = arg;
435 : : int rc;
436 : :
437 : 12351937 : rc = spdk_sock_group_poll(ctx->group);
438 [ - + ]: 12351937 : if (rc < 0) {
439 : 0 : SPDK_ERRLOG("Failed to poll sock_group=%p\n", ctx->group);
440 : : }
441 : :
442 : 12351937 : return rc > 0 ? SPDK_POLLER_BUSY : SPDK_POLLER_IDLE;
443 : : }
444 : :
445 : : static int
446 : 4 : hello_sock_listen(struct hello_context_t *ctx)
447 : : {
448 : 0 : struct spdk_sock_impl_opts impl_opts;
449 : 4 : size_t impl_opts_size = sizeof(impl_opts);
450 : 0 : struct spdk_sock_opts opts;
451 : :
452 : 4 : spdk_sock_impl_get_opts(ctx->sock_impl_name, &impl_opts, &impl_opts_size);
453 : 4 : impl_opts.enable_ktls = ctx->ktls;
454 : 4 : impl_opts.tls_version = ctx->tls_version;
455 : 4 : impl_opts.psk_identity = ctx->psk_identity;
456 : 4 : impl_opts.tls_cipher_suites = "TLS_AES_128_GCM_SHA256";
457 : 4 : impl_opts.psk_key = ctx->psk_key;
458 : 4 : impl_opts.psk_key_size = ctx->psk_key_size;
459 : :
460 : 4 : opts.opts_size = sizeof(opts);
461 : 4 : spdk_sock_get_default_opts(&opts);
462 : 4 : opts.zcopy = ctx->zcopy;
463 : 4 : opts.impl_opts = &impl_opts;
464 : 4 : opts.impl_opts_size = sizeof(impl_opts);
465 : :
466 : 4 : ctx->sock = spdk_sock_listen_ext(ctx->host, ctx->port, ctx->sock_impl_name, &opts);
467 [ - + ]: 4 : if (ctx->sock == NULL) {
468 : 0 : SPDK_ERRLOG("Cannot create server socket\n");
469 : 0 : return -1;
470 : : }
471 : :
472 : 4 : SPDK_NOTICELOG("Listening connection on %s:%d with sock_impl(%s)\n", ctx->host, ctx->port,
473 : : ctx->sock_impl_name);
474 : :
475 : : /*
476 : : * Create sock group for server socket
477 : : */
478 : 4 : ctx->group = spdk_sock_group_create(NULL);
479 [ - + ]: 4 : if (ctx->group == NULL) {
480 : 0 : SPDK_ERRLOG("Cannot create sock group\n");
481 : 0 : spdk_sock_close(&ctx->sock);
482 : 0 : return -1;
483 : : }
484 : :
485 : 4 : spdk_sock_group_provide_buf(ctx->group, ctx->buf, BUFFER_SIZE, NULL);
486 : :
487 : 4 : g_is_running = true;
488 : :
489 : : /*
490 : : * Start acceptor and group poller
491 : : */
492 : 4 : ctx->poller_in = SPDK_POLLER_REGISTER(hello_sock_accept_poll, ctx,
493 : : ACCEPT_TIMEOUT_US);
494 : 4 : ctx->poller_out = SPDK_POLLER_REGISTER(hello_sock_group_poll, ctx, 0);
495 : :
496 : 4 : return 0;
497 : : }
498 : :
499 : : static void
500 : 4 : hello_sock_shutdown_cb(void)
501 : : {
502 : 4 : g_is_running = false;
503 : 4 : }
504 : :
505 : : /*
506 : : * Our initial event that kicks off everything from main().
507 : : */
508 : : static void
509 : 22 : hello_start(void *arg1)
510 : : {
511 : 22 : struct hello_context_t *ctx = arg1;
512 : : int rc;
513 : :
514 : 22 : SPDK_NOTICELOG("Successfully started the application\n");
515 : :
516 [ - + + + ]: 22 : if (ctx->is_server) {
517 : 4 : rc = hello_sock_listen(ctx);
518 : : } else {
519 : 18 : rc = hello_sock_connect(ctx);
520 : : }
521 : :
522 [ + + ]: 22 : if (rc) {
523 : 2 : spdk_app_stop(-1);
524 : 2 : return;
525 : : }
526 : : }
527 : :
528 : : int
529 : 22 : main(int argc, char **argv)
530 : : {
531 : 22 : struct spdk_app_opts opts = {};
532 : 22 : int rc = 0;
533 : 22 : struct hello_context_t hello_context = {};
534 : :
535 : : /* Set default values in opts structure. */
536 : 22 : spdk_app_opts_init(&opts, sizeof(opts));
537 : 22 : opts.name = "hello_sock";
538 : 22 : opts.shutdown_cb = hello_sock_shutdown_cb;
539 : 22 : opts.rpc_addr = NULL;
540 : :
541 [ - + ]: 22 : if ((rc = spdk_app_parse_args(argc, argv, &opts, "E:H:I:kKN:P:ST:VzZ", NULL, hello_sock_parse_arg,
542 : : hello_sock_usage)) != SPDK_APP_PARSE_ARGS_SUCCESS) {
543 : 0 : exit(rc);
544 : : }
545 [ - + ]: 22 : hello_context.is_server = g_is_server;
546 : 22 : hello_context.host = g_host;
547 : 22 : hello_context.sock_impl_name = g_sock_impl_name;
548 : 22 : hello_context.port = g_port;
549 : 22 : hello_context.zcopy = g_zcopy;
550 : 22 : hello_context.ktls = g_ktls;
551 : 22 : hello_context.tls_version = g_tls_version;
552 : 22 : hello_context.psk_key = g_psk_key;
553 : 22 : hello_context.psk_key_size = g_psk_key_size;
554 : 22 : hello_context.psk_identity = g_psk_identity;
555 [ - + ]: 22 : hello_context.verbose = g_verbose;
556 : :
557 [ - + ]: 22 : if (hello_context.sock_impl_name == NULL) {
558 : 0 : hello_context.sock_impl_name = spdk_sock_get_default_impl();
559 : :
560 [ # # ]: 0 : if (hello_context.sock_impl_name == NULL) {
561 : 0 : SPDK_ERRLOG("No sock implementations available!\n");
562 : 0 : exit(-1);
563 : : }
564 : : }
565 : :
566 : 22 : hello_context.buf = calloc(1, BUFFER_SIZE);
567 [ - + ]: 22 : if (hello_context.buf == NULL) {
568 : 0 : SPDK_ERRLOG("Cannot allocate memory for hello_context buffer\n");
569 : 0 : exit(-1);
570 : : }
571 : 22 : hello_context.n = 0;
572 : :
573 [ - + + + ]: 22 : if (hello_context.is_server) {
574 : 4 : struct spdk_sock_impl_opts impl_opts = {};
575 : 4 : size_t len = sizeof(impl_opts);
576 : :
577 : 4 : rc = spdk_sock_impl_get_opts(hello_context.sock_impl_name, &impl_opts, &len);
578 [ - + ]: 4 : if (rc < 0) {
579 : 0 : free(hello_context.buf);
580 : 0 : exit(rc);
581 : : }
582 : :
583 : : /* Our applications will post buffers to be used for receiving. That feature
584 : : * is mutually exclusive with the recv pipe, so we need to disable it. */
585 : 4 : impl_opts.enable_recv_pipe = false;
586 : 4 : spdk_sock_impl_set_opts(hello_context.sock_impl_name, &impl_opts, len);
587 : : }
588 : :
589 : 22 : rc = spdk_app_start(&opts, hello_start, &hello_context);
590 [ + + ]: 22 : if (rc) {
591 : 6 : SPDK_ERRLOG("ERROR starting application\n");
592 : : }
593 : :
594 : 22 : SPDK_NOTICELOG("Exiting from application\n");
595 : :
596 [ - + - + ]: 22 : if (hello_context.verbose) {
597 [ # # ]: 0 : printf("** %d bytes received, %d bytes sent **\n",
598 : : hello_context.bytes_in, hello_context.bytes_out);
599 : : }
600 : :
601 : : /* Gracefully close out all of the SPDK subsystems. */
602 : 22 : spdk_app_fini();
603 : 22 : free(hello_context.buf);
604 : 22 : return rc;
605 : : }
|