LCOV - code coverage report
Current view: top level - spdk/examples/sock/hello_world - hello_sock.c (source / functions) Hit Total Coverage
Test: Combined Lines: 247 325 76.0 %
Date: 2024-07-13 03:51:15 Functions: 13 14 92.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 84 163 51.5 %

           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                 :     303637 : hello_sock_quit(struct hello_context_t *ctx, int rc)
     175                 :            : {
     176                 :     303637 :         ctx->rc = rc;
     177                 :     303637 :         spdk_poller_unregister(&ctx->poller_out);
     178         [ +  + ]:     303637 :         if (!ctx->time_out) {
     179                 :         20 :                 ctx->time_out = SPDK_POLLER_REGISTER(hello_sock_close_timeout_poll, ctx,
     180                 :            :                                                      CLOSE_TIMEOUT_US);
     181                 :            :         }
     182                 :     303637 :         return 0;
     183                 :            : }
     184                 :            : 
     185                 :            : static int
     186                 :    6952860 : hello_sock_recv_poll(void *arg)
     187                 :            : {
     188                 :    6952860 :         struct hello_context_t *ctx = arg;
     189                 :            :         int rc;
     190                 :          0 :         char buf_in[BUFFER_SIZE];
     191                 :            : 
     192                 :            :         /*
     193                 :            :          * Get response
     194                 :            :          */
     195                 :    6952860 :         rc = spdk_sock_recv(ctx->sock, buf_in, sizeof(buf_in) - 1);
     196                 :            : 
     197         [ +  + ]:    6952860 :         if (rc <= 0) {
     198   [ +  +  -  + ]:    6952848 :                 if (errno == EAGAIN || errno == EWOULDBLOCK) {
     199                 :    6653225 :                         return SPDK_POLLER_IDLE;
     200                 :            :                 }
     201                 :            : 
     202                 :     299623 :                 hello_sock_quit(ctx, -1);
     203                 :     299623 :                 SPDK_ERRLOG("spdk_sock_recv() failed, errno %d: %s\n",
     204                 :            :                             errno, spdk_strerror(errno));
     205                 :     299623 :                 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                 :        581 : hello_sock_writev_poll(void *arg)
     219                 :            : {
     220                 :        581 :         struct hello_context_t *ctx = arg;
     221                 :        581 :         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         [ +  + ]:        581 :         if (ctx->n != 0) {
     227                 :        559 :                 iov.iov_base = ctx->buf;
     228                 :        559 :                 iov.iov_len = ctx->n;
     229                 :        559 :                 errno = 0;
     230                 :        559 :                 rc = spdk_sock_writev(ctx->sock, &iov, 1);
     231         [ +  + ]:        559 :                 if (rc < 0) {
     232         [ +  + ]:        553 :                         if (errno == EAGAIN) {
     233                 :        549 :                                 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                 :         36 : hello_sock_cb(void *arg, struct spdk_sock_group *group, struct spdk_sock *sock)
     339                 :            : {
     340                 :            :         int rc;
     341                 :         36 :         struct hello_context_t *ctx = arg;
     342                 :         36 :         struct iovec iov = {};
     343                 :            :         ssize_t n;
     344                 :          0 :         void *user_ctx;
     345                 :            : 
     346                 :         36 :         rc = spdk_sock_recv_next(sock, &iov.iov_base, &user_ctx);
     347         [ +  + ]:         36 :         if (rc < 0) {
     348   [ +  +  -  + ]:         16 :                 if (errno == EAGAIN || errno == EWOULDBLOCK) {
     349                 :         20 :                         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                 :      22978 : hello_sock_accept_poll(void *arg)
     379                 :            : {
     380                 :      22978 :         struct hello_context_t *ctx = arg;
     381                 :          0 :         struct spdk_sock *sock;
     382                 :            :         int rc;
     383                 :      22978 :         int count = 0;
     384                 :          0 :         char saddr[ADDR_STR_LEN], caddr[ADDR_STR_LEN];
     385                 :          0 :         uint16_t cport, sport;
     386                 :            : 
     387   [ -  +  +  + ]:      22978 :         if (!g_is_running) {
     388                 :       3998 :                 hello_sock_quit(ctx, 0);
     389                 :       3998 :                 return SPDK_POLLER_IDLE;
     390                 :            :         }
     391                 :            : 
     392                 :            :         while (1) {
     393                 :      18996 :                 sock = spdk_sock_accept(ctx->sock);
     394         [ +  + ]:      18996 :                 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   [ -  +  -  - ]:      18980 :                         if (errno != EAGAIN && errno != EWOULDBLOCK) {
     417                 :          0 :                                 SPDK_ERRLOG("accept error(%d): %s\n", errno, spdk_strerror(errno));
     418                 :            :                         }
     419                 :      18980 :                         break;
     420                 :            :                 }
     421                 :            :         }
     422                 :            : 
     423                 :      18980 :         return count > 0 ? SPDK_POLLER_BUSY : SPDK_POLLER_IDLE;
     424                 :            : }
     425                 :            : 
     426                 :            : static int
     427                 :   13146228 : hello_sock_group_poll(void *arg)
     428                 :            : {
     429                 :   13146228 :         struct hello_context_t *ctx = arg;
     430                 :            :         int rc;
     431                 :            : 
     432                 :   13146228 :         rc = spdk_sock_group_poll(ctx->group);
     433         [ -  + ]:   13146228 :         if (rc < 0) {
     434                 :          0 :                 SPDK_ERRLOG("Failed to poll sock_group=%p\n", ctx->group);
     435                 :            :         }
     436                 :            : 
     437                 :   13146228 :         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                 :            : }

Generated by: LCOV version 1.14