1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. All rights reserved. 3 * Copyright (c) 2020, 2021 Mellanox Technologies LTD. All rights reserved. 4 * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5 */ 6 7 #include "spdk/stdinc.h" 8 9 #if defined(__FreeBSD__) 10 #include <sys/event.h> 11 #define SPDK_KEVENT 12 #else 13 #include <sys/epoll.h> 14 #define SPDK_EPOLL 15 #endif 16 17 #if defined(__linux__) 18 #include <linux/errqueue.h> 19 #endif 20 21 #include "spdk/env.h" 22 #include "spdk/log.h" 23 #include "spdk/pipe.h" 24 #include "spdk/sock.h" 25 #include "spdk/util.h" 26 #include "spdk/string.h" 27 #include "spdk_internal/sock.h" 28 #include "../sock_kernel.h" 29 30 #include "openssl/crypto.h" 31 #include "openssl/err.h" 32 #include "openssl/ssl.h" 33 34 #define MAX_TMPBUF 1024 35 #define PORTNUMLEN 32 36 37 #if defined(SO_ZEROCOPY) && defined(MSG_ZEROCOPY) 38 #define SPDK_ZEROCOPY 39 #endif 40 41 struct spdk_posix_sock { 42 struct spdk_sock base; 43 int fd; 44 45 uint32_t sendmsg_idx; 46 47 struct spdk_pipe *recv_pipe; 48 void *recv_buf; 49 int recv_buf_sz; 50 bool pipe_has_data; 51 bool socket_has_data; 52 bool zcopy; 53 54 int placement_id; 55 56 SSL_CTX *ctx; 57 SSL *ssl; 58 59 TAILQ_ENTRY(spdk_posix_sock) link; 60 }; 61 62 TAILQ_HEAD(spdk_has_data_list, spdk_posix_sock); 63 64 struct spdk_posix_sock_group_impl { 65 struct spdk_sock_group_impl base; 66 int fd; 67 struct spdk_has_data_list socks_with_data; 68 int placement_id; 69 }; 70 71 static struct spdk_sock_impl_opts g_spdk_posix_sock_impl_opts = { 72 .recv_buf_size = MIN_SO_RCVBUF_SIZE, 73 .send_buf_size = MIN_SO_SNDBUF_SIZE, 74 .enable_recv_pipe = true, 75 .enable_quickack = false, 76 .enable_placement_id = PLACEMENT_NONE, 77 .enable_zerocopy_send_server = true, 78 .enable_zerocopy_send_client = false, 79 .zerocopy_threshold = 0, 80 .tls_version = 0, 81 .enable_ktls = false 82 }; 83 84 static struct spdk_sock_map g_map = { 85 .entries = STAILQ_HEAD_INITIALIZER(g_map.entries), 86 .mtx = PTHREAD_MUTEX_INITIALIZER 87 }; 88 89 __attribute((destructor)) static void 90 posix_sock_map_cleanup(void) 91 { 92 spdk_sock_map_cleanup(&g_map); 93 } 94 95 #define __posix_sock(sock) (struct spdk_posix_sock *)sock 96 #define __posix_group_impl(group) (struct spdk_posix_sock_group_impl *)group 97 98 static void 99 posix_sock_copy_impl_opts(struct spdk_sock_impl_opts *dest, const struct spdk_sock_impl_opts *src, 100 size_t len) 101 { 102 #define FIELD_OK(field) \ 103 offsetof(struct spdk_sock_impl_opts, field) + sizeof(src->field) <= len 104 105 #define SET_FIELD(field) \ 106 if (FIELD_OK(field)) { \ 107 dest->field = src->field; \ 108 } 109 110 SET_FIELD(recv_buf_size); 111 SET_FIELD(send_buf_size); 112 SET_FIELD(enable_recv_pipe); 113 SET_FIELD(enable_zerocopy_send); 114 SET_FIELD(enable_quickack); 115 SET_FIELD(enable_placement_id); 116 SET_FIELD(enable_zerocopy_send_server); 117 SET_FIELD(enable_zerocopy_send_client); 118 SET_FIELD(zerocopy_threshold); 119 SET_FIELD(tls_version); 120 SET_FIELD(enable_ktls); 121 122 #undef SET_FIELD 123 #undef FIELD_OK 124 } 125 126 static int 127 posix_sock_impl_get_opts(struct spdk_sock_impl_opts *opts, size_t *len) 128 { 129 if (!opts || !len) { 130 errno = EINVAL; 131 return -1; 132 } 133 memset(opts, 0, *len); 134 135 posix_sock_copy_impl_opts(opts, &g_spdk_posix_sock_impl_opts, *len); 136 *len = spdk_min(*len, sizeof(g_spdk_posix_sock_impl_opts)); 137 138 return 0; 139 } 140 141 static int 142 posix_sock_impl_set_opts(const struct spdk_sock_impl_opts *opts, size_t len) 143 { 144 if (!opts) { 145 errno = EINVAL; 146 return -1; 147 } 148 149 posix_sock_copy_impl_opts(&g_spdk_posix_sock_impl_opts, opts, len); 150 151 return 0; 152 } 153 154 static void 155 posix_opts_get_impl_opts(const struct spdk_sock_opts *opts, struct spdk_sock_impl_opts *dest) 156 { 157 /* Copy the default impl_opts first to cover cases when user's impl_opts is smaller */ 158 memcpy(dest, &g_spdk_posix_sock_impl_opts, sizeof(*dest)); 159 160 if (opts->impl_opts != NULL) { 161 posix_sock_copy_impl_opts(dest, opts->impl_opts, opts->impl_opts_size); 162 } 163 } 164 165 static int 166 posix_sock_getaddr(struct spdk_sock *_sock, char *saddr, int slen, uint16_t *sport, 167 char *caddr, int clen, uint16_t *cport) 168 { 169 struct spdk_posix_sock *sock = __posix_sock(_sock); 170 struct sockaddr_storage sa; 171 socklen_t salen; 172 int rc; 173 174 assert(sock != NULL); 175 176 memset(&sa, 0, sizeof sa); 177 salen = sizeof sa; 178 rc = getsockname(sock->fd, (struct sockaddr *) &sa, &salen); 179 if (rc != 0) { 180 SPDK_ERRLOG("getsockname() failed (errno=%d)\n", errno); 181 return -1; 182 } 183 184 switch (sa.ss_family) { 185 case AF_UNIX: 186 /* Acceptable connection types that don't have IPs */ 187 return 0; 188 case AF_INET: 189 case AF_INET6: 190 /* Code below will get IP addresses */ 191 break; 192 default: 193 /* Unsupported socket family */ 194 return -1; 195 } 196 197 rc = get_addr_str((struct sockaddr *)&sa, saddr, slen); 198 if (rc != 0) { 199 SPDK_ERRLOG("getnameinfo() failed (errno=%d)\n", errno); 200 return -1; 201 } 202 203 if (sport) { 204 if (sa.ss_family == AF_INET) { 205 *sport = ntohs(((struct sockaddr_in *) &sa)->sin_port); 206 } else if (sa.ss_family == AF_INET6) { 207 *sport = ntohs(((struct sockaddr_in6 *) &sa)->sin6_port); 208 } 209 } 210 211 memset(&sa, 0, sizeof sa); 212 salen = sizeof sa; 213 rc = getpeername(sock->fd, (struct sockaddr *) &sa, &salen); 214 if (rc != 0) { 215 SPDK_ERRLOG("getpeername() failed (errno=%d)\n", errno); 216 return -1; 217 } 218 219 rc = get_addr_str((struct sockaddr *)&sa, caddr, clen); 220 if (rc != 0) { 221 SPDK_ERRLOG("getnameinfo() failed (errno=%d)\n", errno); 222 return -1; 223 } 224 225 if (cport) { 226 if (sa.ss_family == AF_INET) { 227 *cport = ntohs(((struct sockaddr_in *) &sa)->sin_port); 228 } else if (sa.ss_family == AF_INET6) { 229 *cport = ntohs(((struct sockaddr_in6 *) &sa)->sin6_port); 230 } 231 } 232 233 return 0; 234 } 235 236 enum posix_sock_create_type { 237 SPDK_SOCK_CREATE_LISTEN, 238 SPDK_SOCK_CREATE_CONNECT, 239 }; 240 241 static int 242 posix_sock_alloc_pipe(struct spdk_posix_sock *sock, int sz) 243 { 244 uint8_t *new_buf; 245 struct spdk_pipe *new_pipe; 246 struct iovec siov[2]; 247 struct iovec diov[2]; 248 int sbytes; 249 ssize_t bytes; 250 251 if (sock->recv_buf_sz == sz) { 252 return 0; 253 } 254 255 /* If the new size is 0, just free the pipe */ 256 if (sz == 0) { 257 spdk_pipe_destroy(sock->recv_pipe); 258 free(sock->recv_buf); 259 sock->recv_pipe = NULL; 260 sock->recv_buf = NULL; 261 return 0; 262 } else if (sz < MIN_SOCK_PIPE_SIZE) { 263 SPDK_ERRLOG("The size of the pipe must be larger than %d\n", MIN_SOCK_PIPE_SIZE); 264 return -1; 265 } 266 267 /* Round up to next 64 byte multiple */ 268 new_buf = calloc(SPDK_ALIGN_CEIL(sz + 1, 64), sizeof(uint8_t)); 269 if (!new_buf) { 270 SPDK_ERRLOG("socket recv buf allocation failed\n"); 271 return -ENOMEM; 272 } 273 274 new_pipe = spdk_pipe_create(new_buf, sz + 1); 275 if (new_pipe == NULL) { 276 SPDK_ERRLOG("socket pipe allocation failed\n"); 277 free(new_buf); 278 return -ENOMEM; 279 } 280 281 if (sock->recv_pipe != NULL) { 282 /* Pull all of the data out of the old pipe */ 283 sbytes = spdk_pipe_reader_get_buffer(sock->recv_pipe, sock->recv_buf_sz, siov); 284 if (sbytes > sz) { 285 /* Too much data to fit into the new pipe size */ 286 spdk_pipe_destroy(new_pipe); 287 free(new_buf); 288 return -EINVAL; 289 } 290 291 sbytes = spdk_pipe_writer_get_buffer(new_pipe, sz, diov); 292 assert(sbytes == sz); 293 294 bytes = spdk_iovcpy(siov, 2, diov, 2); 295 spdk_pipe_writer_advance(new_pipe, bytes); 296 297 spdk_pipe_destroy(sock->recv_pipe); 298 free(sock->recv_buf); 299 } 300 301 sock->recv_buf_sz = sz; 302 sock->recv_buf = new_buf; 303 sock->recv_pipe = new_pipe; 304 305 return 0; 306 } 307 308 static int 309 posix_sock_set_recvbuf(struct spdk_sock *_sock, int sz) 310 { 311 struct spdk_posix_sock *sock = __posix_sock(_sock); 312 int rc; 313 314 assert(sock != NULL); 315 316 if (_sock->impl_opts.enable_recv_pipe) { 317 rc = posix_sock_alloc_pipe(sock, sz); 318 if (rc) { 319 return rc; 320 } 321 } 322 323 /* Set kernel buffer size to be at least MIN_SO_RCVBUF_SIZE */ 324 if (sz < MIN_SO_RCVBUF_SIZE) { 325 sz = MIN_SO_RCVBUF_SIZE; 326 } 327 328 rc = setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz)); 329 if (rc < 0) { 330 return rc; 331 } 332 333 _sock->impl_opts.recv_buf_size = sz; 334 335 return 0; 336 } 337 338 static int 339 posix_sock_set_sendbuf(struct spdk_sock *_sock, int sz) 340 { 341 struct spdk_posix_sock *sock = __posix_sock(_sock); 342 int rc; 343 344 assert(sock != NULL); 345 346 if (sz < MIN_SO_SNDBUF_SIZE) { 347 sz = MIN_SO_SNDBUF_SIZE; 348 } 349 350 rc = setsockopt(sock->fd, SOL_SOCKET, SO_SNDBUF, &sz, sizeof(sz)); 351 if (rc < 0) { 352 return rc; 353 } 354 355 _sock->impl_opts.send_buf_size = sz; 356 357 return 0; 358 } 359 360 static void 361 posix_sock_init(struct spdk_posix_sock *sock, bool enable_zero_copy) 362 { 363 #if defined(SPDK_ZEROCOPY) || defined(__linux__) 364 int flag; 365 int rc; 366 #endif 367 368 #if defined(SPDK_ZEROCOPY) 369 flag = 1; 370 371 if (enable_zero_copy) { 372 /* Try to turn on zero copy sends */ 373 rc = setsockopt(sock->fd, SOL_SOCKET, SO_ZEROCOPY, &flag, sizeof(flag)); 374 if (rc == 0) { 375 sock->zcopy = true; 376 } 377 } 378 #endif 379 380 #if defined(__linux__) 381 flag = 1; 382 383 if (sock->base.impl_opts.enable_quickack) { 384 rc = setsockopt(sock->fd, IPPROTO_TCP, TCP_QUICKACK, &flag, sizeof(flag)); 385 if (rc != 0) { 386 SPDK_ERRLOG("quickack was failed to set\n"); 387 } 388 } 389 390 spdk_sock_get_placement_id(sock->fd, sock->base.impl_opts.enable_placement_id, 391 &sock->placement_id); 392 393 if (sock->base.impl_opts.enable_placement_id == PLACEMENT_MARK) { 394 /* Save placement_id */ 395 spdk_sock_map_insert(&g_map, sock->placement_id, NULL); 396 } 397 #endif 398 } 399 400 static struct spdk_posix_sock * 401 posix_sock_alloc(int fd, struct spdk_sock_impl_opts *impl_opts, bool enable_zero_copy) 402 { 403 struct spdk_posix_sock *sock; 404 405 sock = calloc(1, sizeof(*sock)); 406 if (sock == NULL) { 407 SPDK_ERRLOG("sock allocation failed\n"); 408 return NULL; 409 } 410 411 sock->fd = fd; 412 memcpy(&sock->base.impl_opts, impl_opts, sizeof(*impl_opts)); 413 posix_sock_init(sock, enable_zero_copy); 414 415 return sock; 416 } 417 418 static int 419 posix_fd_create(struct addrinfo *res, struct spdk_sock_opts *opts, 420 struct spdk_sock_impl_opts *impl_opts) 421 { 422 int fd; 423 int val = 1; 424 int rc, sz; 425 #if defined(__linux__) 426 int to; 427 #endif 428 429 fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 430 if (fd < 0) { 431 /* error */ 432 return -1; 433 } 434 435 sz = impl_opts->recv_buf_size; 436 rc = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz)); 437 if (rc) { 438 /* Not fatal */ 439 } 440 441 sz = impl_opts->send_buf_size; 442 rc = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sz, sizeof(sz)); 443 if (rc) { 444 /* Not fatal */ 445 } 446 447 rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val); 448 if (rc != 0) { 449 close(fd); 450 /* error */ 451 return -1; 452 } 453 rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof val); 454 if (rc != 0) { 455 close(fd); 456 /* error */ 457 return -1; 458 } 459 460 #if defined(SO_PRIORITY) 461 if (opts->priority) { 462 rc = setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &opts->priority, sizeof val); 463 if (rc != 0) { 464 close(fd); 465 /* error */ 466 return -1; 467 } 468 } 469 #endif 470 471 if (res->ai_family == AF_INET6) { 472 rc = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof val); 473 if (rc != 0) { 474 close(fd); 475 /* error */ 476 return -1; 477 } 478 } 479 480 if (opts->ack_timeout) { 481 #if defined(__linux__) 482 to = opts->ack_timeout; 483 rc = setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &to, sizeof(to)); 484 if (rc != 0) { 485 close(fd); 486 /* error */ 487 return -1; 488 } 489 #else 490 SPDK_WARNLOG("TCP_USER_TIMEOUT is not supported.\n"); 491 #endif 492 } 493 494 return fd; 495 } 496 497 #define PSK_ID "nqn.2014-08.org.nvmexpress:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6" 498 #define PSK_KEY "1234567890ABCDEF" 499 500 static unsigned int 501 posix_sock_tls_psk_server_cb(SSL *ssl, 502 const char *id, 503 unsigned char *psk, 504 unsigned int max_psk_len) 505 { 506 long key_len; 507 unsigned char *default_psk; 508 509 if (PSK_KEY == NULL) { 510 SPDK_ERRLOG("PSK is not set\n"); 511 goto err; 512 } 513 SPDK_DEBUGLOG(sock_posix, "Length of Client's PSK ID %lu\n", strlen(PSK_ID)); 514 if (id == NULL) { 515 SPDK_ERRLOG("Received empty PSK ID\n"); 516 goto err; 517 } 518 SPDK_DEBUGLOG(sock_posix, "Received PSK ID '%s'\n", id); 519 if (strcmp(PSK_ID, id) != 0) { 520 SPDK_ERRLOG("Unknown Client's PSK ID\n"); 521 goto err; 522 } 523 524 SPDK_DEBUGLOG(sock_posix, "Length of Client's PSK KEY %u\n", max_psk_len); 525 default_psk = OPENSSL_hexstr2buf(PSK_KEY, &key_len); 526 if (default_psk == NULL) { 527 SPDK_ERRLOG("Could not unhexlify PSK\n"); 528 goto err; 529 } 530 if (key_len > max_psk_len) { 531 SPDK_ERRLOG("Insufficient buffer size to copy PSK\n"); 532 goto err; 533 } 534 535 memcpy(psk, default_psk, key_len); 536 537 return key_len; 538 539 err: 540 return 0; 541 } 542 543 static unsigned int 544 posix_sock_tls_psk_client_cb(SSL *ssl, const char *hint, 545 char *identity, 546 unsigned int max_identity_len, 547 unsigned char *psk, 548 unsigned int max_psk_len) 549 { 550 long key_len; 551 unsigned char *default_psk; 552 553 if (hint) { 554 SPDK_DEBUGLOG(sock_posix, "Received PSK identity hint '%s'\n", hint); 555 } 556 557 if (PSK_KEY == NULL) { 558 SPDK_ERRLOG("PSK is not set\n"); 559 goto err; 560 } 561 default_psk = OPENSSL_hexstr2buf(PSK_KEY, &key_len); 562 if (default_psk == NULL) { 563 SPDK_ERRLOG("Could not unhexlify PSK\n"); 564 goto err; 565 } 566 if ((strlen(PSK_ID) + 1 > max_identity_len) 567 || (key_len > max_psk_len)) { 568 SPDK_ERRLOG("PSK ID or Key buffer is not sufficient\n"); 569 goto err; 570 } 571 spdk_strcpy_pad(identity, PSK_ID, strlen(PSK_ID), 0); 572 SPDK_DEBUGLOG(sock_posix, "Sending PSK identity '%s'\n", identity); 573 574 memcpy(psk, default_psk, key_len); 575 SPDK_DEBUGLOG(sock_posix, "Provided out-of-band (OOB) PSK for TLS1.3 client\n"); 576 577 return key_len; 578 579 err: 580 return 0; 581 } 582 583 static SSL_CTX * 584 posix_sock_create_ssl_context(const SSL_METHOD *method, struct spdk_sock_opts *opts, 585 struct spdk_sock_impl_opts *impl_opts) 586 { 587 SSL_CTX *ctx; 588 int tls_version = 0; 589 bool ktls_enabled = false; 590 #ifdef SSL_OP_ENABLE_KTLS 591 long options; 592 #endif 593 594 SSL_library_init(); 595 OpenSSL_add_all_algorithms(); 596 SSL_load_error_strings(); 597 /* Produce a SSL CTX in SSL V2 and V3 standards compliant way */ 598 ctx = SSL_CTX_new(method); 599 if (!ctx) { 600 SPDK_ERRLOG("SSL_CTX_new() failed, msg = %s\n", ERR_error_string(ERR_peek_last_error(), NULL)); 601 return NULL; 602 } 603 SPDK_DEBUGLOG(sock_posix, "SSL context created\n"); 604 605 switch (impl_opts->tls_version) { 606 case 0: 607 /* auto-negotioation */ 608 break; 609 case SPDK_TLS_VERSION_1_1: 610 tls_version = TLS1_1_VERSION; 611 break; 612 case SPDK_TLS_VERSION_1_2: 613 tls_version = TLS1_2_VERSION; 614 break; 615 case SPDK_TLS_VERSION_1_3: 616 tls_version = TLS1_3_VERSION; 617 break; 618 default: 619 SPDK_ERRLOG("Incorrect TLS version provided: %d\n", impl_opts->tls_version); 620 goto err; 621 } 622 623 if (tls_version) { 624 SPDK_DEBUGLOG(sock_posix, "Hardening TLS version to '%d'='0x%X'\n", impl_opts->tls_version, 625 tls_version); 626 if (!SSL_CTX_set_min_proto_version(ctx, tls_version)) { 627 SPDK_ERRLOG("Unable to set Min TLS version to '%d'='0x%X\n", impl_opts->tls_version, tls_version); 628 goto err; 629 } 630 if (!SSL_CTX_set_max_proto_version(ctx, tls_version)) { 631 SPDK_ERRLOG("Unable to set Max TLS version to '%d'='0x%X\n", impl_opts->tls_version, tls_version); 632 goto err; 633 } 634 } 635 if (impl_opts->enable_ktls) { 636 SPDK_DEBUGLOG(sock_posix, "Enabling kTLS offload\n"); 637 #ifdef SSL_OP_ENABLE_KTLS 638 options = SSL_CTX_set_options(ctx, SSL_OP_ENABLE_KTLS); 639 ktls_enabled = options & SSL_OP_ENABLE_KTLS; 640 #else 641 ktls_enabled = false; 642 #endif 643 if (!ktls_enabled) { 644 SPDK_ERRLOG("Unable to set kTLS offload via SSL_CTX_set_options(). Configure openssl with 'enable-ktls'\n"); 645 goto err; 646 } 647 } 648 649 return ctx; 650 651 err: 652 SSL_CTX_free(ctx); 653 return NULL; 654 } 655 656 static SSL * 657 ssl_sock_connect_loop(SSL_CTX *ctx, int fd) 658 { 659 int rc; 660 SSL *ssl; 661 int ssl_get_error; 662 663 ssl = SSL_new(ctx); 664 if (!ssl) { 665 SPDK_ERRLOG("SSL_new() failed, msg = %s\n", ERR_error_string(ERR_peek_last_error(), NULL)); 666 return NULL; 667 } 668 SSL_set_fd(ssl, fd); 669 SSL_set_psk_client_callback(ssl, posix_sock_tls_psk_client_cb); 670 SPDK_DEBUGLOG(sock_posix, "SSL object creation finished: %p\n", ssl); 671 SPDK_DEBUGLOG(sock_posix, "%s = SSL_state_string_long(%p)\n", SSL_state_string_long(ssl), ssl); 672 while ((rc = SSL_connect(ssl)) != 1) { 673 SPDK_DEBUGLOG(sock_posix, "%s = SSL_state_string_long(%p)\n", SSL_state_string_long(ssl), ssl); 674 ssl_get_error = SSL_get_error(ssl, rc); 675 SPDK_DEBUGLOG(sock_posix, "SSL_connect failed %d = SSL_connect(%p), %d = SSL_get_error(%p, %d)\n", 676 rc, ssl, ssl_get_error, ssl, rc); 677 switch (ssl_get_error) { 678 case SSL_ERROR_WANT_READ: 679 case SSL_ERROR_WANT_WRITE: 680 continue; 681 default: 682 break; 683 } 684 SPDK_ERRLOG("SSL_connect() failed, errno = %d\n", errno); 685 SSL_free(ssl); 686 return NULL; 687 } 688 SPDK_DEBUGLOG(sock_posix, "%s = SSL_state_string_long(%p)\n", SSL_state_string_long(ssl), ssl); 689 SPDK_DEBUGLOG(sock_posix, "Negotiated Cipher suite:%s\n", 690 SSL_CIPHER_get_name(SSL_get_current_cipher(ssl))); 691 return ssl; 692 } 693 694 static SSL * 695 ssl_sock_accept_loop(SSL_CTX *ctx, int fd) 696 { 697 int rc; 698 SSL *ssl; 699 int ssl_get_error; 700 701 ssl = SSL_new(ctx); 702 if (!ssl) { 703 SPDK_ERRLOG("SSL_new() failed, msg = %s\n", ERR_error_string(ERR_peek_last_error(), NULL)); 704 return NULL; 705 } 706 SSL_set_fd(ssl, fd); 707 SSL_set_psk_server_callback(ssl, posix_sock_tls_psk_server_cb); 708 SPDK_DEBUGLOG(sock_posix, "SSL object creation finished: %p\n", ssl); 709 SPDK_DEBUGLOG(sock_posix, "%s = SSL_state_string_long(%p)\n", SSL_state_string_long(ssl), ssl); 710 while ((rc = SSL_accept(ssl)) != 1) { 711 SPDK_DEBUGLOG(sock_posix, "%s = SSL_state_string_long(%p)\n", SSL_state_string_long(ssl), ssl); 712 ssl_get_error = SSL_get_error(ssl, rc); 713 SPDK_DEBUGLOG(sock_posix, "SSL_accept failed %d = SSL_accept(%p), %d = SSL_get_error(%p, %d)\n", rc, 714 ssl, ssl_get_error, ssl, rc); 715 switch (ssl_get_error) { 716 case SSL_ERROR_WANT_READ: 717 case SSL_ERROR_WANT_WRITE: 718 continue; 719 default: 720 break; 721 } 722 SPDK_ERRLOG("SSL_accept() failed, errno = %d\n", errno); 723 SSL_free(ssl); 724 return NULL; 725 } 726 SPDK_DEBUGLOG(sock_posix, "%s = SSL_state_string_long(%p)\n", SSL_state_string_long(ssl), ssl); 727 SPDK_DEBUGLOG(sock_posix, "Negotiated Cipher suite:%s\n", 728 SSL_CIPHER_get_name(SSL_get_current_cipher(ssl))); 729 return ssl; 730 } 731 732 static ssize_t 733 SSL_readv(SSL *ssl, const struct iovec *iov, int iovcnt) 734 { 735 int i, rc = 0; 736 ssize_t total = 0; 737 738 for (i = 0; i < iovcnt; i++) { 739 rc = SSL_read(ssl, iov[i].iov_base, iov[i].iov_len); 740 741 if (rc > 0) { 742 total += rc; 743 } 744 if (rc != (int)iov[i].iov_len) { 745 break; 746 } 747 } 748 if (total > 0) { 749 errno = 0; 750 return total; 751 } 752 switch (SSL_get_error(ssl, rc)) { 753 case SSL_ERROR_ZERO_RETURN: 754 errno = ENOTCONN; 755 return 0; 756 case SSL_ERROR_WANT_READ: 757 case SSL_ERROR_WANT_WRITE: 758 case SSL_ERROR_WANT_CONNECT: 759 case SSL_ERROR_WANT_ACCEPT: 760 case SSL_ERROR_WANT_X509_LOOKUP: 761 case SSL_ERROR_WANT_ASYNC: 762 case SSL_ERROR_WANT_ASYNC_JOB: 763 case SSL_ERROR_WANT_CLIENT_HELLO_CB: 764 errno = EAGAIN; 765 return -1; 766 case SSL_ERROR_SYSCALL: 767 case SSL_ERROR_SSL: 768 errno = ENOTCONN; 769 return -1; 770 default: 771 errno = ENOTCONN; 772 return -1; 773 } 774 } 775 776 static ssize_t 777 SSL_writev(SSL *ssl, struct iovec *iov, int iovcnt) 778 { 779 int i, rc = 0; 780 ssize_t total = 0; 781 782 for (i = 0; i < iovcnt; i++) { 783 rc = SSL_write(ssl, iov[i].iov_base, iov[i].iov_len); 784 785 if (rc > 0) { 786 total += rc; 787 } 788 if (rc != (int)iov[i].iov_len) { 789 break; 790 } 791 } 792 if (total > 0) { 793 errno = 0; 794 return total; 795 } 796 switch (SSL_get_error(ssl, rc)) { 797 case SSL_ERROR_ZERO_RETURN: 798 errno = ENOTCONN; 799 return 0; 800 case SSL_ERROR_WANT_READ: 801 case SSL_ERROR_WANT_WRITE: 802 case SSL_ERROR_WANT_CONNECT: 803 case SSL_ERROR_WANT_ACCEPT: 804 case SSL_ERROR_WANT_X509_LOOKUP: 805 case SSL_ERROR_WANT_ASYNC: 806 case SSL_ERROR_WANT_ASYNC_JOB: 807 case SSL_ERROR_WANT_CLIENT_HELLO_CB: 808 errno = EAGAIN; 809 return -1; 810 case SSL_ERROR_SYSCALL: 811 case SSL_ERROR_SSL: 812 errno = ENOTCONN; 813 return -1; 814 default: 815 errno = ENOTCONN; 816 return -1; 817 } 818 } 819 820 static struct spdk_sock * 821 posix_sock_create(const char *ip, int port, 822 enum posix_sock_create_type type, 823 struct spdk_sock_opts *opts, 824 bool enable_ssl) 825 { 826 struct spdk_posix_sock *sock; 827 struct spdk_sock_impl_opts impl_opts; 828 char buf[MAX_TMPBUF]; 829 char portnum[PORTNUMLEN]; 830 char *p; 831 struct addrinfo hints, *res, *res0; 832 int fd, flag; 833 int rc; 834 bool enable_zcopy_user_opts = true; 835 bool enable_zcopy_impl_opts = true; 836 SSL_CTX *ctx = 0; 837 SSL *ssl = 0; 838 839 assert(opts != NULL); 840 posix_opts_get_impl_opts(opts, &impl_opts); 841 842 if (ip == NULL) { 843 return NULL; 844 } 845 if (ip[0] == '[') { 846 snprintf(buf, sizeof(buf), "%s", ip + 1); 847 p = strchr(buf, ']'); 848 if (p != NULL) { 849 *p = '\0'; 850 } 851 ip = (const char *) &buf[0]; 852 } 853 854 snprintf(portnum, sizeof portnum, "%d", port); 855 memset(&hints, 0, sizeof hints); 856 hints.ai_family = PF_UNSPEC; 857 hints.ai_socktype = SOCK_STREAM; 858 hints.ai_flags = AI_NUMERICSERV; 859 hints.ai_flags |= AI_PASSIVE; 860 hints.ai_flags |= AI_NUMERICHOST; 861 rc = getaddrinfo(ip, portnum, &hints, &res0); 862 if (rc != 0) { 863 SPDK_ERRLOG("getaddrinfo() failed %s (%d)\n", gai_strerror(rc), rc); 864 return NULL; 865 } 866 867 /* try listen */ 868 fd = -1; 869 for (res = res0; res != NULL; res = res->ai_next) { 870 retry: 871 fd = posix_fd_create(res, opts, &impl_opts); 872 if (fd < 0) { 873 continue; 874 } 875 if (type == SPDK_SOCK_CREATE_LISTEN) { 876 if (enable_ssl) { 877 ctx = posix_sock_create_ssl_context(TLS_server_method(), opts, &impl_opts); 878 if (!ctx) { 879 SPDK_ERRLOG("posix_sock_create_ssl_context() failed, errno = %d\n", errno); 880 close(fd); 881 fd = -1; 882 break; 883 } 884 } 885 rc = bind(fd, res->ai_addr, res->ai_addrlen); 886 if (rc != 0) { 887 SPDK_ERRLOG("bind() failed at port %d, errno = %d\n", port, errno); 888 switch (errno) { 889 case EINTR: 890 /* interrupted? */ 891 close(fd); 892 goto retry; 893 case EADDRNOTAVAIL: 894 SPDK_ERRLOG("IP address %s not available. " 895 "Verify IP address in config file " 896 "and make sure setup script is " 897 "run before starting spdk app.\n", ip); 898 /* FALLTHROUGH */ 899 default: 900 /* try next family */ 901 close(fd); 902 fd = -1; 903 continue; 904 } 905 } 906 /* bind OK */ 907 rc = listen(fd, 512); 908 if (rc != 0) { 909 SPDK_ERRLOG("listen() failed, errno = %d\n", errno); 910 close(fd); 911 fd = -1; 912 break; 913 } 914 enable_zcopy_impl_opts = impl_opts.enable_zerocopy_send_server; 915 } else if (type == SPDK_SOCK_CREATE_CONNECT) { 916 rc = connect(fd, res->ai_addr, res->ai_addrlen); 917 if (rc != 0) { 918 SPDK_ERRLOG("connect() failed, errno = %d\n", errno); 919 /* try next family */ 920 close(fd); 921 fd = -1; 922 continue; 923 } 924 enable_zcopy_impl_opts = impl_opts.enable_zerocopy_send_client; 925 if (enable_ssl) { 926 ctx = posix_sock_create_ssl_context(TLS_client_method(), opts, &impl_opts); 927 if (!ctx) { 928 SPDK_ERRLOG("posix_sock_create_ssl_context() failed, errno = %d\n", errno); 929 close(fd); 930 fd = -1; 931 break; 932 } 933 ssl = ssl_sock_connect_loop(ctx, fd); 934 if (!ssl) { 935 SPDK_ERRLOG("ssl_sock_connect_loop() failed, errno = %d\n", errno); 936 close(fd); 937 fd = -1; 938 SSL_CTX_free(ctx); 939 break; 940 } 941 } 942 } 943 944 flag = fcntl(fd, F_GETFL); 945 if (fcntl(fd, F_SETFL, flag | O_NONBLOCK) < 0) { 946 SPDK_ERRLOG("fcntl can't set nonblocking mode for socket, fd: %d (%d)\n", fd, errno); 947 close(fd); 948 fd = -1; 949 break; 950 } 951 break; 952 } 953 freeaddrinfo(res0); 954 955 if (fd < 0) { 956 return NULL; 957 } 958 959 /* Only enable zero copy for non-loopback and non-ssl sockets. */ 960 enable_zcopy_user_opts = opts->zcopy && !sock_is_loopback(fd) && !enable_ssl; 961 962 sock = posix_sock_alloc(fd, &impl_opts, enable_zcopy_user_opts && enable_zcopy_impl_opts); 963 if (sock == NULL) { 964 SPDK_ERRLOG("sock allocation failed\n"); 965 close(fd); 966 return NULL; 967 } 968 969 if (ctx) { 970 sock->ctx = ctx; 971 } 972 973 if (ssl) { 974 sock->ssl = ssl; 975 } 976 977 return &sock->base; 978 } 979 980 static struct spdk_sock * 981 posix_sock_listen(const char *ip, int port, struct spdk_sock_opts *opts) 982 { 983 return posix_sock_create(ip, port, SPDK_SOCK_CREATE_LISTEN, opts, false); 984 } 985 986 static struct spdk_sock * 987 posix_sock_connect(const char *ip, int port, struct spdk_sock_opts *opts) 988 { 989 return posix_sock_create(ip, port, SPDK_SOCK_CREATE_CONNECT, opts, false); 990 } 991 992 static struct spdk_sock * 993 posix_sock_accept(struct spdk_sock *_sock) 994 { 995 struct spdk_posix_sock *sock = __posix_sock(_sock); 996 struct sockaddr_storage sa; 997 socklen_t salen; 998 int rc, fd; 999 struct spdk_posix_sock *new_sock; 1000 int flag; 1001 SSL *ssl = 0; 1002 1003 memset(&sa, 0, sizeof(sa)); 1004 salen = sizeof(sa); 1005 1006 assert(sock != NULL); 1007 1008 rc = accept(sock->fd, (struct sockaddr *)&sa, &salen); 1009 1010 if (rc == -1) { 1011 return NULL; 1012 } 1013 1014 fd = rc; 1015 1016 flag = fcntl(fd, F_GETFL); 1017 if ((!(flag & O_NONBLOCK)) && (fcntl(fd, F_SETFL, flag | O_NONBLOCK) < 0)) { 1018 SPDK_ERRLOG("fcntl can't set nonblocking mode for socket, fd: %d (%d)\n", fd, errno); 1019 close(fd); 1020 return NULL; 1021 } 1022 1023 #if defined(SO_PRIORITY) 1024 /* The priority is not inherited, so call this function again */ 1025 if (sock->base.opts.priority) { 1026 rc = setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &sock->base.opts.priority, sizeof(int)); 1027 if (rc != 0) { 1028 close(fd); 1029 return NULL; 1030 } 1031 } 1032 #endif 1033 1034 /* Establish SSL connection */ 1035 if (sock->ctx) { 1036 ssl = ssl_sock_accept_loop(sock->ctx, fd); 1037 if (!ssl) { 1038 SPDK_ERRLOG("ssl_sock_accept_loop() failed, errno = %d\n", errno); 1039 close(fd); 1040 SSL_CTX_free(sock->ctx); 1041 return NULL; 1042 } 1043 } 1044 1045 /* Inherit the zero copy feature from the listen socket */ 1046 new_sock = posix_sock_alloc(fd, &sock->base.impl_opts, sock->zcopy); 1047 if (new_sock == NULL) { 1048 close(fd); 1049 return NULL; 1050 } 1051 1052 if (sock->ctx) { 1053 new_sock->ctx = sock->ctx; 1054 } 1055 1056 if (ssl) { 1057 new_sock->ssl = ssl; 1058 } 1059 1060 return &new_sock->base; 1061 } 1062 1063 static int 1064 posix_sock_close(struct spdk_sock *_sock) 1065 { 1066 struct spdk_posix_sock *sock = __posix_sock(_sock); 1067 1068 assert(TAILQ_EMPTY(&_sock->pending_reqs)); 1069 1070 /* If the socket fails to close, the best choice is to 1071 * leak the fd but continue to free the rest of the sock 1072 * memory. */ 1073 close(sock->fd); 1074 1075 spdk_pipe_destroy(sock->recv_pipe); 1076 free(sock->recv_buf); 1077 free(sock); 1078 1079 return 0; 1080 } 1081 1082 #ifdef SPDK_ZEROCOPY 1083 static int 1084 _sock_check_zcopy(struct spdk_sock *sock) 1085 { 1086 struct spdk_posix_sock *psock = __posix_sock(sock); 1087 struct msghdr msgh = {}; 1088 uint8_t buf[sizeof(struct cmsghdr) + sizeof(struct sock_extended_err)]; 1089 ssize_t rc; 1090 struct sock_extended_err *serr; 1091 struct cmsghdr *cm; 1092 uint32_t idx; 1093 struct spdk_sock_request *req, *treq; 1094 bool found; 1095 1096 msgh.msg_control = buf; 1097 msgh.msg_controllen = sizeof(buf); 1098 1099 while (true) { 1100 rc = recvmsg(psock->fd, &msgh, MSG_ERRQUEUE); 1101 1102 if (rc < 0) { 1103 if (errno == EWOULDBLOCK || errno == EAGAIN) { 1104 return 0; 1105 } 1106 1107 if (!TAILQ_EMPTY(&sock->pending_reqs)) { 1108 SPDK_ERRLOG("Attempting to receive from ERRQUEUE yielded error, but pending list still has orphaned entries\n"); 1109 } else { 1110 SPDK_WARNLOG("Recvmsg yielded an error!\n"); 1111 } 1112 return 0; 1113 } 1114 1115 cm = CMSG_FIRSTHDR(&msgh); 1116 if (!(cm && 1117 ((cm->cmsg_level == SOL_IP && cm->cmsg_type == IP_RECVERR) || 1118 (cm->cmsg_level == SOL_IPV6 && cm->cmsg_type == IPV6_RECVERR)))) { 1119 SPDK_WARNLOG("Unexpected cmsg level or type!\n"); 1120 return 0; 1121 } 1122 1123 serr = (struct sock_extended_err *)CMSG_DATA(cm); 1124 if (serr->ee_errno != 0 || serr->ee_origin != SO_EE_ORIGIN_ZEROCOPY) { 1125 SPDK_WARNLOG("Unexpected extended error origin\n"); 1126 return 0; 1127 } 1128 1129 /* Most of the time, the pending_reqs array is in the exact 1130 * order we need such that all of the requests to complete are 1131 * in order, in the front. It is guaranteed that all requests 1132 * belonging to the same sendmsg call are sequential, so once 1133 * we encounter one match we can stop looping as soon as a 1134 * non-match is found. 1135 */ 1136 for (idx = serr->ee_info; idx <= serr->ee_data; idx++) { 1137 found = false; 1138 TAILQ_FOREACH_SAFE(req, &sock->pending_reqs, internal.link, treq) { 1139 if (!req->internal.is_zcopy) { 1140 /* This wasn't a zcopy request. It was just waiting in line to complete */ 1141 rc = spdk_sock_request_put(sock, req, 0); 1142 if (rc < 0) { 1143 return rc; 1144 } 1145 } else if (req->internal.offset == idx) { 1146 found = true; 1147 rc = spdk_sock_request_put(sock, req, 0); 1148 if (rc < 0) { 1149 return rc; 1150 } 1151 } else if (found) { 1152 break; 1153 } 1154 } 1155 } 1156 } 1157 1158 return 0; 1159 } 1160 #endif 1161 1162 static int 1163 _sock_flush(struct spdk_sock *sock) 1164 { 1165 struct spdk_posix_sock *psock = __posix_sock(sock); 1166 struct msghdr msg = {}; 1167 int flags; 1168 struct iovec iovs[IOV_BATCH_SIZE]; 1169 int iovcnt; 1170 int retval; 1171 struct spdk_sock_request *req; 1172 int i; 1173 ssize_t rc; 1174 unsigned int offset; 1175 size_t len; 1176 bool is_zcopy = false; 1177 1178 /* Can't flush from within a callback or we end up with recursive calls */ 1179 if (sock->cb_cnt > 0) { 1180 return 0; 1181 } 1182 1183 #ifdef SPDK_ZEROCOPY 1184 if (psock->zcopy) { 1185 flags = MSG_ZEROCOPY | MSG_NOSIGNAL; 1186 } else 1187 #endif 1188 { 1189 flags = MSG_NOSIGNAL; 1190 } 1191 1192 iovcnt = spdk_sock_prep_reqs(sock, iovs, 0, NULL, &flags); 1193 if (iovcnt == 0) { 1194 return 0; 1195 } 1196 1197 #ifdef SPDK_ZEROCOPY 1198 is_zcopy = flags & MSG_ZEROCOPY; 1199 #endif 1200 1201 /* Perform the vectored write */ 1202 msg.msg_iov = iovs; 1203 msg.msg_iovlen = iovcnt; 1204 1205 if (psock->ssl) { 1206 rc = SSL_writev(psock->ssl, iovs, iovcnt); 1207 } else { 1208 rc = sendmsg(psock->fd, &msg, flags); 1209 } 1210 if (rc <= 0) { 1211 if (errno == EAGAIN || errno == EWOULDBLOCK || (errno == ENOBUFS && psock->zcopy)) { 1212 return 0; 1213 } 1214 return rc; 1215 } 1216 1217 if (is_zcopy) { 1218 /* Handling overflow case, because we use psock->sendmsg_idx - 1 for the 1219 * req->internal.offset, so sendmsg_idx should not be zero */ 1220 if (spdk_unlikely(psock->sendmsg_idx == UINT32_MAX)) { 1221 psock->sendmsg_idx = 1; 1222 } else { 1223 psock->sendmsg_idx++; 1224 } 1225 } 1226 1227 /* Consume the requests that were actually written */ 1228 req = TAILQ_FIRST(&sock->queued_reqs); 1229 while (req) { 1230 offset = req->internal.offset; 1231 1232 /* req->internal.is_zcopy is true when the whole req or part of it is sent with zerocopy */ 1233 req->internal.is_zcopy = is_zcopy; 1234 1235 for (i = 0; i < req->iovcnt; i++) { 1236 /* Advance by the offset first */ 1237 if (offset >= SPDK_SOCK_REQUEST_IOV(req, i)->iov_len) { 1238 offset -= SPDK_SOCK_REQUEST_IOV(req, i)->iov_len; 1239 continue; 1240 } 1241 1242 /* Calculate the remaining length of this element */ 1243 len = SPDK_SOCK_REQUEST_IOV(req, i)->iov_len - offset; 1244 1245 if (len > (size_t)rc) { 1246 /* This element was partially sent. */ 1247 req->internal.offset += rc; 1248 return 0; 1249 } 1250 1251 offset = 0; 1252 req->internal.offset += len; 1253 rc -= len; 1254 } 1255 1256 /* Handled a full request. */ 1257 spdk_sock_request_pend(sock, req); 1258 1259 if (!req->internal.is_zcopy && req == TAILQ_FIRST(&sock->pending_reqs)) { 1260 /* The sendmsg syscall above isn't currently asynchronous, 1261 * so it's already done. */ 1262 retval = spdk_sock_request_put(sock, req, 0); 1263 if (retval) { 1264 break; 1265 } 1266 } else { 1267 /* Re-use the offset field to hold the sendmsg call index. The 1268 * index is 0 based, so subtract one here because we've already 1269 * incremented above. */ 1270 req->internal.offset = psock->sendmsg_idx - 1; 1271 } 1272 1273 if (rc == 0) { 1274 break; 1275 } 1276 1277 req = TAILQ_FIRST(&sock->queued_reqs); 1278 } 1279 1280 return 0; 1281 } 1282 1283 static int 1284 posix_sock_flush(struct spdk_sock *sock) 1285 { 1286 #ifdef SPDK_ZEROCOPY 1287 struct spdk_posix_sock *psock = __posix_sock(sock); 1288 1289 if (psock->zcopy && !TAILQ_EMPTY(&sock->pending_reqs)) { 1290 _sock_check_zcopy(sock); 1291 } 1292 #endif 1293 1294 return _sock_flush(sock); 1295 } 1296 1297 static ssize_t 1298 posix_sock_recv_from_pipe(struct spdk_posix_sock *sock, struct iovec *diov, int diovcnt) 1299 { 1300 struct iovec siov[2]; 1301 int sbytes; 1302 ssize_t bytes; 1303 struct spdk_posix_sock_group_impl *group; 1304 1305 sbytes = spdk_pipe_reader_get_buffer(sock->recv_pipe, sock->recv_buf_sz, siov); 1306 if (sbytes < 0) { 1307 errno = EINVAL; 1308 return -1; 1309 } else if (sbytes == 0) { 1310 errno = EAGAIN; 1311 return -1; 1312 } 1313 1314 bytes = spdk_iovcpy(siov, 2, diov, diovcnt); 1315 1316 if (bytes == 0) { 1317 /* The only way this happens is if diov is 0 length */ 1318 errno = EINVAL; 1319 return -1; 1320 } 1321 1322 spdk_pipe_reader_advance(sock->recv_pipe, bytes); 1323 1324 /* If we drained the pipe, mark it appropriately */ 1325 if (spdk_pipe_reader_bytes_available(sock->recv_pipe) == 0) { 1326 assert(sock->pipe_has_data == true); 1327 1328 group = __posix_group_impl(sock->base.group_impl); 1329 if (group && !sock->socket_has_data) { 1330 TAILQ_REMOVE(&group->socks_with_data, sock, link); 1331 } 1332 1333 sock->pipe_has_data = false; 1334 } 1335 1336 return bytes; 1337 } 1338 1339 static inline ssize_t 1340 posix_sock_read(struct spdk_posix_sock *sock) 1341 { 1342 struct iovec iov[2]; 1343 int bytes_avail, bytes_recvd; 1344 struct spdk_posix_sock_group_impl *group; 1345 1346 bytes_avail = spdk_pipe_writer_get_buffer(sock->recv_pipe, sock->recv_buf_sz, iov); 1347 1348 if (bytes_avail <= 0) { 1349 return bytes_avail; 1350 } 1351 1352 if (sock->ssl) { 1353 bytes_recvd = SSL_readv(sock->ssl, iov, 2); 1354 } else { 1355 bytes_recvd = readv(sock->fd, iov, 2); 1356 } 1357 1358 assert(sock->pipe_has_data == false); 1359 1360 if (bytes_recvd <= 0) { 1361 /* Errors count as draining the socket data */ 1362 if (sock->base.group_impl && sock->socket_has_data) { 1363 group = __posix_group_impl(sock->base.group_impl); 1364 TAILQ_REMOVE(&group->socks_with_data, sock, link); 1365 } 1366 1367 sock->socket_has_data = false; 1368 1369 return bytes_recvd; 1370 } 1371 1372 spdk_pipe_writer_advance(sock->recv_pipe, bytes_recvd); 1373 1374 #if DEBUG 1375 if (sock->base.group_impl) { 1376 assert(sock->socket_has_data == true); 1377 } 1378 #endif 1379 1380 sock->pipe_has_data = true; 1381 if (bytes_recvd < bytes_avail) { 1382 /* We drained the kernel socket entirely. */ 1383 sock->socket_has_data = false; 1384 } 1385 1386 return bytes_recvd; 1387 } 1388 1389 static ssize_t 1390 posix_sock_readv(struct spdk_sock *_sock, struct iovec *iov, int iovcnt) 1391 { 1392 struct spdk_posix_sock *sock = __posix_sock(_sock); 1393 struct spdk_posix_sock_group_impl *group = __posix_group_impl(sock->base.group_impl); 1394 int rc, i; 1395 size_t len; 1396 1397 if (sock->recv_pipe == NULL) { 1398 assert(sock->pipe_has_data == false); 1399 if (group && sock->socket_has_data) { 1400 sock->socket_has_data = false; 1401 TAILQ_REMOVE(&group->socks_with_data, sock, link); 1402 } 1403 if (sock->ssl) { 1404 return SSL_readv(sock->ssl, iov, iovcnt); 1405 } else { 1406 return readv(sock->fd, iov, iovcnt); 1407 } 1408 } 1409 1410 /* If the socket is not in a group, we must assume it always has 1411 * data waiting for us because it is not epolled */ 1412 if (!sock->pipe_has_data && (group == NULL || sock->socket_has_data)) { 1413 /* If the user is receiving a sufficiently large amount of data, 1414 * receive directly to their buffers. */ 1415 len = 0; 1416 for (i = 0; i < iovcnt; i++) { 1417 len += iov[i].iov_len; 1418 } 1419 1420 if (len >= MIN_SOCK_PIPE_SIZE) { 1421 /* TODO: Should this detect if kernel socket is drained? */ 1422 if (sock->ssl) { 1423 return SSL_readv(sock->ssl, iov, iovcnt); 1424 } else { 1425 return readv(sock->fd, iov, iovcnt); 1426 } 1427 } 1428 1429 /* Otherwise, do a big read into our pipe */ 1430 rc = posix_sock_read(sock); 1431 if (rc <= 0) { 1432 return rc; 1433 } 1434 } 1435 1436 return posix_sock_recv_from_pipe(sock, iov, iovcnt); 1437 } 1438 1439 static ssize_t 1440 posix_sock_recv(struct spdk_sock *sock, void *buf, size_t len) 1441 { 1442 struct iovec iov[1]; 1443 1444 iov[0].iov_base = buf; 1445 iov[0].iov_len = len; 1446 1447 return posix_sock_readv(sock, iov, 1); 1448 } 1449 1450 static void 1451 posix_sock_readv_async(struct spdk_sock *sock, struct spdk_sock_request *req) 1452 { 1453 req->cb_fn(req->cb_arg, -ENOTSUP); 1454 } 1455 1456 static ssize_t 1457 posix_sock_writev(struct spdk_sock *_sock, struct iovec *iov, int iovcnt) 1458 { 1459 struct spdk_posix_sock *sock = __posix_sock(_sock); 1460 int rc; 1461 1462 /* In order to process a writev, we need to flush any asynchronous writes 1463 * first. */ 1464 rc = _sock_flush(_sock); 1465 if (rc < 0) { 1466 return rc; 1467 } 1468 1469 if (!TAILQ_EMPTY(&_sock->queued_reqs)) { 1470 /* We weren't able to flush all requests */ 1471 errno = EAGAIN; 1472 return -1; 1473 } 1474 1475 if (sock->ssl) { 1476 return SSL_writev(sock->ssl, iov, iovcnt); 1477 } else { 1478 return writev(sock->fd, iov, iovcnt); 1479 } 1480 } 1481 1482 static void 1483 posix_sock_writev_async(struct spdk_sock *sock, struct spdk_sock_request *req) 1484 { 1485 int rc; 1486 1487 spdk_sock_request_queue(sock, req); 1488 1489 /* If there are a sufficient number queued, just flush them out immediately. */ 1490 if (sock->queued_iovcnt >= IOV_BATCH_SIZE) { 1491 rc = _sock_flush(sock); 1492 if (rc) { 1493 spdk_sock_abort_requests(sock); 1494 } 1495 } 1496 } 1497 1498 static int 1499 posix_sock_set_recvlowat(struct spdk_sock *_sock, int nbytes) 1500 { 1501 struct spdk_posix_sock *sock = __posix_sock(_sock); 1502 int val; 1503 int rc; 1504 1505 assert(sock != NULL); 1506 1507 val = nbytes; 1508 rc = setsockopt(sock->fd, SOL_SOCKET, SO_RCVLOWAT, &val, sizeof val); 1509 if (rc != 0) { 1510 return -1; 1511 } 1512 return 0; 1513 } 1514 1515 static bool 1516 posix_sock_is_ipv6(struct spdk_sock *_sock) 1517 { 1518 struct spdk_posix_sock *sock = __posix_sock(_sock); 1519 struct sockaddr_storage sa; 1520 socklen_t salen; 1521 int rc; 1522 1523 assert(sock != NULL); 1524 1525 memset(&sa, 0, sizeof sa); 1526 salen = sizeof sa; 1527 rc = getsockname(sock->fd, (struct sockaddr *) &sa, &salen); 1528 if (rc != 0) { 1529 SPDK_ERRLOG("getsockname() failed (errno=%d)\n", errno); 1530 return false; 1531 } 1532 1533 return (sa.ss_family == AF_INET6); 1534 } 1535 1536 static bool 1537 posix_sock_is_ipv4(struct spdk_sock *_sock) 1538 { 1539 struct spdk_posix_sock *sock = __posix_sock(_sock); 1540 struct sockaddr_storage sa; 1541 socklen_t salen; 1542 int rc; 1543 1544 assert(sock != NULL); 1545 1546 memset(&sa, 0, sizeof sa); 1547 salen = sizeof sa; 1548 rc = getsockname(sock->fd, (struct sockaddr *) &sa, &salen); 1549 if (rc != 0) { 1550 SPDK_ERRLOG("getsockname() failed (errno=%d)\n", errno); 1551 return false; 1552 } 1553 1554 return (sa.ss_family == AF_INET); 1555 } 1556 1557 static bool 1558 posix_sock_is_connected(struct spdk_sock *_sock) 1559 { 1560 struct spdk_posix_sock *sock = __posix_sock(_sock); 1561 uint8_t byte; 1562 int rc; 1563 1564 rc = recv(sock->fd, &byte, 1, MSG_PEEK); 1565 if (rc == 0) { 1566 return false; 1567 } 1568 1569 if (rc < 0) { 1570 if (errno == EAGAIN || errno == EWOULDBLOCK) { 1571 return true; 1572 } 1573 1574 return false; 1575 } 1576 1577 return true; 1578 } 1579 1580 static struct spdk_sock_group_impl * 1581 posix_sock_group_impl_get_optimal(struct spdk_sock *_sock, struct spdk_sock_group_impl *hint) 1582 { 1583 struct spdk_posix_sock *sock = __posix_sock(_sock); 1584 struct spdk_sock_group_impl *group_impl; 1585 1586 if (sock->placement_id != -1) { 1587 spdk_sock_map_lookup(&g_map, sock->placement_id, &group_impl, hint); 1588 return group_impl; 1589 } 1590 1591 return NULL; 1592 } 1593 1594 static struct spdk_sock_group_impl * 1595 posix_sock_group_impl_create(void) 1596 { 1597 struct spdk_posix_sock_group_impl *group_impl; 1598 int fd; 1599 1600 #if defined(SPDK_EPOLL) 1601 fd = epoll_create1(0); 1602 #elif defined(SPDK_KEVENT) 1603 fd = kqueue(); 1604 #endif 1605 if (fd == -1) { 1606 return NULL; 1607 } 1608 1609 group_impl = calloc(1, sizeof(*group_impl)); 1610 if (group_impl == NULL) { 1611 SPDK_ERRLOG("group_impl allocation failed\n"); 1612 close(fd); 1613 return NULL; 1614 } 1615 1616 group_impl->fd = fd; 1617 TAILQ_INIT(&group_impl->socks_with_data); 1618 group_impl->placement_id = -1; 1619 1620 if (g_spdk_posix_sock_impl_opts.enable_placement_id == PLACEMENT_CPU) { 1621 spdk_sock_map_insert(&g_map, spdk_env_get_current_core(), &group_impl->base); 1622 group_impl->placement_id = spdk_env_get_current_core(); 1623 } 1624 1625 return &group_impl->base; 1626 } 1627 1628 static void 1629 posix_sock_mark(struct spdk_posix_sock_group_impl *group, struct spdk_posix_sock *sock, 1630 int placement_id) 1631 { 1632 #if defined(SO_MARK) 1633 int rc; 1634 1635 rc = setsockopt(sock->fd, SOL_SOCKET, SO_MARK, 1636 &placement_id, sizeof(placement_id)); 1637 if (rc != 0) { 1638 /* Not fatal */ 1639 SPDK_ERRLOG("Error setting SO_MARK\n"); 1640 return; 1641 } 1642 1643 rc = spdk_sock_map_insert(&g_map, placement_id, &group->base); 1644 if (rc != 0) { 1645 /* Not fatal */ 1646 SPDK_ERRLOG("Failed to insert sock group into map: %d\n", rc); 1647 return; 1648 } 1649 1650 sock->placement_id = placement_id; 1651 #endif 1652 } 1653 1654 static void 1655 posix_sock_update_mark(struct spdk_sock_group_impl *_group, struct spdk_sock *_sock) 1656 { 1657 struct spdk_posix_sock_group_impl *group = __posix_group_impl(_group); 1658 1659 if (group->placement_id == -1) { 1660 group->placement_id = spdk_sock_map_find_free(&g_map); 1661 1662 /* If a free placement id is found, update existing sockets in this group */ 1663 if (group->placement_id != -1) { 1664 struct spdk_sock *sock, *tmp; 1665 1666 TAILQ_FOREACH_SAFE(sock, &_group->socks, link, tmp) { 1667 posix_sock_mark(group, __posix_sock(sock), group->placement_id); 1668 } 1669 } 1670 } 1671 1672 if (group->placement_id != -1) { 1673 /* 1674 * group placement id is already determined for this poll group. 1675 * Mark socket with group's placement id. 1676 */ 1677 posix_sock_mark(group, __posix_sock(_sock), group->placement_id); 1678 } 1679 } 1680 1681 static int 1682 posix_sock_group_impl_add_sock(struct spdk_sock_group_impl *_group, struct spdk_sock *_sock) 1683 { 1684 struct spdk_posix_sock_group_impl *group = __posix_group_impl(_group); 1685 struct spdk_posix_sock *sock = __posix_sock(_sock); 1686 int rc; 1687 1688 #if defined(SPDK_EPOLL) 1689 struct epoll_event event; 1690 1691 memset(&event, 0, sizeof(event)); 1692 /* EPOLLERR is always on even if we don't set it, but be explicit for clarity */ 1693 event.events = EPOLLIN | EPOLLERR; 1694 event.data.ptr = sock; 1695 1696 rc = epoll_ctl(group->fd, EPOLL_CTL_ADD, sock->fd, &event); 1697 #elif defined(SPDK_KEVENT) 1698 struct kevent event; 1699 struct timespec ts = {0}; 1700 1701 EV_SET(&event, sock->fd, EVFILT_READ, EV_ADD, 0, 0, sock); 1702 1703 rc = kevent(group->fd, &event, 1, NULL, 0, &ts); 1704 #endif 1705 1706 if (rc != 0) { 1707 return rc; 1708 } 1709 1710 /* switched from another polling group due to scheduling */ 1711 if (spdk_unlikely(sock->recv_pipe != NULL && 1712 (spdk_pipe_reader_bytes_available(sock->recv_pipe) > 0))) { 1713 sock->pipe_has_data = true; 1714 sock->socket_has_data = false; 1715 TAILQ_INSERT_TAIL(&group->socks_with_data, sock, link); 1716 } 1717 1718 if (g_spdk_posix_sock_impl_opts.enable_placement_id == PLACEMENT_MARK) { 1719 posix_sock_update_mark(_group, _sock); 1720 } else if (sock->placement_id != -1) { 1721 rc = spdk_sock_map_insert(&g_map, sock->placement_id, &group->base); 1722 if (rc != 0) { 1723 SPDK_ERRLOG("Failed to insert sock group into map: %d\n", rc); 1724 /* Do not treat this as an error. The system will continue running. */ 1725 } 1726 } 1727 1728 return rc; 1729 } 1730 1731 static int 1732 posix_sock_group_impl_remove_sock(struct spdk_sock_group_impl *_group, struct spdk_sock *_sock) 1733 { 1734 struct spdk_posix_sock_group_impl *group = __posix_group_impl(_group); 1735 struct spdk_posix_sock *sock = __posix_sock(_sock); 1736 int rc; 1737 1738 if (sock->pipe_has_data || sock->socket_has_data) { 1739 TAILQ_REMOVE(&group->socks_with_data, sock, link); 1740 sock->pipe_has_data = false; 1741 sock->socket_has_data = false; 1742 } 1743 1744 if (sock->placement_id != -1) { 1745 spdk_sock_map_release(&g_map, sock->placement_id); 1746 } 1747 1748 #if defined(SPDK_EPOLL) 1749 struct epoll_event event; 1750 1751 /* Event parameter is ignored but some old kernel version still require it. */ 1752 rc = epoll_ctl(group->fd, EPOLL_CTL_DEL, sock->fd, &event); 1753 #elif defined(SPDK_KEVENT) 1754 struct kevent event; 1755 struct timespec ts = {0}; 1756 1757 EV_SET(&event, sock->fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); 1758 1759 rc = kevent(group->fd, &event, 1, NULL, 0, &ts); 1760 if (rc == 0 && event.flags & EV_ERROR) { 1761 rc = -1; 1762 errno = event.data; 1763 } 1764 #endif 1765 1766 spdk_sock_abort_requests(_sock); 1767 1768 return rc; 1769 } 1770 1771 static int 1772 posix_sock_group_impl_poll(struct spdk_sock_group_impl *_group, int max_events, 1773 struct spdk_sock **socks) 1774 { 1775 struct spdk_posix_sock_group_impl *group = __posix_group_impl(_group); 1776 struct spdk_sock *sock, *tmp; 1777 int num_events, i, rc; 1778 struct spdk_posix_sock *psock, *ptmp; 1779 #if defined(SPDK_EPOLL) 1780 struct epoll_event events[MAX_EVENTS_PER_POLL]; 1781 #elif defined(SPDK_KEVENT) 1782 struct kevent events[MAX_EVENTS_PER_POLL]; 1783 struct timespec ts = {0}; 1784 #endif 1785 1786 #ifdef SPDK_ZEROCOPY 1787 /* When all of the following conditions are met 1788 * - non-blocking socket 1789 * - zero copy is enabled 1790 * - interrupts suppressed (i.e. busy polling) 1791 * - the NIC tx queue is full at the time sendmsg() is called 1792 * - epoll_wait determines there is an EPOLLIN event for the socket 1793 * then we can get into a situation where data we've sent is queued 1794 * up in the kernel network stack, but interrupts have been suppressed 1795 * because other traffic is flowing so the kernel misses the signal 1796 * to flush the software tx queue. If there wasn't incoming data 1797 * pending on the socket, then epoll_wait would have been sufficient 1798 * to kick off the send operation, but since there is a pending event 1799 * epoll_wait does not trigger the necessary operation. 1800 * 1801 * We deal with this by checking for all of the above conditions and 1802 * additionally looking for EPOLLIN events that were not consumed from 1803 * the last poll loop. We take this to mean that the upper layer is 1804 * unable to consume them because it is blocked waiting for resources 1805 * to free up, and those resources are most likely freed in response 1806 * to a pending asynchronous write completing. 1807 * 1808 * Additionally, sockets that have the same placement_id actually share 1809 * an underlying hardware queue. That means polling one of them is 1810 * equivalent to polling all of them. As a quick mechanism to avoid 1811 * making extra poll() calls, stash the last placement_id during the loop 1812 * and only poll if it's not the same. The overwhelmingly common case 1813 * is that all sockets in this list have the same placement_id because 1814 * SPDK is intentionally grouping sockets by that value, so even 1815 * though this won't stop all extra calls to poll(), it's very fast 1816 * and will catch all of them in practice. 1817 */ 1818 int last_placement_id = -1; 1819 1820 TAILQ_FOREACH(psock, &group->socks_with_data, link) { 1821 if (psock->zcopy && psock->placement_id >= 0 && 1822 psock->placement_id != last_placement_id) { 1823 struct pollfd pfd = {psock->fd, POLLIN | POLLERR, 0}; 1824 1825 poll(&pfd, 1, 0); 1826 last_placement_id = psock->placement_id; 1827 } 1828 } 1829 #endif 1830 1831 /* This must be a TAILQ_FOREACH_SAFE because while flushing, 1832 * a completion callback could remove the sock from the 1833 * group. */ 1834 TAILQ_FOREACH_SAFE(sock, &_group->socks, link, tmp) { 1835 rc = _sock_flush(sock); 1836 if (rc) { 1837 spdk_sock_abort_requests(sock); 1838 } 1839 } 1840 1841 assert(max_events > 0); 1842 1843 #if defined(SPDK_EPOLL) 1844 num_events = epoll_wait(group->fd, events, max_events, 0); 1845 #elif defined(SPDK_KEVENT) 1846 num_events = kevent(group->fd, NULL, 0, events, max_events, &ts); 1847 #endif 1848 1849 if (num_events == -1) { 1850 return -1; 1851 } else if (num_events == 0 && !TAILQ_EMPTY(&_group->socks)) { 1852 sock = TAILQ_FIRST(&_group->socks); 1853 psock = __posix_sock(sock); 1854 /* poll() is called here to busy poll the queue associated with 1855 * first socket in list and potentially reap incoming data. 1856 */ 1857 if (sock->opts.priority) { 1858 struct pollfd pfd = {0, 0, 0}; 1859 1860 pfd.fd = psock->fd; 1861 pfd.events = POLLIN | POLLERR; 1862 poll(&pfd, 1, 0); 1863 } 1864 } 1865 1866 for (i = 0; i < num_events; i++) { 1867 #if defined(SPDK_EPOLL) 1868 sock = events[i].data.ptr; 1869 psock = __posix_sock(sock); 1870 1871 #ifdef SPDK_ZEROCOPY 1872 if (events[i].events & EPOLLERR) { 1873 rc = _sock_check_zcopy(sock); 1874 /* If the socket was closed or removed from 1875 * the group in response to a send ack, don't 1876 * add it to the array here. */ 1877 if (rc || sock->cb_fn == NULL) { 1878 continue; 1879 } 1880 } 1881 #endif 1882 if ((events[i].events & EPOLLIN) == 0) { 1883 continue; 1884 } 1885 1886 #elif defined(SPDK_KEVENT) 1887 sock = events[i].udata; 1888 psock = __posix_sock(sock); 1889 #endif 1890 1891 /* If the socket is not already in the list, add it now */ 1892 if (!psock->socket_has_data && !psock->pipe_has_data) { 1893 TAILQ_INSERT_TAIL(&group->socks_with_data, psock, link); 1894 } 1895 psock->socket_has_data = true; 1896 } 1897 1898 num_events = 0; 1899 1900 TAILQ_FOREACH_SAFE(psock, &group->socks_with_data, link, ptmp) { 1901 if (num_events == max_events) { 1902 break; 1903 } 1904 1905 /* If the socket's cb_fn is NULL, just remove it from the 1906 * list and do not add it to socks array */ 1907 if (spdk_unlikely(psock->base.cb_fn == NULL)) { 1908 psock->socket_has_data = false; 1909 psock->pipe_has_data = false; 1910 TAILQ_REMOVE(&group->socks_with_data, psock, link); 1911 continue; 1912 } 1913 1914 socks[num_events++] = &psock->base; 1915 } 1916 1917 /* Cycle the has_data list so that each time we poll things aren't 1918 * in the same order. Say we have 6 sockets in the list, named as follows: 1919 * A B C D E F 1920 * And all 6 sockets had epoll events, but max_events is only 3. That means 1921 * psock currently points at D. We want to rearrange the list to the following: 1922 * D E F A B C 1923 * 1924 * The variables below are named according to this example to make it easier to 1925 * follow the swaps. 1926 */ 1927 if (psock != NULL) { 1928 struct spdk_posix_sock *pa, *pc, *pd, *pf; 1929 1930 /* Capture pointers to the elements we need */ 1931 pd = psock; 1932 pc = TAILQ_PREV(pd, spdk_has_data_list, link); 1933 pa = TAILQ_FIRST(&group->socks_with_data); 1934 pf = TAILQ_LAST(&group->socks_with_data, spdk_has_data_list); 1935 1936 /* Break the link between C and D */ 1937 pc->link.tqe_next = NULL; 1938 1939 /* Connect F to A */ 1940 pf->link.tqe_next = pa; 1941 pa->link.tqe_prev = &pf->link.tqe_next; 1942 1943 /* Fix up the list first/last pointers */ 1944 group->socks_with_data.tqh_first = pd; 1945 group->socks_with_data.tqh_last = &pc->link.tqe_next; 1946 1947 /* D is in front of the list, make tqe prev pointer point to the head of list */ 1948 pd->link.tqe_prev = &group->socks_with_data.tqh_first; 1949 } 1950 1951 return num_events; 1952 } 1953 1954 static int 1955 posix_sock_group_impl_close(struct spdk_sock_group_impl *_group) 1956 { 1957 struct spdk_posix_sock_group_impl *group = __posix_group_impl(_group); 1958 int rc; 1959 1960 if (g_spdk_posix_sock_impl_opts.enable_placement_id == PLACEMENT_CPU) { 1961 spdk_sock_map_release(&g_map, spdk_env_get_current_core()); 1962 } 1963 1964 rc = close(group->fd); 1965 free(group); 1966 return rc; 1967 } 1968 1969 static struct spdk_net_impl g_posix_net_impl = { 1970 .name = "posix", 1971 .getaddr = posix_sock_getaddr, 1972 .connect = posix_sock_connect, 1973 .listen = posix_sock_listen, 1974 .accept = posix_sock_accept, 1975 .close = posix_sock_close, 1976 .recv = posix_sock_recv, 1977 .readv = posix_sock_readv, 1978 .readv_async = posix_sock_readv_async, 1979 .writev = posix_sock_writev, 1980 .writev_async = posix_sock_writev_async, 1981 .flush = posix_sock_flush, 1982 .set_recvlowat = posix_sock_set_recvlowat, 1983 .set_recvbuf = posix_sock_set_recvbuf, 1984 .set_sendbuf = posix_sock_set_sendbuf, 1985 .is_ipv6 = posix_sock_is_ipv6, 1986 .is_ipv4 = posix_sock_is_ipv4, 1987 .is_connected = posix_sock_is_connected, 1988 .group_impl_get_optimal = posix_sock_group_impl_get_optimal, 1989 .group_impl_create = posix_sock_group_impl_create, 1990 .group_impl_add_sock = posix_sock_group_impl_add_sock, 1991 .group_impl_remove_sock = posix_sock_group_impl_remove_sock, 1992 .group_impl_poll = posix_sock_group_impl_poll, 1993 .group_impl_close = posix_sock_group_impl_close, 1994 .get_opts = posix_sock_impl_get_opts, 1995 .set_opts = posix_sock_impl_set_opts, 1996 }; 1997 1998 SPDK_NET_IMPL_REGISTER(posix, &g_posix_net_impl, DEFAULT_SOCK_PRIORITY); 1999 2000 static struct spdk_sock * 2001 ssl_sock_listen(const char *ip, int port, struct spdk_sock_opts *opts) 2002 { 2003 return posix_sock_create(ip, port, SPDK_SOCK_CREATE_LISTEN, opts, true); 2004 } 2005 2006 static struct spdk_sock * 2007 ssl_sock_connect(const char *ip, int port, struct spdk_sock_opts *opts) 2008 { 2009 return posix_sock_create(ip, port, SPDK_SOCK_CREATE_CONNECT, opts, true); 2010 } 2011 2012 static struct spdk_net_impl g_ssl_net_impl = { 2013 .name = "ssl", 2014 .getaddr = posix_sock_getaddr, 2015 .connect = ssl_sock_connect, 2016 .listen = ssl_sock_listen, 2017 .accept = posix_sock_accept, 2018 .close = posix_sock_close, 2019 .recv = posix_sock_recv, 2020 .readv = posix_sock_readv, 2021 .writev = posix_sock_writev, 2022 .writev_async = posix_sock_writev_async, 2023 .flush = posix_sock_flush, 2024 .set_recvlowat = posix_sock_set_recvlowat, 2025 .set_recvbuf = posix_sock_set_recvbuf, 2026 .set_sendbuf = posix_sock_set_sendbuf, 2027 .is_ipv6 = posix_sock_is_ipv6, 2028 .is_ipv4 = posix_sock_is_ipv4, 2029 .is_connected = posix_sock_is_connected, 2030 .group_impl_get_optimal = posix_sock_group_impl_get_optimal, 2031 .group_impl_create = posix_sock_group_impl_create, 2032 .group_impl_add_sock = posix_sock_group_impl_add_sock, 2033 .group_impl_remove_sock = posix_sock_group_impl_remove_sock, 2034 .group_impl_poll = posix_sock_group_impl_poll, 2035 .group_impl_close = posix_sock_group_impl_close, 2036 .get_opts = posix_sock_impl_get_opts, 2037 .set_opts = posix_sock_impl_set_opts, 2038 }; 2039 2040 SPDK_NET_IMPL_REGISTER(ssl, &g_ssl_net_impl, DEFAULT_SOCK_PRIORITY); 2041 SPDK_LOG_REGISTER_COMPONENT(sock_posix) 2042