Compare commits
40
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b28e10660 | ||
|
|
f5d19b657a | ||
|
|
82f9515bf1 | ||
|
|
dc13f2dd45 | ||
|
|
d54f73195b | ||
|
|
6c584df3ca | ||
|
|
b2effacbc1 | ||
|
|
440a722827 | ||
|
|
e478139e4d | ||
|
|
7d68443235 | ||
|
|
ff6519a005 | ||
|
|
34a98e4dcc | ||
|
|
1ebac51110 | ||
|
|
2e261ac2cf | ||
|
|
405a8c3f53 | ||
|
|
8d4d49dad3 | ||
|
|
6a646be234 | ||
|
|
bc0aa48bc7 | ||
|
|
df08f4e4d2 | ||
|
|
2669ba96ad | ||
|
|
b5b3c95bfd | ||
|
|
0d5530f89a | ||
|
|
0b32d76f75 | ||
|
|
67132a29ae | ||
|
|
6d22ab77ec | ||
|
|
b2bcf2734c | ||
|
|
04e4fcd14d | ||
|
|
2dbfc8548a | ||
|
|
74a826d0be | ||
|
|
4aa9c8bf2b | ||
|
|
5a51415d2c | ||
|
|
2be8dfbb48 | ||
|
|
49db218f73 | ||
|
|
b04a2d62b2 | ||
|
|
dcd545a1a5 | ||
|
|
553e153c16 | ||
|
|
cc420ca32d | ||
|
|
dd5941b9a4 | ||
|
|
4005b88865 | ||
|
|
280b5cd675 |
+1
-1
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8...3.30)
|
||||
|
||||
project(vitastor)
|
||||
|
||||
set(VITASTOR_VERSION "3.0.8")
|
||||
set(VITASTOR_VERSION "3.0.9")
|
||||
|
||||
include(CTest)
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
VITASTOR_VERSION ?= v3.0.8
|
||||
VITASTOR_VERSION ?= v3.0.9
|
||||
|
||||
all: build push
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ spec:
|
||||
capabilities:
|
||||
add: ["SYS_ADMIN"]
|
||||
allowPrivilegeEscalation: true
|
||||
image: vitalif/vitastor-csi:v3.0.8
|
||||
image: vitalif/vitastor-csi:v3.0.9
|
||||
args:
|
||||
- "--node=$(NODE_ID)"
|
||||
- "--endpoint=$(CSI_ENDPOINT)"
|
||||
|
||||
@@ -121,7 +121,7 @@ spec:
|
||||
privileged: true
|
||||
capabilities:
|
||||
add: ["SYS_ADMIN"]
|
||||
image: vitalif/vitastor-csi:v3.0.8
|
||||
image: vitalif/vitastor-csi:v3.0.9
|
||||
args:
|
||||
- "--node=$(NODE_ID)"
|
||||
- "--endpoint=$(CSI_ENDPOINT)"
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ package vitastor
|
||||
|
||||
const (
|
||||
vitastorCSIDriverName = "csi.vitastor.io"
|
||||
vitastorCSIDriverVersion = "3.0.8"
|
||||
vitastorCSIDriverVersion = "3.0.9"
|
||||
)
|
||||
|
||||
// Config struct fills the parameters of request or user input
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
vitastor (3.0.8-1) unstable; urgency=medium
|
||||
vitastor (3.0.9-1) unstable; urgency=medium
|
||||
|
||||
* Bugfixes
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
VITASTOR_VERSION ?= v3.0.8
|
||||
VITASTOR_VERSION ?= v3.0.9
|
||||
|
||||
all: build push
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
|
||||
# Desired Vitastor version
|
||||
VITASTOR_VERSION=v3.0.8
|
||||
VITASTOR_VERSION=v3.0.9
|
||||
|
||||
# Additional arguments for all containers
|
||||
# For example, you may want to specify a custom logging driver here
|
||||
|
||||
@@ -70,6 +70,7 @@ with an OSD restart or, for some of them, even without restarting by updating co
|
||||
- [use_atomic_flag](#use_atomic_flag)
|
||||
- [pg_reshard_chunk_size](#pg_reshard_chunk_size)
|
||||
- [pg_reshard_chunk_pause_ms](#pg_reshard_chunk_pause_ms)
|
||||
- [gc_on_start](#gc_on_start)
|
||||
|
||||
## bind_address
|
||||
|
||||
@@ -753,3 +754,9 @@ This option sets the maximum number of object is a chunk. Moving 100k objects us
|
||||
- Default: 100
|
||||
|
||||
This option sets the interval between handling two PG count change chunks.
|
||||
|
||||
## gc_on_start
|
||||
|
||||
- Type: boolean
|
||||
|
||||
Forcibly clean all garbage entries in the new store on every OSD restart.
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
- [use_atomic_flag](#use_atomic_flag)
|
||||
- [pg_reshard_chunk_size](#pg_reshard_chunk_size)
|
||||
- [pg_reshard_chunk_pause_ms](#pg_reshard_chunk_pause_ms)
|
||||
- [gc_on_start](#gc_on_start)
|
||||
|
||||
## bind_address
|
||||
|
||||
@@ -793,3 +794,9 @@ pg_minsize OSD во время переключений, что может по
|
||||
- Значение по умолчанию: 100
|
||||
|
||||
Данная опция задаёт интервал между обработкой двух порций изменения числа PG пулов.
|
||||
|
||||
## gc_on_start
|
||||
|
||||
- Тип: булево (да/нет)
|
||||
|
||||
Принудительно очищать все мусорные записи в новом хранилище при каждом запуске OSD.
|
||||
|
||||
@@ -938,3 +938,7 @@
|
||||
This option sets the interval between handling two PG count change chunks.
|
||||
info_ru: |
|
||||
Данная опция задаёт интервал между обработкой двух порций изменения числа PG пулов.
|
||||
- name: gc_on_start
|
||||
type: bool
|
||||
info: Forcibly clean all garbage entries in the new store on every OSD restart.
|
||||
info_ru: Принудительно очищать все мусорные записи в новом хранилище при каждом запуске OSD.
|
||||
|
||||
@@ -26,9 +26,9 @@ at Vitastor Kubernetes operator: https://github.com/Antilles7227/vitastor-operat
|
||||
The instruction is very simple.
|
||||
|
||||
1. Download a Docker image of the desired version: \
|
||||
`docker pull vitalif/vitastor:v3.0.8`
|
||||
`docker pull vitalif/vitastor:v3.0.9`
|
||||
2. Install scripts to the host system: \
|
||||
`docker run --rm -it -v /etc:/host-etc -v /usr/bin:/host-bin vitalif/vitastor:v3.0.8 install.sh`
|
||||
`docker run --rm -it -v /etc:/host-etc -v /usr/bin:/host-bin vitalif/vitastor:v3.0.9 install.sh`
|
||||
3. Reload udev rules: \
|
||||
`udevadm control --reload-rules`
|
||||
4. Enable the vitastor-host service: \
|
||||
|
||||
@@ -25,9 +25,9 @@ Vitastor можно установить в Docker/Podman. При этом etcd,
|
||||
Инструкция по установке максимально простая.
|
||||
|
||||
1. Скачайте Docker-образ желаемой версии: \
|
||||
`docker pull vitalif/vitastor:v3.0.8`
|
||||
`docker pull vitalif/vitastor:v3.0.9`
|
||||
2. Установите скрипты в хост-систему командой: \
|
||||
`docker run --rm -it -v /etc:/host-etc -v /usr/bin:/host-bin vitalif/vitastor:v3.0.8 install.sh`
|
||||
`docker run --rm -it -v /etc:/host-etc -v /usr/bin:/host-bin vitalif/vitastor:v3.0.9 install.sh`
|
||||
3. Перезагрузите правила udev: \
|
||||
`udevadm control --reload-rules`
|
||||
4. Включите сервис vitastor-host: \
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vitastor-mon",
|
||||
"version": "3.0.8",
|
||||
"version": "3.0.9",
|
||||
"description": "Vitastor SDS monitor service",
|
||||
"main": "mon-main.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vitastor",
|
||||
"version": "3.0.8",
|
||||
"version": "3.0.9",
|
||||
"description": "Low-level native bindings to Vitastor client library",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
|
||||
@@ -50,7 +50,7 @@ from cinder.volume import configuration
|
||||
from cinder.volume import driver
|
||||
from cinder.volume import volume_utils
|
||||
|
||||
VITASTOR_VERSION = '3.0.8'
|
||||
VITASTOR_VERSION = '3.0.9'
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Name: vitastor
|
||||
Version: 3.0.8
|
||||
Version: 3.0.9
|
||||
Release: 1%{?dist}
|
||||
Summary: Vitastor, a fast software-defined clustered block storage
|
||||
|
||||
License: Vitastor Network Public License 1.1
|
||||
URL: https://vitastor.io/
|
||||
Source0: vitastor-3.0.8.el10.tar.gz
|
||||
Source0: vitastor-3.0.9.el10.tar.gz
|
||||
|
||||
BuildRequires: gperftools-devel
|
||||
BuildRequires: gcc-c++
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Name: vitastor
|
||||
Version: 3.0.8
|
||||
Version: 3.0.9
|
||||
Release: 1%{?dist}
|
||||
Summary: Vitastor, a fast software-defined clustered block storage
|
||||
|
||||
License: Vitastor Network Public License 1.1
|
||||
URL: https://vitastor.io/
|
||||
Source0: vitastor-3.0.8.el7.tar.gz
|
||||
Source0: vitastor-3.0.9.el7.tar.gz
|
||||
|
||||
BuildRequires: gperftools-devel
|
||||
BuildRequires: devtoolset-9-gcc-c++
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Name: vitastor
|
||||
Version: 3.0.8
|
||||
Version: 3.0.9
|
||||
Release: 1%{?dist}
|
||||
Summary: Vitastor, a fast software-defined clustered block storage
|
||||
|
||||
License: Vitastor Network Public License 1.1
|
||||
URL: https://vitastor.io/
|
||||
Source0: vitastor-3.0.8.el8.tar.gz
|
||||
Source0: vitastor-3.0.9.el8.tar.gz
|
||||
|
||||
BuildRequires: gperftools-devel
|
||||
BuildRequires: gcc-toolset-9-gcc-c++
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Name: vitastor
|
||||
Version: 3.0.8
|
||||
Version: 3.0.9
|
||||
Release: 1%{?dist}
|
||||
Summary: Vitastor, a fast software-defined clustered block storage
|
||||
|
||||
License: Vitastor Network Public License 1.1
|
||||
URL: https://vitastor.io/
|
||||
Source0: vitastor-3.0.8.el9.tar.gz
|
||||
Source0: vitastor-3.0.9.el9.tar.gz
|
||||
|
||||
BuildRequires: gperftools-devel
|
||||
BuildRequires: gcc-c++
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ if("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/local/?$")
|
||||
endif()
|
||||
set(ENABLE_COVERAGE false CACHE BOOL "Enable code coverage")
|
||||
|
||||
add_definitions(-DVITASTOR_VERSION="3.0.8")
|
||||
add_definitions(-DVITASTOR_VERSION="3.0.9")
|
||||
add_definitions(-D_GNU_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -Wno-sign-compare -Wno-comment -Wno-parentheses -Wno-pointer-arith -fdiagnostics-color=always -fno-omit-frame-pointer -fvisibility=hidden -I ${CMAKE_SOURCE_DIR}/src)
|
||||
add_link_options(-fno-omit-frame-pointer)
|
||||
if (${WITH_ASAN})
|
||||
|
||||
@@ -877,7 +877,7 @@ uint64_t blockstore_impl_t::get_garbage_entries()
|
||||
|
||||
uint64_t blockstore_impl_t::get_garbage_memory()
|
||||
{
|
||||
return sizeof(blockstore_dirty_db_t::node_type) * dirty_db.size();
|
||||
return (sizeof(obj_ver_id) + sizeof(dirty_entry) + 32) * dirty_db.size();
|
||||
}
|
||||
|
||||
} // namespace v1
|
||||
|
||||
+26
-14
@@ -164,30 +164,42 @@ void http_ares_cb(void *data, ares_socket_t socket_fd, int readable, int writabl
|
||||
}
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
bool openssl_ctx_add_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
||||
{
|
||||
BIO *bio = NULL;
|
||||
if (file_or_pem.substr(0, 5) != "-----")
|
||||
{
|
||||
std::string pem = read_file(file_or_pem);
|
||||
bio = BIO_new_mem_buf(pem.data(), pem.size());
|
||||
}
|
||||
else
|
||||
bio = BIO_new_mem_buf(file_or_pem.data(), file_or_pem.size());
|
||||
if (!bio)
|
||||
return false;
|
||||
X509 *x509 = PEM_read_bio_X509(bio, NULL, 0, NULL);
|
||||
bool ok = !!x509;
|
||||
if (x509)
|
||||
{
|
||||
X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
|
||||
X509_STORE_add_cert(store, x509);
|
||||
X509_free(x509);
|
||||
}
|
||||
BIO_free(bio);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool openssl_ctx_use_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
||||
{
|
||||
if (file_or_pem.substr(0, 5) == "-----")
|
||||
{
|
||||
BIO *bio = BIO_new_mem_buf(file_or_pem.data(), file_or_pem.size());
|
||||
if (!bio)
|
||||
return false;
|
||||
X509 *x509 = PEM_read_bio_X509(bio, NULL, 0, NULL);
|
||||
bool ok = !!x509;
|
||||
if (x509)
|
||||
{
|
||||
X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
|
||||
X509_STORE_add_cert(store, x509);
|
||||
X509_free(x509);
|
||||
}
|
||||
BIO_free(bio);
|
||||
return ok;
|
||||
return openssl_ctx_add_ca(ssl_ctx, file_or_pem);
|
||||
}
|
||||
return file_or_pem.empty()
|
||||
? !!SSL_CTX_set_default_verify_paths(ssl_ctx)
|
||||
: !!SSL_CTX_load_verify_locations(ssl_ctx, file_or_pem.c_str(), NULL);
|
||||
}
|
||||
|
||||
static std::string openssl_get_cn(X509 *x509)
|
||||
std::string openssl_get_cn(X509 *x509)
|
||||
{
|
||||
X509_NAME* subj = X509_get_subject_name(x509);
|
||||
int pos = X509_NAME_get_index_by_NID(subj, NID_commonName, -1);
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
#include <functional>
|
||||
#include "json11/json11.hpp"
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/types.h>
|
||||
#endif
|
||||
|
||||
#define WS_CONTINUATION 0
|
||||
#define WS_TEXT 1
|
||||
#define WS_BINARY 2
|
||||
@@ -69,3 +73,11 @@ void http_close(http_co_t *co);
|
||||
void http_destroy(http_co_t *co);
|
||||
|
||||
#pragma GCC visibility pop
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
bool openssl_ctx_add_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
||||
bool openssl_ctx_use_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
||||
std::string openssl_get_cn(X509 *x509);
|
||||
bool openssl_ctx_use_cert(SSL_CTX *ssl_ctx, const std::string & file_or_pem, std::string & common_name);
|
||||
bool openssl_ctx_use_key(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
||||
#endif
|
||||
|
||||
+107
-4
@@ -14,6 +14,13 @@
|
||||
#ifdef WITH_RDMA
|
||||
#include "msgr_rdma.h"
|
||||
#endif
|
||||
#include "http_client.h"
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#include <sys/poll.h>
|
||||
|
||||
@@ -117,6 +124,43 @@ void msgr_iothread_t::run()
|
||||
|
||||
void osd_messenger_t::init()
|
||||
{
|
||||
if (!tls_cert.empty() || !tls_key.empty() || !osd_tls_ca.empty() || !client_tls_ca.empty())
|
||||
{
|
||||
// Initialize TLS context
|
||||
// FIXME: require OpenSSL
|
||||
#ifndef WITH_OPENSSL
|
||||
fprintf(stderr, "Vitastor is built without OpenSSL support\n");
|
||||
exit(1);
|
||||
#else
|
||||
if (tls_cert.empty() || tls_key.empty() || osd_tls_ca.empty() || osd_num && client_tls_ca.empty())
|
||||
{
|
||||
if (osd_num)
|
||||
fprintf(stderr, "Vitastor OSD TLS requires osd_tls_cert, osd_tls_key, osd_tls_ca, client_tls_ca\n");
|
||||
else
|
||||
fprintf(stderr, "Vitastor client TLS requires tls_cert, tls_key and osd_tls_ca\n");
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
|
||||
bool ok = SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
|
||||
ok = ok && openssl_ctx_add_ca(ssl_ctx, osd_tls_ca);
|
||||
if (osd_num)
|
||||
{
|
||||
// OSD uses 2 separate root certificates to distinguish between clients and peer OSDs
|
||||
ok = ok && openssl_ctx_add_ca(ssl_ctx, client_tls_ca);
|
||||
}
|
||||
ok = ok && openssl_ctx_use_cert(ssl_ctx, tls_cert, tls_cn);
|
||||
ok = ok && openssl_ctx_use_key(ssl_ctx, tls_key);
|
||||
if (!ok)
|
||||
{
|
||||
SSL_CTX_free(ssl_ctx);
|
||||
ssl_ctx = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef WITH_RDMACM
|
||||
if (use_rdmacm)
|
||||
{
|
||||
@@ -303,6 +347,13 @@ osd_messenger_t::~osd_messenger_t()
|
||||
{
|
||||
destroy_aes_xts_decrypt(decrypt_ctx);
|
||||
}
|
||||
#ifdef WITH_OPENSSL
|
||||
if (ssl_ctx)
|
||||
{
|
||||
SSL_CTX_free(ssl_ctx);
|
||||
ssl_ctx = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void osd_messenger_t::parse_config(const json11::Json & config)
|
||||
@@ -340,7 +391,27 @@ void osd_messenger_t::parse_config(const json11::Json & config)
|
||||
this->max_aes_xts_pool_size = config["max_aes_xts_pool_size"].uint64_value();
|
||||
if (!this->max_aes_xts_pool_size)
|
||||
this->max_aes_xts_pool_size = 256;
|
||||
this->use_proto_checksums = config["use_proto_checksums"].is_null() || config["use_proto_checksums"].bool_value();
|
||||
if (config["proto_checksums"].is_null())
|
||||
this->use_proto_checksums = MSGR_CSUM_PAYLOAD;
|
||||
else if (config["proto_checksums"].is_bool())
|
||||
this->use_proto_checksums = config["proto_checksums"].bool_value() ? MSGR_CSUM_FULL : 0;
|
||||
else if (config["proto_checksums"].string_value() != "")
|
||||
this->use_proto_checksums = config["proto_checksums"].string_value() == "full" ? MSGR_CSUM_FULL : MSGR_CSUM_PAYLOAD;
|
||||
else
|
||||
this->use_proto_checksums = 0;
|
||||
if (!osd_num)
|
||||
{
|
||||
tls_cert = config["tls_cert"].string_value();
|
||||
tls_key = config["tls_key"].string_value();
|
||||
osd_tls_ca = config["osd_tls_ca"].string_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
tls_cert = config["osd_tls_cert"].string_value();
|
||||
tls_key = config["osd_tls_key"].string_value();
|
||||
osd_tls_ca = config["osd_tls_ca"].string_value();
|
||||
client_tls_ca = config["client_tls_ca"].string_value();
|
||||
}
|
||||
if (!osd_num)
|
||||
this->iothread_count = (uint32_t)config["client_iothread_count"].uint64_value();
|
||||
else
|
||||
@@ -571,6 +642,10 @@ void osd_messenger_t::handle_connect_epoll(int peer_fd)
|
||||
handle_peer_epoll(peer_fd, epoll_events);
|
||||
});
|
||||
// Check OSD number
|
||||
if (!tls_cert.empty())
|
||||
{
|
||||
ssl_init(cl, false);
|
||||
}
|
||||
check_peer_config(cl);
|
||||
}
|
||||
|
||||
@@ -663,7 +738,7 @@ void osd_messenger_t::check_peer_config(osd_client_t *cl)
|
||||
auto features = json11::Json::object{ { "check_sequencing", true } };
|
||||
if (use_proto_checksums)
|
||||
{
|
||||
features["proto_checksums"] = true;
|
||||
features["proto_checksums"] = use_proto_checksums;
|
||||
}
|
||||
payload["features"] = features;
|
||||
#ifdef WITH_RDMA
|
||||
@@ -740,9 +815,13 @@ void osd_messenger_t::check_peer_config(osd_client_t *cl)
|
||||
delete op;
|
||||
return;
|
||||
}
|
||||
if (use_proto_checksums && config["features"]["proto_checksums"].bool_value())
|
||||
if (use_proto_checksums)
|
||||
{
|
||||
cl->proto_csum_status = MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT;
|
||||
auto peer_csums = config["features"]["proto_checksums"].uint64_value();
|
||||
if (peer_csums == MSGR_CSUM_FULL && use_proto_checksums == MSGR_CSUM_FULL)
|
||||
cl->proto_csum_status = MSGR_CSUM_FULL;
|
||||
else if (peer_csums && use_proto_checksums)
|
||||
cl->proto_csum_status = MSGR_CSUM_PAYLOAD;
|
||||
}
|
||||
#ifdef WITH_RDMA
|
||||
if (!use_rdmacm && cl->rdma_conn && config["rdma_address"].is_string())
|
||||
@@ -808,6 +887,10 @@ void osd_messenger_t::accept_connections(int listen_fd)
|
||||
cl->peer_fd = peer_fd;
|
||||
cl->peer_state = PEER_CONNECTED;
|
||||
cl->in_buf = (uint8_t*)malloc_or_die(receive_buffer_size);
|
||||
if (!tls_cert.empty())
|
||||
{
|
||||
ssl_init(cl, true);
|
||||
}
|
||||
// Add FD to epoll
|
||||
tfd->set_fd_handler(peer_fd, false, [this](int peer_fd, int epoll_events)
|
||||
{
|
||||
@@ -822,6 +905,26 @@ void osd_messenger_t::accept_connections(int listen_fd)
|
||||
}
|
||||
}
|
||||
|
||||
void osd_messenger_t::ssl_init(osd_client_t *cl, bool server_mode)
|
||||
{
|
||||
#ifdef WITH_OPENSSL
|
||||
cl->write_to_ssl = BIO_new(BIO_s_mem());
|
||||
cl->read_from_ssl = BIO_new(BIO_s_mem());
|
||||
cl->ssl_cli = SSL_new(ssl_ctx);
|
||||
if (server_mode)
|
||||
{
|
||||
SSL_set_accept_state(cl->ssl_cli);
|
||||
}
|
||||
else
|
||||
{
|
||||
SSL_set_connect_state(cl->ssl_cli);
|
||||
}
|
||||
SSL_set_bio(cl->ssl_cli, cl->write_to_ssl, cl->read_from_ssl);
|
||||
bool ok = ssl_do_handshake(cl);
|
||||
assert(ok);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WITH_RDMA
|
||||
msgr_rdma_context_t* osd_messenger_t::choose_rdma_context(osd_client_t *cl)
|
||||
{
|
||||
|
||||
+46
-3
@@ -12,6 +12,10 @@
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/types.h>
|
||||
#endif
|
||||
|
||||
#include "../util/xxh_x86dispatch.h"
|
||||
#include "../util/robin_hood.h"
|
||||
#include "malloc_or_die.h"
|
||||
@@ -32,8 +36,9 @@
|
||||
#define PEER_RDMA 4
|
||||
#define PEER_STOPPED 5
|
||||
|
||||
#define MSGR_PEER_CSUM_IN 1
|
||||
#define MSGR_PEER_CSUM_OUT 2
|
||||
#define MSGR_CSUM_PAYLOAD 1
|
||||
#define MSGR_CSUM_FULL 2
|
||||
#define MSGR_CSUM_NEG 4
|
||||
|
||||
#define VITASTOR_CONFIG_PATH "/etc/vitastor/vitastor.conf"
|
||||
|
||||
@@ -55,6 +60,12 @@ struct op_aes_xts_decrypt_t;
|
||||
void destroy_aes_xts_encrypt(op_aes_xts_encrypt_t *encrypt_ctx);
|
||||
void destroy_aes_xts_decrypt(op_aes_xts_decrypt_t *decrypt_ctx);
|
||||
|
||||
struct __attribute__((__packed__)) msgr_tls_record_hdr_t
|
||||
{
|
||||
uint8_t encrypted;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
struct osd_client_t
|
||||
{
|
||||
uint64_t client_id = 0;
|
||||
@@ -77,6 +88,17 @@ struct osd_client_t
|
||||
msgr_rdma_connection_t *rdma_conn = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
SSL *ssl_cli = NULL;
|
||||
BIO *write_to_ssl = NULL;
|
||||
// FIXME: use custom bio to avoid 1 more memory copy?
|
||||
BIO *read_from_ssl = NULL;
|
||||
uint8_t *ssl_out_buf = NULL;
|
||||
size_t ssl_out_buf_size = 0, ssl_out_buf_cap = 0;
|
||||
bool ssl_handshake_done = false;
|
||||
bool ssl_want_write = false;
|
||||
#endif
|
||||
|
||||
// Read state
|
||||
int read_ready = 0;
|
||||
osd_op_t *read_op = NULL;
|
||||
@@ -210,6 +232,11 @@ protected:
|
||||
int iothread_count = 0;
|
||||
int max_aes_xts_pool_size = 256;
|
||||
|
||||
std::string tls_cert;
|
||||
std::string tls_key;
|
||||
std::string osd_tls_ca;
|
||||
std::string client_tls_ca;
|
||||
|
||||
#ifdef WITH_RDMA
|
||||
bool use_rdma = true;
|
||||
bool use_rdmacm = false;
|
||||
@@ -226,6 +253,19 @@ protected:
|
||||
robin_hood::unordered_flat_map<rdma_cm_id*, rdmacm_connecting_t*> rdmacm_connecting;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
SSL_CTX *ssl_ctx = NULL;
|
||||
std::string tls_cn;
|
||||
|
||||
void ssl_init(osd_client_t *cl, bool server_mode);
|
||||
bool ssl_do_handshake(osd_client_t *cl);
|
||||
bool ssl_do_encrypt(osd_client_t *cl);
|
||||
size_t ssl_do_encrypt_to(osd_client_t *cl, uint8_t *buf, size_t size);
|
||||
bool ssl_op_write_buf(osd_client_t *cl, uint8_t *src, size_t src_len, bool skip_csum, size_t & from, size_t & done);
|
||||
size_t ssl_op_copy_to(osd_client_t *cl, uint8_t *dst, size_t dst_len);
|
||||
void ssl_op_get_write_buffers(osd_client_t *cl, std::vector<iovec> & lst);
|
||||
#endif
|
||||
|
||||
std::vector<msgr_iothread_t*> iothreads;
|
||||
std::vector<uint64_t> read_ready_clients;
|
||||
std::vector<uint64_t> write_ready_clients;
|
||||
@@ -252,7 +292,7 @@ public:
|
||||
std::vector<addr_mask_t> osd_cluster_network_masks;
|
||||
std::vector<std::string> all_osd_networks;
|
||||
std::vector<addr_mask_t> all_osd_network_masks;
|
||||
bool use_proto_checksums = true;
|
||||
int use_proto_checksums = 0;
|
||||
// op statistics
|
||||
osd_op_stats_t stats, recovery_stats;
|
||||
|
||||
@@ -304,6 +344,9 @@ protected:
|
||||
void handle_send(int result, bool prev, bool more, osd_client_t *cl);
|
||||
size_t op_copy_to(osd_client_t *cl, uint8_t *dst, size_t dst_len);
|
||||
void op_get_write_buffers(osd_client_t *cl, std::vector<iovec> & lst);
|
||||
void next_write_op(osd_client_t *cl);
|
||||
bool op_write_buf(osd_client_t *cl, uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_len, bool skip_csum, size_t & from, size_t & done);
|
||||
bool op_copy_data_to(osd_client_t *cl, uint8_t *dst, size_t dst_len, size_t & from, size_t & done);
|
||||
|
||||
void handle_read(int result, osd_client_t *cl);
|
||||
bool handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size_t bufsize);
|
||||
|
||||
@@ -187,6 +187,8 @@ std::vector<msgr_rdma_context_t*> msgr_rdma_context_t::create_all(const std::vec
|
||||
ibv_device **raw_dev_list = NULL;
|
||||
ibv_device **dev_list = NULL;
|
||||
ibv_device *single_list[2] = {};
|
||||
int up_ports = 0;
|
||||
int single_port_num = 0;
|
||||
|
||||
raw_dev_list = dev_list = ibv_get_device_list(NULL);
|
||||
if (!dev_list || !*dev_list)
|
||||
@@ -221,6 +223,7 @@ std::vector<msgr_rdma_context_t*> msgr_rdma_context_t::create_all(const std::vec
|
||||
dev_list = single_list;
|
||||
}
|
||||
|
||||
retry:
|
||||
for (int i = 0; dev_list[i]; ++i)
|
||||
{
|
||||
auto dev = dev_list[i];
|
||||
@@ -258,6 +261,9 @@ std::vector<msgr_rdma_context_t*> msgr_rdma_context_t::create_all(const std::vec
|
||||
fprintf(stderr, "RDMA device %s port %d GID %d does not exist\n", ibv_get_device_name(dev), port_num, sel_gid_index);
|
||||
continue;
|
||||
}
|
||||
up_ports++;
|
||||
single_port_num = port_num;
|
||||
single_list[0] = dev;
|
||||
uint32_t port_mtu = sel_mtu ? sel_mtu : ibv_mtu_to_bytes(portinfo.active_mtu);
|
||||
#ifdef IBV_ADVISE_MR_ADVICE_PREFETCH_NO_FAULT
|
||||
if (sel_gid_index < 0)
|
||||
@@ -298,6 +304,14 @@ cleanup_dev:
|
||||
ibv_close_device(context);
|
||||
}
|
||||
|
||||
if (!ret.size() && up_ports == 1 && dev_list != single_list)
|
||||
{
|
||||
// Auto-select the only available device/port if there is only one
|
||||
dev_list = single_list;
|
||||
sel_port_num = single_port_num;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (raw_dev_list)
|
||||
ibv_free_device_list(raw_dev_list);
|
||||
@@ -559,11 +573,7 @@ int osd_messenger_t::try_send_rdma_copy(osd_client_t *cl, uint8_t *dst, int dst_
|
||||
int total_dst_len = dst_len;
|
||||
while (dst_len > 0 && (cl->write_op || cl->write_ops.size()))
|
||||
{
|
||||
if (!cl->write_op)
|
||||
{
|
||||
cl->write_op = cl->write_ops.front();
|
||||
cl->write_ops.pop_front();
|
||||
}
|
||||
next_write_op(cl);
|
||||
osd_op_t *op = cl->write_op;
|
||||
size_t copied = op_copy_to(cl, dst, dst_len);
|
||||
if (!copied)
|
||||
@@ -744,10 +754,10 @@ void osd_messenger_t::handle_rdma_events(msgr_rdma_context_t *rdma_context)
|
||||
cl->send_free_ops.pop_front();
|
||||
}
|
||||
cl->send_free_ops.pop_front();
|
||||
if (cl->proto_csum_status == MSGR_PEER_CSUM_IN && !cl->write_op && !cl->write_ops.size())
|
||||
if ((cl->proto_csum_status & MSGR_CSUM_NEG) && !cl->write_op && !cl->write_ops.size())
|
||||
{
|
||||
// Checksums negotiated, enable
|
||||
cl->proto_csum_status = MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT;
|
||||
cl->proto_csum_status = cl->proto_csum_status & (~MSGR_CSUM_NEG);
|
||||
}
|
||||
try_send_rdma(cl);
|
||||
}
|
||||
|
||||
+15
-10
@@ -203,7 +203,7 @@ bool osd_messenger_t::handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size
|
||||
cl->read_op_size = 0;
|
||||
cl->read_op_inline_decrypt_in = 0;
|
||||
cl->read_op_inline_decrypt_pos = (size_t)-1;
|
||||
if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT))
|
||||
if (cl->proto_csum_status == MSGR_CSUM_FULL || cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
|
||||
{
|
||||
if (!cl->read_csum_state)
|
||||
cl->read_csum_state = XXH3_createState();
|
||||
@@ -236,6 +236,10 @@ bool osd_messenger_t::handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size
|
||||
|
||||
bool osd_messenger_t::handle_hdr(osd_client_t *cl)
|
||||
{
|
||||
if (cl->proto_csum_status == MSGR_CSUM_FULL)
|
||||
{
|
||||
XXH3_64bits_update(cl->read_csum_state, cl->read_op->req.buf, OSD_PACKET_SIZE);
|
||||
}
|
||||
if (cl->read_op->req.hdr.magic == SECONDARY_OSD_REPLY_MAGIC)
|
||||
{
|
||||
auto req_it = cl->sent_ops.find(cl->read_op->req.hdr.id);
|
||||
@@ -333,7 +337,8 @@ bool osd_messenger_t::allocate_op_buffers(osd_client_t *cl)
|
||||
}
|
||||
cl->read_op_size = cur_op->req.show_conf.json_len;
|
||||
}
|
||||
if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT))
|
||||
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
|
||||
cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
|
||||
{
|
||||
cl->read_op_size += 8;
|
||||
}
|
||||
@@ -391,7 +396,8 @@ bool osd_messenger_t::allocate_reply_buffers(osd_client_t *cl, osd_op_t *op)
|
||||
free(op->buf);
|
||||
op->buf = malloc_or_die(op->reply.describe.result_bytes);
|
||||
}
|
||||
if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT))
|
||||
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
|
||||
cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
|
||||
{
|
||||
cl->read_op_size += 8;
|
||||
}
|
||||
@@ -429,10 +435,6 @@ bool osd_messenger_t::op_copy_from(osd_client_t *cl, uint8_t *src, size_t src_le
|
||||
from -= dst_len;
|
||||
return true;
|
||||
};
|
||||
if (cl->read_csum_state && !from)
|
||||
{
|
||||
XXH3_64bits_update(cl->read_csum_state, (op->op_type == OSD_OP_IN ? op->req.buf : op->reply.buf), OSD_PACKET_SIZE);
|
||||
}
|
||||
if (op->op_type == OSD_OP_IN)
|
||||
{
|
||||
if (op->req.hdr.opcode == OSD_OP_SEC_WRITE ||
|
||||
@@ -520,7 +522,8 @@ bool osd_messenger_t::op_copy_from(osd_client_t *cl, uint8_t *src, size_t src_le
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT))
|
||||
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
|
||||
cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
|
||||
{
|
||||
if (!op_read_buf((uint8_t*)&op->csum, 8, true))
|
||||
return true;
|
||||
@@ -642,7 +645,8 @@ void osd_messenger_t::op_get_read_buffers(osd_client_t *cl, std::vector<iovec> &
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT))
|
||||
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
|
||||
cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
|
||||
{
|
||||
if (!op_read_buf((uint8_t*)&op->csum, 8))
|
||||
return;
|
||||
@@ -676,7 +680,8 @@ void osd_messenger_t::op_alloc_temp_buffers(osd_op_t *op, int i)
|
||||
bool osd_messenger_t::handle_finished_op(osd_client_t *cl)
|
||||
{
|
||||
osd_op_t *op = cl->read_op;
|
||||
if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT))
|
||||
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
|
||||
cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
|
||||
{
|
||||
uint64_t real_csum = XXH3_64bits_digest(cl->read_csum_state);
|
||||
if (op->csum != real_csum)
|
||||
|
||||
+383
-64
@@ -7,6 +7,13 @@
|
||||
|
||||
#include "messenger.h"
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
void osd_messenger_t::outbox_push(osd_op_t *cur_op)
|
||||
{
|
||||
assert(cur_op->client_id);
|
||||
@@ -116,25 +123,103 @@ void osd_messenger_t::measure_exec(osd_op_t *cur_op)
|
||||
}
|
||||
}
|
||||
|
||||
bool osd_messenger_t::ssl_do_handshake(osd_client_t *cl)
|
||||
{
|
||||
int r = SSL_do_handshake(cl->ssl_cli);
|
||||
if (r > 0)
|
||||
{
|
||||
cl->ssl_handshake_done = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = SSL_get_error(cl->ssl_cli, r);
|
||||
if (r != SSL_ERROR_WANT_WRITE && r != SSL_ERROR_WANT_READ)
|
||||
{
|
||||
fprintf(stderr, "Client %ju TLS handshake error: %s, stopping client\n", cl->client_id, ERR_error_string(ERR_get_error(), NULL));
|
||||
stop_client(cl->client_id);
|
||||
return false;
|
||||
}
|
||||
if (r == SSL_ERROR_WANT_WRITE)
|
||||
{
|
||||
cl->ssl_want_write = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool osd_messenger_t::ssl_do_encrypt(osd_client_t *cl)
|
||||
{
|
||||
if (cl->send_list.size() >= IOV_MAX || !cl->ssl_want_write)
|
||||
return false;
|
||||
size_t prev_size = cl->ssl_out_buf_size;
|
||||
while (true)
|
||||
{
|
||||
size_t min_cap = cl->ssl_out_buf_size*2;
|
||||
if (min_cap < 16384)
|
||||
min_cap = 16384;
|
||||
if (cl->ssl_out_buf_cap < min_cap)
|
||||
{
|
||||
uint8_t *old_buf = cl->ssl_out_buf;
|
||||
uint8_t *old_end = old_buf + cl->ssl_out_buf_cap;
|
||||
cl->ssl_out_buf = (uint8_t*)realloc_or_die(cl->ssl_out_buf, min_cap);
|
||||
cl->ssl_out_buf_cap = min_cap;
|
||||
for (auto & iov: cl->send_list)
|
||||
{
|
||||
if (iov.iov_base >= old_buf && iov.iov_base < old_end)
|
||||
iov.iov_base = cl->ssl_out_buf + ((uint8_t*)iov.iov_base - old_buf);
|
||||
}
|
||||
}
|
||||
bool full_read = (ssl_do_encrypt_to(cl, cl->ssl_out_buf+cl->ssl_out_buf_size,
|
||||
cl->ssl_out_buf_cap-cl->ssl_out_buf_size) == cl->ssl_out_buf_cap-cl->ssl_out_buf_size);
|
||||
if (!full_read)
|
||||
break;
|
||||
}
|
||||
if (cl->ssl_out_buf_size > prev_size)
|
||||
cl->send_list.push_back((iovec){ .iov_base = cl->ssl_out_buf+prev_size, .iov_len = cl->ssl_out_buf_size-prev_size });
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t osd_messenger_t::ssl_do_encrypt_to(osd_client_t *cl, uint8_t *buf, size_t size)
|
||||
{
|
||||
if (size < sizeof(msgr_tls_record_hdr_t))
|
||||
return 0;
|
||||
int r = BIO_read(cl->read_from_ssl, buf+sizeof(msgr_tls_record_hdr_t), size-sizeof(msgr_tls_record_hdr_t));
|
||||
if (r > 0)
|
||||
{
|
||||
if (r < size-sizeof(msgr_tls_record_hdr_t))
|
||||
cl->ssl_want_write = false;
|
||||
msgr_tls_record_hdr_t *hdr = (msgr_tls_record_hdr_t*)buf;
|
||||
hdr->encrypted = 1;
|
||||
hdr->size = r;
|
||||
return r+sizeof(msgr_tls_record_hdr_t);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool osd_messenger_t::try_send(osd_client_t *cl)
|
||||
{
|
||||
if (!cl->write_op && !cl->write_ops.size() || cl->write_msg.msg_iovlen > 0 || cl->peer_state == PEER_STOPPED || cl->peer_fd < 0)
|
||||
if (!cl->write_op && !cl->write_ops.size() && !cl->ssl_want_write ||
|
||||
cl->write_msg.msg_iovlen > 0 || cl->peer_state == PEER_STOPPED || cl->peer_fd < 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
assert(cl->peer_state != PEER_RDMA);
|
||||
while ((cl->write_op || cl->write_ops.size()) && cl->send_list.size() < IOV_MAX)
|
||||
if (cl->ssl_cli && !cl->ssl_handshake_done)
|
||||
{
|
||||
if (!cl->write_op)
|
||||
bool ok = ssl_do_encrypt(cl);
|
||||
assert(ok && cl->send_list.size() > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((cl->write_op || cl->write_ops.size()) && cl->send_list.size() < IOV_MAX)
|
||||
{
|
||||
cl->write_op = cl->write_ops.front();
|
||||
cl->write_ops.pop_front();
|
||||
}
|
||||
osd_op_t *op = cl->write_op;
|
||||
op_get_write_buffers(cl, cl->send_list);
|
||||
if (!cl->write_op && op->op_type == OSD_OP_IN)
|
||||
{
|
||||
cl->send_free_ops.push_back(op);
|
||||
next_write_op(cl);
|
||||
osd_op_t *op = cl->write_op;
|
||||
op_get_write_buffers(cl, cl->send_list);
|
||||
if (!cl->write_op && op->op_type == OSD_OP_IN)
|
||||
{
|
||||
cl->send_free_ops.push_back(op);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ringloop && !use_sync_send_recv)
|
||||
@@ -197,6 +282,21 @@ bool osd_messenger_t::try_send(osd_client_t *cl)
|
||||
return true;
|
||||
}
|
||||
|
||||
void osd_messenger_t::next_write_op(osd_client_t *cl)
|
||||
{
|
||||
if (!cl->write_op)
|
||||
{
|
||||
cl->write_op = cl->write_ops.front();
|
||||
cl->write_ops.pop_front();
|
||||
if (cl->proto_csum_status == MSGR_CSUM_FULL || cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
|
||||
{
|
||||
if (!cl->write_csum_state)
|
||||
cl->write_csum_state = XXH3_createState();
|
||||
XXH3_64bits_reset(cl->write_csum_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void osd_messenger_t::send_replies()
|
||||
{
|
||||
for (int i = 0; i < write_ready_clients.size(); i++)
|
||||
@@ -264,14 +364,15 @@ void osd_messenger_t::handle_send(int result, bool prev, bool more, osd_client_t
|
||||
else
|
||||
delete op;
|
||||
}
|
||||
cl->ssl_out_buf_size = 0;
|
||||
if (more)
|
||||
cl->zc_free_list.push_back(NULL); // end marker
|
||||
cl->send_free_ops.clear();
|
||||
cl->write_state = cl->write_op || cl->write_ops.size() ? CL_WRITE_READY : 0;
|
||||
if (cl->proto_csum_status == MSGR_PEER_CSUM_IN && !cl->write_op && !cl->write_ops.size())
|
||||
if ((cl->proto_csum_status & MSGR_CSUM_NEG) && !cl->write_op && !cl->write_ops.size())
|
||||
{
|
||||
// Checksums negotiated, enable
|
||||
cl->proto_csum_status = MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT;
|
||||
cl->proto_csum_status = cl->proto_csum_status & (~MSGR_CSUM_NEG);
|
||||
}
|
||||
#ifdef WITH_RDMA
|
||||
if (cl->rdma_conn && !cl->write_op && !cl->write_ops.size() && cl->peer_state == PEER_RDMA_CONNECTING)
|
||||
@@ -293,36 +394,37 @@ void osd_messenger_t::handle_send(int result, bool prev, bool more, osd_client_t
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool op_write_headers(osd_op_t *op, std::function<bool(uint8_t*, size_t)> op_write_buf)
|
||||
static inline bool op_write_headers(osd_op_t *op, std::function<bool(uint8_t*, size_t, bool)> op_write_buf, bool skip_hdr_csum)
|
||||
{
|
||||
// Header
|
||||
if (!op_write_buf((op->op_type == OSD_OP_IN ? op->reply.buf : op->req.buf), OSD_PACKET_SIZE))
|
||||
if (!op_write_buf((op->op_type == OSD_OP_IN ? op->reply.buf : op->req.buf), OSD_PACKET_SIZE, skip_hdr_csum))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Bitmap
|
||||
if (op->op_type == OSD_OP_IN &&
|
||||
op->req.hdr.opcode == OSD_OP_SEC_READ &&
|
||||
op->reply.sec_rw.attr_len > 0)
|
||||
{
|
||||
if (!op_write_buf((uint8_t*)op->bitmap, op->reply.sec_rw.attr_len))
|
||||
if (!op_write_buf((uint8_t*)op->bitmap, op->reply.sec_rw.attr_len, false))
|
||||
return false;
|
||||
}
|
||||
else if (op->op_type == OSD_OP_OUT &&
|
||||
(op->req.hdr.opcode == OSD_OP_SEC_WRITE || op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE) &&
|
||||
op->req.sec_rw.attr_len > 0)
|
||||
{
|
||||
if (!op_write_buf((uint8_t*)op->bitmap, op->req.sec_rw.attr_len))
|
||||
if (!op_write_buf((uint8_t*)op->bitmap, op->req.sec_rw.attr_len, false))
|
||||
return false;
|
||||
}
|
||||
if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP)
|
||||
{
|
||||
if (op->op_type == OSD_OP_IN && op->reply.hdr.retval > 0)
|
||||
{
|
||||
if (!op_write_buf((uint8_t*)op->buf, (size_t)op->reply.hdr.retval))
|
||||
if (!op_write_buf((uint8_t*)op->buf, (size_t)op->reply.hdr.retval, false))
|
||||
return false;
|
||||
}
|
||||
else if (op->op_type == OSD_OP_OUT && op->req.sec_read_bmp.len > 0)
|
||||
{
|
||||
if (!op_write_buf((uint8_t*)op->buf, (size_t)op->req.sec_read_bmp.len))
|
||||
if (!op_write_buf((uint8_t*)op->buf, (size_t)op->req.sec_read_bmp.len, false))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -345,20 +447,38 @@ static inline bool op_has_data(osd_op_t *op)
|
||||
op->req.hdr.opcode == OSD_OP_SHOW_CONFIG)) && op->iov.count > 0;
|
||||
}
|
||||
|
||||
size_t osd_messenger_t::op_copy_to(osd_client_t *cl, uint8_t *dst, size_t dst_len)
|
||||
static inline bool op_has_data_for_ssl(osd_op_t *op)
|
||||
{
|
||||
size_t done = 0;
|
||||
size_t from = cl->write_op_pos;
|
||||
auto op_write_buf = [&](uint8_t *src, size_t src_len, bool skip_csum = false)
|
||||
return (op->op_type == OSD_OP_IN
|
||||
? (op->req.hdr.opcode == OSD_OP_SEC_LIST ||
|
||||
op->req.hdr.opcode == OSD_OP_SHOW_CONFIG ||
|
||||
op->req.hdr.opcode == OSD_OP_DESCRIBE)
|
||||
: (op->req.hdr.opcode == OSD_OP_SEC_STABILIZE ||
|
||||
op->req.hdr.opcode == OSD_OP_SEC_ROLLBACK ||
|
||||
op->req.hdr.opcode == OSD_OP_SHOW_CONFIG)) && op->iov.count > 0;
|
||||
}
|
||||
|
||||
static inline bool op_has_data_for_nonssl(osd_op_t *op)
|
||||
{
|
||||
return (op->op_type == OSD_OP_IN
|
||||
? (op->req.hdr.opcode == OSD_OP_READ ||
|
||||
op->req.hdr.opcode == OSD_OP_SEC_READ)
|
||||
: (op->req.hdr.opcode == OSD_OP_WRITE ||
|
||||
op->req.hdr.opcode == OSD_OP_SEC_WRITE ||
|
||||
op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE)) && op->iov.count > 0;
|
||||
}
|
||||
|
||||
bool osd_messenger_t::ssl_op_write_buf(osd_client_t *cl, uint8_t *src, size_t src_len, bool skip_csum, size_t & from, size_t & done)
|
||||
{
|
||||
if (from < src_len)
|
||||
{
|
||||
if (from < src_len)
|
||||
size_t n = src_len-from;
|
||||
int ok = SSL_write_ex(cl->ssl_cli, src+from, n, &n);
|
||||
if (ok)
|
||||
{
|
||||
size_t n = src_len-from;
|
||||
if (n > dst_len-done)
|
||||
n = dst_len-done;
|
||||
cl->ssl_want_write = true;
|
||||
if (cl->write_csum_state && !skip_csum)
|
||||
XXH3_64bits_update(cl->write_csum_state, src+from, n);
|
||||
memcpy(dst+done, src+from, n);
|
||||
done += n;
|
||||
cl->write_op_pos += n;
|
||||
from += n;
|
||||
@@ -367,39 +487,135 @@ size_t osd_messenger_t::op_copy_to(osd_client_t *cl, uint8_t *dst, size_t dst_le
|
||||
from = 0;
|
||||
}
|
||||
else
|
||||
from -= src_len;
|
||||
return true;
|
||||
};
|
||||
if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT) && !from)
|
||||
{
|
||||
if (!cl->write_csum_state)
|
||||
cl->write_csum_state = XXH3_createState();
|
||||
XXH3_64bits_reset(cl->write_csum_state);
|
||||
{
|
||||
int res = SSL_get_error(cl->ssl_cli, ok);
|
||||
if (res == SSL_ERROR_WANT_WRITE || res == 0)
|
||||
cl->ssl_want_write = true;
|
||||
else if (res == SSL_ERROR_ZERO_RETURN)
|
||||
{
|
||||
fprintf(stderr, "Client %ju TLS disconnected\n", cl->client_id);
|
||||
stop_client(cl->client_id);
|
||||
}
|
||||
else if (res != SSL_ERROR_WANT_READ)
|
||||
{
|
||||
fprintf(stderr, "Client %ju TLS write error: %s. Disconnecting client\n", cl->client_id, ERR_error_string(ERR_get_error(), NULL));
|
||||
stop_client(cl->client_id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!op_write_headers(cl->write_op, op_write_buf))
|
||||
else
|
||||
from -= src_len;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool osd_messenger_t::op_write_buf(osd_client_t *cl, uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_len, bool skip_csum, size_t & from, size_t & done)
|
||||
{
|
||||
if (from < src_len)
|
||||
{
|
||||
size_t n = src_len-from;
|
||||
if (n > dst_len-done)
|
||||
n = dst_len-done;
|
||||
if (cl->write_csum_state && !skip_csum)
|
||||
XXH3_64bits_update(cl->write_csum_state, src+from, n);
|
||||
memcpy(dst+done, src+from, n);
|
||||
done += n;
|
||||
cl->write_op_pos += n;
|
||||
from += n;
|
||||
if (from < src_len)
|
||||
return false;
|
||||
from = 0;
|
||||
}
|
||||
else
|
||||
from -= src_len;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t osd_messenger_t::ssl_op_copy_to(osd_client_t *cl, uint8_t *dst, size_t dst_len)
|
||||
{
|
||||
size_t done = 0;
|
||||
size_t from = cl->write_op_pos;
|
||||
// Encrypt headers and data except read/write data
|
||||
auto to_ssl = [&](uint8_t *src, size_t src_len, bool skip_csum)
|
||||
{
|
||||
return ssl_op_write_buf(cl, src, src_len, skip_csum, from, done);
|
||||
};
|
||||
int i = 0;
|
||||
bool full_hdr = false;
|
||||
bool full_op = false;
|
||||
do
|
||||
{
|
||||
if (!full_hdr)
|
||||
full_hdr = op_write_headers(cl->write_op, to_ssl, cl->proto_csum_status != MSGR_CSUM_FULL);
|
||||
if (full_hdr && op_has_data_for_ssl(cl->write_op))
|
||||
{
|
||||
for (; i < cl->write_op->iov.count; i++)
|
||||
if (!ssl_op_write_buf(cl, (uint8_t*)cl->write_op->iov.buf[i].iov_base, cl->write_op->iov.buf[i].iov_len, false, from, done))
|
||||
break;
|
||||
full_op = true;
|
||||
}
|
||||
if (cl->peer_state == PEER_STOPPED)
|
||||
return 0;
|
||||
if (cl->ssl_want_write)
|
||||
{
|
||||
auto ssl_written = ssl_do_encrypt_to(cl, dst+done, dst_len-done);
|
||||
if (!ssl_written)
|
||||
return done;
|
||||
done += ssl_written;
|
||||
}
|
||||
} while (!full_op);
|
||||
// Non-TLS-encrypted operation data
|
||||
if (op_has_data_for_nonssl(cl->write_op))
|
||||
{
|
||||
if (!op_copy_data_to(cl, dst, dst_len, from, done))
|
||||
return done;
|
||||
}
|
||||
// TLS-encrypted checksum (uh oh...)
|
||||
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
|
||||
cl->proto_csum_status == MSGR_CSUM_PAYLOAD && cl->write_op_pos > OSD_PACKET_SIZE)
|
||||
{
|
||||
if (!from)
|
||||
cl->write_op->csum = XXH3_64bits_digest(cl->write_csum_state);
|
||||
if (!ssl_op_write_buf(cl, (uint8_t*)&cl->write_op->csum, 8, true, from, done))
|
||||
return done;
|
||||
if (cl->ssl_want_write)
|
||||
{
|
||||
auto ssl_written = ssl_do_encrypt_to(cl, dst+done, dst_len-done);
|
||||
if (!ssl_written)
|
||||
return done;
|
||||
done += ssl_written;
|
||||
}
|
||||
}
|
||||
cl->write_op = NULL;
|
||||
cl->write_op_pos = 0;
|
||||
return done;
|
||||
}
|
||||
|
||||
size_t osd_messenger_t::op_copy_to(osd_client_t *cl, uint8_t *dst, size_t dst_len)
|
||||
{
|
||||
if (cl->ssl_cli)
|
||||
{
|
||||
return ssl_op_copy_to(cl, dst, dst_len);
|
||||
}
|
||||
size_t done = 0;
|
||||
size_t from = cl->write_op_pos;
|
||||
auto op_write_buf = [&](uint8_t *src, size_t src_len, bool skip_csum)
|
||||
{
|
||||
return this->op_write_buf(cl, src, src_len, dst, dst_len, skip_csum, from, done);
|
||||
};
|
||||
// Header
|
||||
if (!op_write_headers(cl->write_op, op_write_buf, cl->proto_csum_status != MSGR_CSUM_FULL))
|
||||
{
|
||||
return done;
|
||||
}
|
||||
// Operation data
|
||||
if (op_has_data(cl->write_op))
|
||||
{
|
||||
if (cl->write_op->enc)
|
||||
{
|
||||
if (!op_encrypted_copy_data_to(cl, dst, dst_len, from, done))
|
||||
{
|
||||
return done;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < cl->write_op->iov.count; i++)
|
||||
{
|
||||
if (!op_write_buf((uint8_t*)cl->write_op->iov.buf[i].iov_base, cl->write_op->iov.buf[i].iov_len))
|
||||
return done;
|
||||
}
|
||||
}
|
||||
if (!op_copy_data_to(cl, dst, dst_len, from, done))
|
||||
return done;
|
||||
}
|
||||
if (cl->write_csum_state)
|
||||
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
|
||||
cl->proto_csum_status == MSGR_CSUM_PAYLOAD && cl->write_op_pos > OSD_PACKET_SIZE)
|
||||
{
|
||||
if (!from)
|
||||
cl->write_op->csum = XXH3_64bits_digest(cl->write_csum_state);
|
||||
@@ -411,10 +627,31 @@ size_t osd_messenger_t::op_copy_to(osd_client_t *cl, uint8_t *dst, size_t dst_le
|
||||
return done;
|
||||
}
|
||||
|
||||
bool osd_messenger_t::op_copy_data_to(osd_client_t *cl, uint8_t *dst, size_t dst_len, size_t & from, size_t & done)
|
||||
{
|
||||
if (cl->write_op->enc)
|
||||
{
|
||||
if (!op_encrypted_copy_data_to(cl, dst, dst_len, from, done))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < cl->write_op->iov.count; i++)
|
||||
{
|
||||
auto & iov = cl->write_op->iov.buf[i];
|
||||
if (!op_write_buf(cl, (uint8_t*)iov.iov_base, iov.iov_len, dst, dst_len, false, from, done))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void osd_messenger_t::op_get_write_buffers(osd_client_t *cl, std::vector<iovec> & lst)
|
||||
{
|
||||
size_t from = cl->write_op_pos;
|
||||
auto op_write_buf = [&](uint8_t *src, size_t src_len, bool skip_csum = false)
|
||||
auto op_write_buf = [&](uint8_t *src, size_t src_len, bool skip_csum)
|
||||
{
|
||||
if (lst.size() >= IOV_MAX)
|
||||
return false;
|
||||
@@ -430,13 +667,8 @@ void osd_messenger_t::op_get_write_buffers(osd_client_t *cl, std::vector<iovec>
|
||||
from -= src_len;
|
||||
return true;
|
||||
};
|
||||
if (cl->proto_csum_status == (MSGR_PEER_CSUM_IN|MSGR_PEER_CSUM_OUT) && !from)
|
||||
{
|
||||
if (!cl->write_csum_state)
|
||||
cl->write_csum_state = XXH3_createState();
|
||||
XXH3_64bits_reset(cl->write_csum_state);
|
||||
}
|
||||
if (!op_write_headers(cl->write_op, op_write_buf))
|
||||
// Header
|
||||
if (!op_write_headers(cl->write_op, op_write_buf, cl->proto_csum_status != MSGR_CSUM_FULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -462,12 +694,13 @@ void osd_messenger_t::op_get_write_buffers(osd_client_t *cl, std::vector<iovec>
|
||||
{
|
||||
for (int i = 0; i < cl->write_op->iov.count; i++)
|
||||
{
|
||||
if (!op_write_buf((uint8_t*)cl->write_op->iov.buf[i].iov_base, cl->write_op->iov.buf[i].iov_len))
|
||||
if (!op_write_buf((uint8_t*)cl->write_op->iov.buf[i].iov_base, cl->write_op->iov.buf[i].iov_len, false))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cl->write_csum_state)
|
||||
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
|
||||
cl->proto_csum_status == MSGR_CSUM_PAYLOAD && cl->write_op_pos > OSD_PACKET_SIZE)
|
||||
{
|
||||
if (!from)
|
||||
cl->write_op->csum = XXH3_64bits_digest(cl->write_csum_state);
|
||||
@@ -477,3 +710,89 @@ void osd_messenger_t::op_get_write_buffers(osd_client_t *cl, std::vector<iovec>
|
||||
cl->write_op = NULL;
|
||||
cl->write_op_pos = 0;
|
||||
}
|
||||
|
||||
void osd_messenger_t::ssl_op_get_write_buffers(osd_client_t *cl, std::vector<iovec> & lst)
|
||||
{
|
||||
size_t done = 0;
|
||||
size_t from = cl->write_op_pos;
|
||||
auto op_write_buf = [&](uint8_t *src, size_t src_len, bool skip_csum)
|
||||
{
|
||||
if (lst.size() >= IOV_MAX)
|
||||
return false;
|
||||
if (from < src_len)
|
||||
{
|
||||
if (cl->write_csum_state && !skip_csum)
|
||||
XXH3_64bits_update(cl->write_csum_state, src+from, src_len-from);
|
||||
lst.push_back((iovec){ .iov_base = src+from, .iov_len = src_len-from });
|
||||
cl->write_op_pos += src_len-from;
|
||||
from = 0;
|
||||
}
|
||||
else
|
||||
from -= src_len;
|
||||
return true;
|
||||
};
|
||||
// Encrypt headers and data except read/write data
|
||||
auto to_ssl = [&](uint8_t *src, size_t src_len, bool skip_csum)
|
||||
{
|
||||
return ssl_op_write_buf(cl, src, src_len, skip_csum, from, done);
|
||||
};
|
||||
int i = 0;
|
||||
bool full_hdr = false;
|
||||
bool full_op = false;
|
||||
do
|
||||
{
|
||||
if (!full_hdr)
|
||||
full_hdr = op_write_headers(cl->write_op, to_ssl, cl->proto_csum_status != MSGR_CSUM_FULL);
|
||||
if (full_hdr && op_has_data_for_ssl(cl->write_op))
|
||||
{
|
||||
for (; i < cl->write_op->iov.count; i++)
|
||||
if (!ssl_op_write_buf(cl, (uint8_t*)cl->write_op->iov.buf[i].iov_base, cl->write_op->iov.buf[i].iov_len, false, from, done))
|
||||
break;
|
||||
full_op = true;
|
||||
}
|
||||
if (cl->peer_state == PEER_STOPPED)
|
||||
return;
|
||||
if (!ssl_do_encrypt(cl))
|
||||
return;
|
||||
} while (!full_op);
|
||||
// Non-TLS-encrypted operation data
|
||||
if (op_has_data_for_nonssl(cl->write_op))
|
||||
{
|
||||
if (cl->write_op->enc)
|
||||
{
|
||||
if (lst.size() >= IOV_MAX)
|
||||
return;
|
||||
// No way except to allocate a temporary buffer and encrypt data to it
|
||||
assert(cl->write_op->req.hdr.opcode == OSD_OP_WRITE);
|
||||
size_t remsize = cl->write_op->req.rw.len - from + (from % 16);
|
||||
assert(remsize > 0);
|
||||
assert(!cl->write_op->enc_buf);
|
||||
cl->write_op->enc_buf = (uint8_t*)malloc_or_die(remsize);
|
||||
size_t done = 0;
|
||||
bool end = op_encrypted_copy_data_to(cl, cl->write_op->enc_buf, remsize, from, done);
|
||||
assert(end);
|
||||
lst.push_back((iovec){ .iov_base = cl->write_op->enc_buf, .iov_len = remsize });
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < cl->write_op->iov.count; i++)
|
||||
{
|
||||
if (!op_write_buf((uint8_t*)cl->write_op->iov.buf[i].iov_base, cl->write_op->iov.buf[i].iov_len, false))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TLS-encrypted checksum (uh oh...)
|
||||
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
|
||||
cl->proto_csum_status == MSGR_CSUM_PAYLOAD && cl->write_op_pos > OSD_PACKET_SIZE)
|
||||
{
|
||||
if (!from)
|
||||
cl->write_op->csum = XXH3_64bits_digest(cl->write_csum_state);
|
||||
if (!ssl_op_write_buf(cl, (uint8_t*)&cl->write_op->csum, 8, true, from, done))
|
||||
return;
|
||||
if (!ssl_do_encrypt(cl))
|
||||
return;
|
||||
}
|
||||
cl->write_op = NULL;
|
||||
cl->write_op_pos = 0;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
#ifdef WITH_RDMA
|
||||
#include "msgr_rdma.h"
|
||||
#endif
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
void osd_client_t::cancel_ops()
|
||||
{
|
||||
@@ -239,4 +245,18 @@ osd_client_t::~osd_client_t()
|
||||
XXH3_freeState(write_csum_state);
|
||||
write_csum_state = NULL;
|
||||
}
|
||||
#ifdef WITH_OPENSSL
|
||||
if (ssl_cli)
|
||||
{
|
||||
SSL_free(ssl_cli);
|
||||
ssl_cli = NULL;
|
||||
write_to_ssl = NULL;
|
||||
read_from_ssl = NULL;
|
||||
}
|
||||
if (ssl_out_buf)
|
||||
{
|
||||
free(ssl_out_buf);
|
||||
ssl_out_buf = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
|
||||
|
||||
Name: Vitastor
|
||||
Description: Vitastor client library
|
||||
Version: 3.0.8
|
||||
Version: 3.0.9
|
||||
Libs: -L${libdir} -lvitastor_client
|
||||
Cflags: -I${includedir}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "xxhash.h"
|
||||
#include "addr_util.h"
|
||||
#include "osd_primary.h"
|
||||
#include "osd.h"
|
||||
@@ -16,46 +15,8 @@
|
||||
#include "str_util.h"
|
||||
#include "json_util.h"
|
||||
|
||||
void xxhash_run_test(XXH3_state_t *st, void *buf, size_t size)
|
||||
{
|
||||
timespec tv, tv1;
|
||||
clock_gettime(CLOCK_REALTIME, &tv);
|
||||
uint64_t res = 1;
|
||||
uint64_t done = 0;
|
||||
while (true)
|
||||
{
|
||||
XXH3_64bits_reset(st);
|
||||
XXH3_64bits_update(st, buf, size);
|
||||
res *= XXH3_64bits_digest(st);
|
||||
done++;
|
||||
if (!(done % 100000))
|
||||
{
|
||||
clock_gettime(CLOCK_REALTIME, &tv1);
|
||||
if ((tv1.tv_sec-tv.tv_sec)*1000 + (tv1.tv_nsec-tv.tv_nsec)/1000000 > 1000)
|
||||
break;
|
||||
}
|
||||
}
|
||||
double sec = (tv1.tv_sec-tv.tv_sec) + (tv1.tv_nsec-tv.tv_nsec)/1000000000.0;
|
||||
fprintf(stderr, "xxhash3: %lu %zu byte blocks in %.2f sec = %.1f MB/s\n",
|
||||
done, size, sec, done*size/sec/1024/1024);
|
||||
}
|
||||
|
||||
void xxhash_bench()
|
||||
{
|
||||
std::vector<uint8_t> buf;
|
||||
buf.resize(128*1024);
|
||||
for (size_t i = 0; i < buf.size(); i++)
|
||||
buf[i] = ((i+37)*3) % 255;
|
||||
XXH3_state_t *st = XXH3_createState();
|
||||
xxhash_run_test(st, buf.data(), 4096);
|
||||
xxhash_run_test(st, buf.data(), buf.size());
|
||||
XXH3_freeState(st);
|
||||
}
|
||||
|
||||
osd_t::osd_t(const json11::Json & config, ring_loop_t *ringloop)
|
||||
{
|
||||
xxhash_bench();
|
||||
|
||||
zero_buffer_size = 1<<20;
|
||||
zero_buffer = malloc_or_die(zero_buffer_size);
|
||||
memset(zero_buffer, 0, zero_buffer_size);
|
||||
|
||||
@@ -348,10 +348,17 @@ void osd_t::exec_show_config(osd_op_t *cur_op)
|
||||
cl->read_op_id = cur_op->req.hdr.id + 1;
|
||||
}
|
||||
auto features = json11::Json::object{ { "pg_locks", true } };
|
||||
if (req_json["features"]["proto_checksums"].bool_value() && msgr.use_proto_checksums)
|
||||
if (msgr.use_proto_checksums)
|
||||
{
|
||||
cl->proto_csum_status = MSGR_PEER_CSUM_IN;
|
||||
features["proto_checksums"] = true;
|
||||
auto peer_csums = req_json["features"]["proto_checksums"].uint64_value();
|
||||
if (peer_csums == MSGR_CSUM_FULL || peer_csums == MSGR_CSUM_PAYLOAD)
|
||||
{
|
||||
if (msgr.use_proto_checksums == MSGR_CSUM_FULL && peer_csums == MSGR_CSUM_FULL)
|
||||
cl->proto_csum_status = MSGR_CSUM_FULL|MSGR_CSUM_NEG;
|
||||
else
|
||||
cl->proto_csum_status = MSGR_CSUM_PAYLOAD|MSGR_CSUM_NEG;
|
||||
features["proto_checksums"] = msgr.use_proto_checksums;
|
||||
}
|
||||
}
|
||||
// Expose sensitive configuration values so peers can check them
|
||||
json11::Json::object wire_config = json11::Json::object {
|
||||
|
||||
@@ -41,7 +41,7 @@ add_executable(test_heap
|
||||
../blockstore/multilist.cpp
|
||||
../blockstore/blockstore_heap.cpp
|
||||
../util/crc32c.c
|
||||
../util/xxhash.c
|
||||
../util/xxh_x86dispatch.c
|
||||
../util/allocator.cpp
|
||||
../blockstore/blockstore_disk.cpp
|
||||
../util/str_util.cpp
|
||||
@@ -62,6 +62,14 @@ target_link_libraries(test_cas
|
||||
vitastor_client
|
||||
)
|
||||
|
||||
# http_hello
|
||||
add_executable(http_hello
|
||||
http_hello.cpp
|
||||
)
|
||||
target_link_libraries(http_hello
|
||||
vitastor_client
|
||||
)
|
||||
|
||||
# test_crc32
|
||||
add_executable(test_crc32
|
||||
test_crc32.cpp
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "http_client.h"
|
||||
#include "ringloop.h"
|
||||
#include "epoll_manager.h"
|
||||
#include "addr_util.h"
|
||||
|
||||
int main(int narg, char *args[])
|
||||
{
|
||||
ring_consumer_t looper;
|
||||
ring_loop_t *ringloop = new ring_loop_t(RINGLOOP_DEFAULT_SIZE);
|
||||
epoll_manager_t *epmgr = new epoll_manager_t(ringloop);
|
||||
// Accept new connections
|
||||
int listen_fd = create_and_bind_socket("0.0.0.0", 8085, 128, NULL);
|
||||
fcntl(listen_fd, F_SETFL, fcntl(listen_fd, F_GETFL, 0) | O_NONBLOCK);
|
||||
std::string error;
|
||||
auto http_ctx = http_context_init(epmgr->tfd, "", "", "", false, error);
|
||||
epmgr->set_fd_handler(listen_fd, false, [http_ctx](int listen_fd, int events)
|
||||
{
|
||||
sockaddr_storage addr;
|
||||
socklen_t peer_addr_size = sizeof(addr);
|
||||
int peer_fd;
|
||||
while ((peer_fd = accept(listen_fd, (sockaddr*)&addr, &peer_addr_size)) >= 0)
|
||||
{
|
||||
assert(peer_fd != 0);
|
||||
fcntl(peer_fd, F_SETFL, fcntl(peer_fd, F_GETFL, 0) | O_NONBLOCK);
|
||||
int one = 1;
|
||||
setsockopt(peer_fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one));
|
||||
auto co = http_init(http_ctx);
|
||||
http_serve(co, peer_fd, (http_options_t){}, [co](http_message_t *msg)
|
||||
{
|
||||
if (msg->eof)
|
||||
{
|
||||
http_destroy(co);
|
||||
return;
|
||||
}
|
||||
http_reply(co, "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nContent-Length: 13\r\n\r\nHello, world!");
|
||||
});
|
||||
}
|
||||
});
|
||||
while (true)
|
||||
{
|
||||
ringloop->loop();
|
||||
ringloop->wait();
|
||||
}
|
||||
delete epmgr;
|
||||
delete ringloop;
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user