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 : 207003 : hello_sock_quit(struct hello_context_t *ctx, int rc)
175 : : {
176 : 207003 : ctx->rc = rc;
177 : 207003 : spdk_poller_unregister(&ctx->poller_out);
178 [ + + ]: 207003 : if (!ctx->time_out) {
179 : 20 : ctx->time_out = SPDK_POLLER_REGISTER(hello_sock_close_timeout_poll, ctx,
180 : : CLOSE_TIMEOUT_US);
181 : : }
182 : 207003 : return 0;
183 : : }
184 : :
185 : : static int
186 : 4808948 : hello_sock_recv_poll(void *arg)
187 : : {
188 : 4808948 : struct hello_context_t *ctx = arg;
189 : : int rc;
190 : 0 : char buf_in[BUFFER_SIZE];
191 : :
192 : : /*
193 : : * Get response
194 : : */
195 : 4808948 : rc = spdk_sock_recv(ctx->sock, buf_in, sizeof(buf_in) - 1);
196 : :
197 [ + + ]: 4808948 : if (rc <= 0) {
198 [ + + - + ]: 4808936 : if (errno == EAGAIN || errno == EWOULDBLOCK) {
199 : 4605949 : return SPDK_POLLER_IDLE;
200 : : }
201 : :
202 : 202987 : hello_sock_quit(ctx, -1);
203 : 202987 : SPDK_ERRLOG("spdk_sock_recv() failed, errno %d: %s\n",
204 : : errno, spdk_strerror(errno));
205 : 202987 : return SPDK_POLLER_BUSY;
206 : : }
207 : :
208 [ + - ]: 12 : if (rc > 0) {
209 : 12 : ctx->bytes_in += rc;
210 : 12 : buf_in[rc] = '\0';
211 : 12 : printf("%s", buf_in);
212 : : }
213 : :
214 : 12 : return SPDK_POLLER_BUSY;
215 : : }
216 : :
217 : : static int
218 : 480 : hello_sock_writev_poll(void *arg)
219 : : {
220 : 480 : struct hello_context_t *ctx = arg;
221 : 480 : int rc = 0;
222 : 0 : struct iovec iov;
223 : : ssize_t n;
224 : :
225 : : /* If previously we could not send any bytes, we should try again with the same buffer. */
226 [ + + ]: 480 : if (ctx->n != 0) {
227 : 458 : iov.iov_base = ctx->buf;
228 : 458 : iov.iov_len = ctx->n;
229 : 458 : errno = 0;
230 : 458 : rc = spdk_sock_writev(ctx->sock, &iov, 1);
231 [ + + ]: 458 : if (rc < 0) {
232 [ + + ]: 452 : if (errno == EAGAIN) {
233 : 448 : return SPDK_POLLER_BUSY;
234 : : }
235 : 4 : SPDK_ERRLOG("Write to socket failed. Closing connection...\n");
236 : 4 : hello_sock_quit(ctx, -1);
237 : 4 : return SPDK_POLLER_IDLE;
238 : : }
239 : 6 : ctx->bytes_out += rc;
240 : 6 : ctx->n = 0;
241 : : }
242 : :
243 : 28 : n = read(STDIN_FILENO, ctx->buf, BUFFER_SIZE);
244 [ + + - + : 28 : if (n == 0 || !g_is_running) {
- + ]
245 : : /* EOF */
246 : 12 : SPDK_NOTICELOG("Closing connection...\n");
247 : 12 : hello_sock_quit(ctx, 0);
248 : 12 : return SPDK_POLLER_IDLE;
249 : : }
250 [ + - ]: 16 : if (n > 0) {
251 : : /*
252 : : * Send message to the server
253 : : */
254 : 16 : iov.iov_base = ctx->buf;
255 : 16 : iov.iov_len = n;
256 : 16 : errno = 0;
257 : 16 : rc = spdk_sock_writev(ctx->sock, &iov, 1);
258 [ + + ]: 16 : if (rc < 0) {
259 [ + - ]: 10 : if (errno == EAGAIN) {
260 : 10 : ctx->n = n;
261 : : } else {
262 : 0 : SPDK_ERRLOG("Write to socket failed. Closing connection...\n");
263 : 0 : hello_sock_quit(ctx, -1);
264 : 0 : return SPDK_POLLER_IDLE;
265 : : }
266 : : }
267 [ + + ]: 16 : if (rc > 0) {
268 : 6 : ctx->bytes_out += rc;
269 : : }
270 : : }
271 : :
272 : 16 : return rc > 0 ? SPDK_POLLER_BUSY : SPDK_POLLER_IDLE;
273 : : }
274 : :
275 : : static int
276 : 18 : hello_sock_connect(struct hello_context_t *ctx)
277 : : {
278 : : int rc;
279 : 0 : char saddr[ADDR_STR_LEN], caddr[ADDR_STR_LEN];
280 : 0 : uint16_t cport, sport;
281 : 0 : struct spdk_sock_impl_opts impl_opts;
282 : 18 : size_t impl_opts_size = sizeof(impl_opts);
283 : 0 : struct spdk_sock_opts opts;
284 : :
285 : 18 : spdk_sock_impl_get_opts(ctx->sock_impl_name, &impl_opts, &impl_opts_size);
286 : 18 : impl_opts.enable_ktls = ctx->ktls;
287 : 18 : impl_opts.tls_version = ctx->tls_version;
288 : 18 : impl_opts.psk_identity = ctx->psk_identity;
289 : 18 : impl_opts.tls_cipher_suites = "TLS_AES_128_GCM_SHA256";
290 : 18 : impl_opts.psk_key = ctx->psk_key;
291 : 18 : impl_opts.psk_key_size = ctx->psk_key_size;
292 : :
293 : 18 : opts.opts_size = sizeof(opts);
294 : 18 : spdk_sock_get_default_opts(&opts);
295 : 18 : opts.zcopy = ctx->zcopy;
296 : 18 : opts.impl_opts = &impl_opts;
297 : 18 : opts.impl_opts_size = sizeof(impl_opts);
298 : :
299 : 18 : SPDK_NOTICELOG("Connecting to the server on %s:%d with sock_impl(%s)\n", ctx->host, ctx->port,
300 : : ctx->sock_impl_name);
301 : :
302 : 18 : ctx->sock = spdk_sock_connect_ext(ctx->host, ctx->port, ctx->sock_impl_name, &opts);
303 [ + + ]: 18 : if (ctx->sock == NULL) {
304 : 2 : SPDK_ERRLOG("connect error(%d): %s\n", errno, spdk_strerror(errno));
305 : 2 : return -1;
306 : : }
307 : :
308 : 16 : rc = spdk_sock_getaddr(ctx->sock, saddr, sizeof(saddr), &sport, caddr, sizeof(caddr), &cport);
309 [ - + ]: 16 : if (rc < 0) {
310 : 0 : SPDK_ERRLOG("Cannot get connection addresses\n");
311 : 0 : goto err;
312 : : }
313 : :
314 : 16 : SPDK_NOTICELOG("Connection accepted from (%s, %hu) to (%s, %hu)\n", caddr, cport, saddr, sport);
315 : :
316 : 16 : rc = fcntl(STDIN_FILENO, F_GETFL);
317 [ - + ]: 16 : if (rc == -1) {
318 : 0 : SPDK_ERRLOG("Getting file status flag failed: %s\n", strerror(errno));
319 : 0 : goto err;
320 : : }
321 : :
322 [ - + ]: 16 : if (fcntl(STDIN_FILENO, F_SETFL, rc | O_NONBLOCK) == -1) {
323 : 0 : SPDK_ERRLOG("Setting file status flag failed: %s\n", strerror(errno));
324 : 0 : goto err;
325 : : }
326 : :
327 : 16 : g_is_running = true;
328 : 16 : ctx->poller_in = SPDK_POLLER_REGISTER(hello_sock_recv_poll, ctx, 0);
329 : 16 : ctx->poller_out = SPDK_POLLER_REGISTER(hello_sock_writev_poll, ctx, 0);
330 : :
331 : 16 : return 0;
332 : 0 : err:
333 : 0 : spdk_sock_close(&ctx->sock);
334 : 0 : return -1;
335 : : }
336 : :
337 : : static void
338 : 35 : hello_sock_cb(void *arg, struct spdk_sock_group *group, struct spdk_sock *sock)
339 : : {
340 : : int rc;
341 : 35 : struct hello_context_t *ctx = arg;
342 : 35 : struct iovec iov = {};
343 : : ssize_t n;
344 : 0 : void *user_ctx;
345 : :
346 : 35 : rc = spdk_sock_recv_next(sock, &iov.iov_base, &user_ctx);
347 [ + + ]: 35 : if (rc < 0) {
348 [ + + - + ]: 15 : if (errno == EAGAIN || errno == EWOULDBLOCK) {
349 : 19 : return;
350 : : }
351 : :
352 [ - + - - ]: 6 : if (errno != ENOTCONN && errno != ECONNRESET) {
353 : 0 : SPDK_ERRLOG("spdk_sock_recv_zcopy() failed, errno %d: %s\n",
354 : : errno, spdk_strerror(errno));
355 : : }
356 : : }
357 : :
358 [ + + ]: 26 : if (rc > 0) {
359 : 10 : iov.iov_len = rc;
360 : 10 : ctx->bytes_in += iov.iov_len;
361 : 10 : n = spdk_sock_writev(sock, &iov, 1);
362 [ + - ]: 10 : if (n > 0) {
363 [ - + ]: 10 : assert(n == rc);
364 : 10 : ctx->bytes_out += n;
365 : : }
366 : :
367 : 10 : spdk_sock_group_provide_buf(ctx->group, iov.iov_base, BUFFER_SIZE, NULL);
368 : 10 : return;
369 : : }
370 : :
371 : : /* Connection closed */
372 : 16 : SPDK_NOTICELOG("Connection closed\n");
373 : 16 : spdk_sock_group_remove_sock(group, sock);
374 : 16 : spdk_sock_close(&sock);
375 : : }
376 : :
377 : : static int
378 : 23545 : hello_sock_accept_poll(void *arg)
379 : : {
380 : 23545 : struct hello_context_t *ctx = arg;
381 : 0 : struct spdk_sock *sock;
382 : : int rc;
383 : 23545 : int count = 0;
384 : 0 : char saddr[ADDR_STR_LEN], caddr[ADDR_STR_LEN];
385 : 0 : uint16_t cport, sport;
386 : :
387 [ - + + + ]: 23545 : if (!g_is_running) {
388 : 4000 : hello_sock_quit(ctx, 0);
389 : 4000 : return SPDK_POLLER_IDLE;
390 : : }
391 : :
392 : : while (1) {
393 : 19561 : sock = spdk_sock_accept(ctx->sock);
394 [ + + ]: 19561 : if (sock != NULL) {
395 : 16 : rc = spdk_sock_getaddr(sock, saddr, sizeof(saddr), &sport, caddr, sizeof(caddr), &cport);
396 [ - + ]: 16 : if (rc < 0) {
397 : 0 : SPDK_ERRLOG("Cannot get connection addresses\n");
398 : 0 : spdk_sock_close(&sock);
399 : 0 : return SPDK_POLLER_IDLE;
400 : : }
401 : :
402 : 16 : SPDK_NOTICELOG("Accepting a new connection from (%s, %hu) to (%s, %hu)\n",
403 : : caddr, cport, saddr, sport);
404 : :
405 : 16 : rc = spdk_sock_group_add_sock(ctx->group, sock,
406 : : hello_sock_cb, ctx);
407 : :
408 [ - + ]: 16 : if (rc < 0) {
409 : 0 : spdk_sock_close(&sock);
410 : 0 : SPDK_ERRLOG("failed\n");
411 : 0 : break;
412 : : }
413 : :
414 : 16 : count++;
415 : : } else {
416 [ - + - - ]: 19545 : if (errno != EAGAIN && errno != EWOULDBLOCK) {
417 : 0 : SPDK_ERRLOG("accept error(%d): %s\n", errno, spdk_strerror(errno));
418 : : }
419 : 19545 : break;
420 : : }
421 : : }
422 : :
423 : 19545 : return count > 0 ? SPDK_POLLER_BUSY : SPDK_POLLER_IDLE;
424 : : }
425 : :
426 : : static int
427 : 11047946 : hello_sock_group_poll(void *arg)
428 : : {
429 : 11047946 : struct hello_context_t *ctx = arg;
430 : : int rc;
431 : :
432 : 11047946 : rc = spdk_sock_group_poll(ctx->group);
433 [ - + ]: 11047946 : if (rc < 0) {
434 : 0 : SPDK_ERRLOG("Failed to poll sock_group=%p\n", ctx->group);
435 : : }
436 : :
437 : 11047946 : return rc > 0 ? SPDK_POLLER_BUSY : SPDK_POLLER_IDLE;
438 : : }
439 : :
440 : : static int
441 : 4 : hello_sock_listen(struct hello_context_t *ctx)
442 : : {
443 : 0 : struct spdk_sock_impl_opts impl_opts;
444 : 4 : size_t impl_opts_size = sizeof(impl_opts);
445 : 0 : struct spdk_sock_opts opts;
446 : :
447 : 4 : spdk_sock_impl_get_opts(ctx->sock_impl_name, &impl_opts, &impl_opts_size);
448 : 4 : impl_opts.enable_ktls = ctx->ktls;
449 : 4 : impl_opts.tls_version = ctx->tls_version;
450 : 4 : impl_opts.psk_identity = ctx->psk_identity;
451 : 4 : impl_opts.tls_cipher_suites = "TLS_AES_128_GCM_SHA256";
452 : 4 : impl_opts.psk_key = ctx->psk_key;
453 : 4 : impl_opts.psk_key_size = ctx->psk_key_size;
454 : :
455 : 4 : opts.opts_size = sizeof(opts);
456 : 4 : spdk_sock_get_default_opts(&opts);
457 : 4 : opts.zcopy = ctx->zcopy;
458 : 4 : opts.impl_opts = &impl_opts;
459 : 4 : opts.impl_opts_size = sizeof(impl_opts);
460 : :
461 : 4 : ctx->sock = spdk_sock_listen_ext(ctx->host, ctx->port, ctx->sock_impl_name, &opts);
462 [ - + ]: 4 : if (ctx->sock == NULL) {
463 : 0 : SPDK_ERRLOG("Cannot create server socket\n");
464 : 0 : return -1;
465 : : }
466 : :
467 : 4 : SPDK_NOTICELOG("Listening connection on %s:%d with sock_impl(%s)\n", ctx->host, ctx->port,
468 : : ctx->sock_impl_name);
469 : :
470 : : /*
471 : : * Create sock group for server socket
472 : : */
473 : 4 : ctx->group = spdk_sock_group_create(NULL);
474 [ - + ]: 4 : if (ctx->group == NULL) {
475 : 0 : SPDK_ERRLOG("Cannot create sock group\n");
476 : 0 : spdk_sock_close(&ctx->sock);
477 : 0 : return -1;
478 : : }
479 : :
480 : 4 : spdk_sock_group_provide_buf(ctx->group, ctx->buf, BUFFER_SIZE, NULL);
481 : :
482 : 4 : g_is_running = true;
483 : :
484 : : /*
485 : : * Start acceptor and group poller
486 : : */
487 : 4 : ctx->poller_in = SPDK_POLLER_REGISTER(hello_sock_accept_poll, ctx,
488 : : ACCEPT_TIMEOUT_US);
489 : 4 : ctx->poller_out = SPDK_POLLER_REGISTER(hello_sock_group_poll, ctx, 0);
490 : :
491 : 4 : return 0;
492 : : }
493 : :
494 : : static void
495 : 4 : hello_sock_shutdown_cb(void)
496 : : {
497 : 4 : g_is_running = false;
498 : 4 : }
499 : :
500 : : /*
501 : : * Our initial event that kicks off everything from main().
502 : : */
503 : : static void
504 : 22 : hello_start(void *arg1)
505 : : {
506 : 22 : struct hello_context_t *ctx = arg1;
507 : : int rc;
508 : :
509 : 22 : SPDK_NOTICELOG("Successfully started the application\n");
510 : :
511 [ - + + + ]: 22 : if (ctx->is_server) {
512 : 4 : rc = hello_sock_listen(ctx);
513 : : } else {
514 : 18 : rc = hello_sock_connect(ctx);
515 : : }
516 : :
517 [ + + ]: 22 : if (rc) {
518 : 2 : spdk_app_stop(-1);
519 : 2 : return;
520 : : }
521 : : }
522 : :
523 : : int
524 : 22 : main(int argc, char **argv)
525 : : {
526 : 22 : struct spdk_app_opts opts = {};
527 : 22 : int rc = 0;
528 : 22 : struct hello_context_t hello_context = {};
529 : :
530 : : /* Set default values in opts structure. */
531 : 22 : spdk_app_opts_init(&opts, sizeof(opts));
532 : 22 : opts.name = "hello_sock";
533 : 22 : opts.shutdown_cb = hello_sock_shutdown_cb;
534 : 22 : opts.rpc_addr = NULL;
535 : :
536 [ - + ]: 22 : if ((rc = spdk_app_parse_args(argc, argv, &opts, "E:H:I:kKN:P:ST:VzZ", NULL, hello_sock_parse_arg,
537 : : hello_sock_usage)) != SPDK_APP_PARSE_ARGS_SUCCESS) {
538 : 0 : exit(rc);
539 : : }
540 [ - + ]: 22 : hello_context.is_server = g_is_server;
541 : 22 : hello_context.host = g_host;
542 : 22 : hello_context.sock_impl_name = g_sock_impl_name;
543 : 22 : hello_context.port = g_port;
544 : 22 : hello_context.zcopy = g_zcopy;
545 : 22 : hello_context.ktls = g_ktls;
546 : 22 : hello_context.tls_version = g_tls_version;
547 : 22 : hello_context.psk_key = g_psk_key;
548 : 22 : hello_context.psk_key_size = g_psk_key_size;
549 : 22 : hello_context.psk_identity = g_psk_identity;
550 [ - + ]: 22 : hello_context.verbose = g_verbose;
551 : :
552 [ - + ]: 22 : if (hello_context.sock_impl_name == NULL) {
553 : 0 : hello_context.sock_impl_name = spdk_sock_get_default_impl();
554 : :
555 [ # # ]: 0 : if (hello_context.sock_impl_name == NULL) {
556 : 0 : SPDK_ERRLOG("No sock implementations available!\n");
557 : 0 : exit(-1);
558 : : }
559 : : }
560 : :
561 : 22 : hello_context.buf = calloc(1, BUFFER_SIZE);
562 [ - + ]: 22 : if (hello_context.buf == NULL) {
563 : 0 : SPDK_ERRLOG("Cannot allocate memory for hello_context buffer\n");
564 : 0 : exit(-1);
565 : : }
566 : 22 : hello_context.n = 0;
567 : :
568 [ - + + + ]: 22 : if (hello_context.is_server) {
569 : 4 : struct spdk_sock_impl_opts impl_opts = {};
570 : 4 : size_t len = sizeof(impl_opts);
571 : :
572 : 4 : rc = spdk_sock_impl_get_opts(hello_context.sock_impl_name, &impl_opts, &len);
573 [ - + ]: 4 : if (rc < 0) {
574 : 0 : free(hello_context.buf);
575 : 0 : exit(rc);
576 : : }
577 : :
578 : : /* Our applications will post buffers to be used for receiving. That feature
579 : : * is mutually exclusive with the recv pipe, so we need to disable it. */
580 : 4 : impl_opts.enable_recv_pipe = false;
581 : 4 : spdk_sock_impl_set_opts(hello_context.sock_impl_name, &impl_opts, len);
582 : : }
583 : :
584 : 22 : rc = spdk_app_start(&opts, hello_start, &hello_context);
585 [ + + ]: 22 : if (rc) {
586 : 6 : SPDK_ERRLOG("ERROR starting application\n");
587 : : }
588 : :
589 : 22 : SPDK_NOTICELOG("Exiting from application\n");
590 : :
591 [ - + - + ]: 22 : if (hello_context.verbose) {
592 [ # # ]: 0 : printf("** %d bytes received, %d bytes sent **\n",
593 : : hello_context.bytes_in, hello_context.bytes_out);
594 : : }
595 : :
596 : : /* Gracefully close out all of the SPDK subsystems. */
597 : 22 : spdk_app_fini();
598 : 22 : free(hello_context.buf);
599 : 22 : return rc;
600 : : }
|