diff --git a/src/kernel/Communicator.cc b/src/kernel/Communicator.cc index 9abef974fb..f85445dd0f 100644 --- a/src/kernel/Communicator.cc +++ b/src/kernel/Communicator.cc @@ -119,6 +119,59 @@ static int __create_ssl(SSL_CTX *ssl_ctx, struct CommConnEntry *entry) return -1; } +#define SSL_WRITEV_BUFSIZE 2048 + +static int __ssl_writev(SSL *ssl, struct iovec vectors[], int cnt) +{ + if (vectors[0].iov_len < SSL_WRITEV_BUFSIZE && cnt > 1) + { + char *p = (char *)SSL_get_app_data(ssl); + size_t nleft = SSL_WRITEV_BUFSIZE; + size_t n; + int i; + + if (!p) + { + p = (char *)malloc(SSL_WRITEV_BUFSIZE); + if (!p) + return -1; + + if (SSL_set_app_data(ssl, p) <= 0) + { + free(p); + return -1; + } + } + + n = vectors[0].iov_len; + memcpy(p, vectors[0].iov_base, n); + vectors[0].iov_base = p; + + p += n; + nleft -= n; + for (i = 1; i < cnt; i++) + { + if (vectors[i].iov_len < nleft) + n = vectors[i].iov_len; + else + n = nleft; + + memcpy(p, vectors[i].iov_base, n); + vectors[i].iov_base = (char *)vectors[i].iov_base + n; + vectors[i].iov_len -= n; + + p += n; + nleft -= n; + if (nleft == 0) + break; + } + + vectors[0].iov_len = SSL_WRITEV_BUFSIZE - nleft; + } + + return SSL_write(ssl, vectors[0].iov_base, vectors[0].iov_len); +} + static void __release_conn(struct CommConnEntry *entry) { delete entry->conn; @@ -126,7 +179,10 @@ static void __release_conn(struct CommConnEntry *entry) pthread_mutex_destroy(&entry->mutex); if (entry->ssl) + { + free(SSL_get_app_data(entry->ssl)); SSL_free(entry->ssl); + } close(entry->sockfd); free(entry); @@ -446,7 +502,7 @@ int Communicator::send_message_sync(struct iovec vectors[], int cnt, } else if (vectors->iov_len > 0) { - n = SSL_write(entry->ssl, vectors->iov_base, vectors->iov_len); + n = __ssl_writev(entry->ssl, vectors, cnt); if (n <= 0) return cnt; } @@ -457,12 +513,14 @@ int Communicator::send_message_sync(struct iovec vectors[], int cnt, { if ((size_t)n >= vectors[i].iov_len) n -= vectors[i].iov_len; - else + else if (n > 0) { vectors[i].iov_base = (char *)vectors[i].iov_base + n; vectors[i].iov_len -= n; - break; + return cnt - i; } + else + break; } vectors += i; diff --git a/src/manager/RouteManager.cc b/src/manager/RouteManager.cc index 081e350f6d..6280ca3959 100644 --- a/src/manager/RouteManager.cc +++ b/src/manager/RouteManager.cc @@ -78,27 +78,7 @@ class RouteTargetSCTP : public RouteManager::RouteTarget #endif }; -class RouteTargetTCP_SSL : public RouteTargetTCP -{ -private: - virtual int create_connect_fd() - { - const struct sockaddr *addr; - socklen_t addrlen; - int sockfd; - - this->get_addr(&addr, &addrlen); - sockfd = socket(addr->sa_family, SOCK_STREAM, 0); - if (sockfd >= 0) - { - int nodelay = 1; - setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, - &nodelay, sizeof (int)); - } - - return sockfd; - } -}; +using RouteTargetTCP_SSL = RouteTargetTCP; /* To support TLS SNI. */ class RouteTargetTCP_TLS_SNI : public RouteTargetTCP_SSL diff --git a/src/server/WFServer.cc b/src/server/WFServer.cc index 7c275388d2..bfd7e19490 100644 --- a/src/server/WFServer.cc +++ b/src/server/WFServer.cc @@ -183,18 +183,6 @@ WFConnection *WFServerBase::new_connection(int accept_fd) int reuse = 1; setsockopt(accept_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof (int)); - - if (this->get_ssl_ctx()) - { - if (this->params.transport_type == TT_TCP || - this->params.transport_type == TT_TCP_SSL) - { - int nodelay = 1; - setsockopt(accept_fd, IPPROTO_TCP, TCP_NODELAY, - &nodelay, sizeof (int)); - } - } - return new WFServerConnection(&this->conn_count); }