diff --git a/.drone.jsonnet b/.drone.jsonnet index d0b1adc6..3f1efb98 100644 --- a/.drone.jsonnet +++ b/.drone.jsonnet @@ -299,6 +299,8 @@ local mac_builder(name, debian_pipeline('Debian sid/Debug', docker_base + 'debian-sid', build_type='Debug'), clang(16), full_llvm(16), + clang(19), + full_llvm(19), debian_pipeline('Debian sid -GSO', docker_base + 'debian-sid', cmake_extra='-DLIBQUIC_SEND=sendmmsg'), debian_pipeline('Debian sid -mmsg', docker_base + 'debian-sid', cmake_extra='-DLIBQUIC_SEND=sendmsg -DLIBQUIC_RECVMMSG=OFF'), debian_pipeline('Debian sid -GSO/Debug', docker_base + 'debian-sid', build_type='Debug', cmake_extra='-DLIBQUIC_SEND=sendmmsg'), diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index c3fef889..63237384 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -73,20 +73,31 @@ if(NOT NGTCP2_FOUND OR NOT NGTCP2_GNUTLS_FOUND) endif() # oxen-logging -if (NOT TARGET oxen::logging) +if(BUILD_STATIC_DEPS) + message(STATUS "Building static dependencies; using oxen-logging submodule") + set(OXEN_LOGGING_FORCE_SUBMODULES ON CACHE INTERNAL "") +endif() + +if(NOT OXEN_LOGGING_FORCE_SUBMODULES AND CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 19.0.0) + message(STATUS "Forcing oxen-logging submodules; Clang version > 19 requires fmt version > 10") + set(OXEN_LOGGING_FORCE_SUBMODULES ON CACHE INTERNAL "") +endif() + +if (NOT OXEN_LOGGING_FORCE_SUBMODULES AND NOT TARGET oxen::logging) message(STATUS "Target oxen::logging not found; using submodule") - if(BUILD_STATIC_DEPS) - set(OXEN_LOGGING_FORCE_SUBMODULES ON CACHE INTERNAL "") - endif() - add_subdirectory(oxen-logging) + set(OXEN_LOGGING_FORCE_SUBMODULES ON CACHE INTERNAL "") else() message(STATUS "Target oxen::logging already found!") endif() + +if (OXEN_LOGGING_FORCE_SUBMODULES) + add_subdirectory(oxen-logging) +endif() oxen_logging_add_source_dir("${PROJECT_SOURCE_DIR}") # oxenc if (NOT TARGET oxenc) - system_or_submodule(OXENC oxenc liboxenc>=1.1.0 oxen-encoding) + system_or_submodule(OXENC oxenc liboxenc>=1.2.0 oxen-encoding) endif() # libevent diff --git a/include/oxen/quic/btstream.hpp b/include/oxen/quic/btstream.hpp index d194e25d..71da21ab 100644 --- a/include/oxen/quic/btstream.hpp +++ b/include/oxen/quic/btstream.hpp @@ -81,7 +81,7 @@ namespace oxen::quic explicit operator bool() const { return !timed_out && !is_error(); } template - std::basic_string_view view() const + const_span span() const { return {reinterpret_cast(data.data()), data.size()}; } diff --git a/include/oxen/quic/connection.hpp b/include/oxen/quic/connection.hpp index c898b0aa..0427caab 100644 --- a/include/oxen/quic/connection.hpp +++ b/include/oxen/quic/connection.hpp @@ -126,8 +126,8 @@ namespace oxen::quic void send_datagram(std::vector&& buf) { auto keep_alive = std::make_shared>(std::move(buf)); - std::basic_string_view view{keep_alive->data(), keep_alive->size()}; - send_datagram(str_to_bspan(view), std::move(keep_alive)); + auto bsp = vec_to_span(*keep_alive); + send_datagram(bsp, std::move(keep_alive)); } template @@ -138,6 +138,12 @@ namespace oxen::quic send_datagram(str_to_bspan(view), std::move(keep_alive)); } + template + void send_datagram(const_span data, std::shared_ptr keep_alive = nullptr) + { + send_datagram(span_to_span(data), std::move(keep_alive)); + } + virtual void send_datagram(bspan data, std::shared_ptr keep_alive = nullptr) = 0; virtual Endpoint& endpoint() = 0; diff --git a/include/oxen/quic/format.hpp b/include/oxen/quic/format.hpp index e38d7fa9..c8f7e733 100644 --- a/include/oxen/quic/format.hpp +++ b/include/oxen/quic/format.hpp @@ -6,19 +6,21 @@ // library). #include "formattable.hpp" +#include "utils.hpp" #include #include #include +#include namespace oxen::quic { struct buffer_printer { private: - std::basic_string_view buf; + bspan buf; public: template @@ -64,14 +66,13 @@ namespace fmt } }; - template - struct formatter : formatter + template <> + struct formatter : formatter { template - auto format(const T& val, FormatContext& ctx) const + auto format(const oxen::quic::cspan& val, FormatContext& ctx) const { - return formatter::format( - std::string_view{reinterpret_cast(val.data()), val.size()}, ctx); + return formatter::format({val.data(), val.size()}, ctx); } }; } // namespace fmt diff --git a/include/oxen/quic/opt.hpp b/include/oxen/quic/opt.hpp index 06702b3f..5402a339 100644 --- a/include/oxen/quic/opt.hpp +++ b/include/oxen/quic/opt.hpp @@ -35,8 +35,9 @@ namespace oxen::quic const DIR direction; std::vector> protos; - constexpr alpns(DIR d, std::vector>&& alpns) : direction{d}, protos{std::move(alpns)} - {} + // constexpr alpns(DIR d, std::vector>&& alpns) : direction{d}, + // protos{std::move(alpns)} + // {} template requires(std::same_as && ...) diff --git a/include/oxen/quic/udp.hpp b/include/oxen/quic/udp.hpp index 47f793be..cbe643c7 100644 --- a/include/oxen/quic/udp.hpp +++ b/include/oxen/quic/udp.hpp @@ -43,9 +43,9 @@ namespace oxen::quic // Return a string_view type, starting from index `pos` template - std::basic_string_view data(size_t pos = 0) const + const_span data(size_t pos = 0) const { - return std::basic_string_view{reinterpret_cast(data_sp.data() + pos), data_sp.size() - pos}; + return const_span{reinterpret_cast(data_sp.data() + pos), data_sp.size() - pos}; } /// Constructs a packet from a path and data view: diff --git a/src/gnutls_session.cpp b/src/gnutls_session.cpp index a2a6deab..1c398603 100644 --- a/src/gnutls_session.cpp +++ b/src/gnutls_session.cpp @@ -345,7 +345,7 @@ namespace oxen::quic if (auto rv = gnutls_alpn_get_selected_protocol(session, &_alpn); rv < 0) { - auto err = fmt::format("{} called, but ALPN negotiation incomplete.", __PRETTY_FUNCTION__); + auto err = "{} called, but ALPN negotiation incomplete."_format(__PRETTY_FUNCTION__); log::error(log_cat, "{}", err); throw std::logic_error(err); } diff --git a/tests/001-handshake.cpp b/tests/001-handshake.cpp index c7aa581c..eb77b6ca 100644 --- a/tests/001-handshake.cpp +++ b/tests/001-handshake.cpp @@ -421,9 +421,8 @@ namespace oxen::quic::test auto [client_tls, server_tls] = defaults::tls_creds_from_ed_keys(); - server_tls->set_key_verify_callback([](const uspan& key, const uspan&) { - return key == convert_sv(std::string_view{defaults::CLIENT_PUBKEY}); - }); + server_tls->set_key_verify_callback( + [](const uspan& key, const uspan&) { return key == str_to_uspan(defaults::CLIENT_PUBKEY); }); Address server_local{}; Address client_local{}; diff --git a/tests/002-send-receive.cpp b/tests/002-send-receive.cpp index acb4dbcb..95c60890 100644 --- a/tests/002-send-receive.cpp +++ b/tests/002-send-receive.cpp @@ -242,7 +242,7 @@ namespace oxen::quic::test { auto server_bp_cb = callback_waiter{[&](message msg) { if (msg) - log::info(test_cat, "Server bparser received: {}", msg.view()); + log::info(test_cat, "Server bparser received: {}", msg.span()); }}; stream_constructor_callback server_constructor = [&](Connection& c, Endpoint& e, std::optional) { @@ -271,7 +271,7 @@ namespace oxen::quic::test auto server_bp_cb = callback_waiter{[&](message msg) { if (msg) { - log::info(test_cat, "Server bparser received: {}", msg.view()); + log::info(test_cat, "Server bparser received: {}", msg.span()); msg.respond("test_response"s); } }}; @@ -279,7 +279,7 @@ namespace oxen::quic::test auto client_bp_cb = callback_waiter{[&](message msg) { if (msg) { - log::info(test_cat, "Client bparser received: {}", msg.view()); + log::info(test_cat, "Client bparser received: {}", msg.span()); msg.respond("test_response"s); } }}; @@ -315,7 +315,7 @@ namespace oxen::quic::test auto server_bp_cb = callback_waiter{[&](message msg) { if (msg) { - log::info(test_cat, "Server bparser received: {}", msg.view()); + log::info(test_cat, "Server bparser received: {}", msg.span()); msg.respond("test_response"s); } }}; @@ -323,7 +323,7 @@ namespace oxen::quic::test auto client_bp_cb = callback_waiter{[&](message msg) { if (msg) { - log::info(test_cat, "Client bparser received: {}", msg.view()); + log::info(test_cat, "Client bparser received: {}", msg.span()); msg.respond("test_response"s); } }}; @@ -443,7 +443,7 @@ namespace oxen::quic::test auto server_handler = [&](message msg) { if (msg) { - log::info(test_cat, "Server bparser received: {}", msg.view()); + log::info(test_cat, "Server bparser received: {}", msg.span()); if (msg.body() == req_msg) msg.respond(res_msg); else @@ -456,7 +456,7 @@ namespace oxen::quic::test { std::lock_guard lock{mut}; responses++; - log::debug(test_cat, "Client bparser received response {}: {}", responses, msg.view()); + log::debug(test_cat, "Client bparser received response {}: {}", responses, msg.span()); if (msg.body() == res_msg) good_responses++; if (responses == num_requests) @@ -534,7 +534,7 @@ namespace oxen::quic::test if (msg) { ++responses; - log::debug(test_cat, "Client bparser received response {}: {}", responses.load(), msg.view()); + log::debug(test_cat, "Client bparser received response {}: {}", responses.load(), msg.span()); if (msg.body() == res_msg) ++good_responses; if (responses == num_requests) @@ -582,7 +582,7 @@ namespace oxen::quic::test auto client_reply_handler = [&](message msg) mutable { if (msg) - log::debug(test_cat, "Client bparser received response: {}", msg.view()); + log::debug(test_cat, "Client bparser received response: {}", msg.span()); else log::debug(test_cat, "got back a failed message response"); }; diff --git a/tests/004-streams.cpp b/tests/004-streams.cpp index 0b1b6462..616e5998 100644 --- a/tests/004-streams.cpp +++ b/tests/004-streams.cpp @@ -609,7 +609,7 @@ namespace oxen::quic::test stream_data_callback server_data_cb = [&](Stream& s, bspan) { std::lock_guard lock{mut}; server_seen[s.stream_id()]++; - s.send("🤔 {}"_format(s.stream_id())); + s.send("stupid emojis {}"_format(s.stream_id())); }; Address server_local{}; @@ -662,7 +662,7 @@ namespace oxen::quic::test auto s3 = client_ci->open_stream(); CHECK(client_stream_ctor_count.load() == 2); - REQUIRE(std::dynamic_pointer_cast(s1)); + REQUIRE(std::dynamic_pointer_cast(s3)); auto s4 = client_ci->open_stream(); CHECK(client_stream_ctor_count.load() == 3); @@ -678,10 +678,10 @@ namespace oxen::quic::test require_future(cf2); require_future(cf3); require_future(cf4); - CHECK(cf1.get() == "🤔 0"_bsp); - CHECK(cf2.get() == "🤔 4"_bsp); - CHECK(cf3.get() == "🤔 8"_bsp); - CHECK(cf4.get() == "🤔 12"_bsp); + CHECK(cf1.get() == "stupid emojis 0"_bsp); + CHECK(cf2.get() == "stupid emojis 4"_bsp); + CHECK(cf3.get() == "stupid emojis 8"_bsp); + CHECK(cf4.get() == "stupid emojis 12"_bsp); { std::lock_guard lock{mut}; @@ -915,7 +915,7 @@ namespace oxen::quic::test auto server_endpoint = test_net.endpoint(server_local); server_endpoint->listen(server_tls, [&](Stream& s, bspan data) { count += data.size(); - log::debug(test_cat, "Got some data {}, replying with '{}'", data, count); + log::debug(test_cat, "Got some data {}, replying with '{}'", buffer_printer{data}, count); s.send("{}"_format(count)); }); diff --git a/tests/007-datagrams.cpp b/tests/007-datagrams.cpp index ea4131b1..339a6271 100644 --- a/tests/007-datagrams.cpp +++ b/tests/007-datagrams.cpp @@ -332,14 +332,14 @@ namespace oxen::quic::test std::this_thread::sleep_for(5ms); auto max_size = conn_interface->get_max_datagram_size(); - std::basic_string good_msg{}; + std::vector good_msg{}; uint8_t v{0}; while (good_msg.size() < max_size) - good_msg += v++; + good_msg.emplace_back(v++); for (int i = 0; i < n; ++i) - conn_interface->send_datagram(std::basic_string_view{good_msg}); + conn_interface->send_datagram(bspan{reinterpret_cast(good_msg.data()), good_msg.size()}); for (auto& f : data_futures) require_future(f); @@ -416,20 +416,20 @@ namespace oxen::quic::test std::this_thread::sleep_for(5ms); auto max_size = conn_interface->get_max_datagram_size(); - std::basic_string big_msg{}, small_msg{}; + std::vector big_msg{}, small_msg{}; uint8_t v{0}; while (big_msg.size() < max_size) - big_msg += v++; + big_msg.emplace_back(v++); while (small_msg.size() < 500) - small_msg += v++; + small_msg.emplace_back(v++); - conn_interface->send_datagram(std::basic_string_view{big_msg}); - conn_interface->send_datagram(std::basic_string_view{big_msg}); - conn_interface->send_datagram(std::basic_string_view{small_msg}); - conn_interface->send_datagram(std::basic_string_view{big_msg}); - conn_interface->send_datagram(std::basic_string_view{small_msg}); + conn_interface->send_datagram(uspan{big_msg}); + conn_interface->send_datagram(uspan{big_msg}); + conn_interface->send_datagram(uspan{small_msg}); + conn_interface->send_datagram(uspan{big_msg}); + conn_interface->send_datagram(uspan{small_msg}); for (auto& f : data_futures) require_future(f); @@ -585,17 +585,17 @@ namespace oxen::quic::test std::this_thread::sleep_for(5ms); auto max_size = conn_interface->get_max_datagram_size(); - std::basic_string big{}, medium{}, small{}; + std::vector big{}, medium{}, small{}; uint8_t v{0}; while (big.size() < max_size * 2 / 3) - big += v++; + big.emplace_back(v++); while (medium.size() < max_size / 2 - 100) - medium += v++; + medium.emplace_back(v++); while (small.size() < 50) - small += v++; + small.emplace_back(v++); TestHelper::enable_dgram_flip_flop(*conn_interface); @@ -603,19 +603,19 @@ namespace oxen::quic::test std::future ftr = pr.get_future(); client->call([&]() { - conn_interface->send_datagram(std::basic_string_view{big}); - conn_interface->send_datagram(std::basic_string_view{small}); - conn_interface->send_datagram(std::basic_string_view{small}); - conn_interface->send_datagram(std::basic_string_view{big}); - conn_interface->send_datagram(std::basic_string_view{big}); - conn_interface->send_datagram(std::basic_string_view{small}); - conn_interface->send_datagram(std::basic_string_view{medium}); - conn_interface->send_datagram(std::basic_string_view{big}); - conn_interface->send_datagram(std::basic_string_view{small}); - conn_interface->send_datagram(std::basic_string_view{small}); - conn_interface->send_datagram(std::basic_string_view{small}); - conn_interface->send_datagram(std::basic_string_view{small}); - conn_interface->send_datagram(std::basic_string_view{small}); + conn_interface->send_datagram(uspan{big}); + conn_interface->send_datagram(uspan{small}); + conn_interface->send_datagram(uspan{small}); + conn_interface->send_datagram(uspan{big}); + conn_interface->send_datagram(uspan{big}); + conn_interface->send_datagram(uspan{small}); + conn_interface->send_datagram(uspan{medium}); + conn_interface->send_datagram(uspan{big}); + conn_interface->send_datagram(uspan{small}); + conn_interface->send_datagram(uspan{small}); + conn_interface->send_datagram(uspan{small}); + conn_interface->send_datagram(uspan{small}); + conn_interface->send_datagram(uspan{small}); pr.set_value(); }); diff --git a/tests/015-bt-encoding.cpp b/tests/015-bt-encoding.cpp index d49647cc..3dfe0692 100644 --- a/tests/015-bt-encoding.cpp +++ b/tests/015-bt-encoding.cpp @@ -52,13 +52,13 @@ namespace oxen::quic::test Address client_local{}; auto server_bp_cb = callback_waiter{[&](message msg) { - log::debug(test_cat, "Server bparser received: {}", msg.view()); + log::debug(test_cat, "Server bparser received: {}", msg.span()); CHECK(bt_decode(msg.body())); msg.respond(msg.body()); }}; auto client_bp_cb = callback_waiter{[&](message msg) { - log::debug(test_cat, "Client bparser received: {}", msg.view()); + log::debug(test_cat, "Client bparser received: {}", msg.span()); CHECK(bt_decode(msg.body())); }}; @@ -112,36 +112,36 @@ namespace oxen::quic::test std::shared_ptr node_a_bp, node_b_bp, node_c_bp; auto node_a_response_cb = callback_waiter{[&](message msg) { - log::debug(test_cat, "Node A received response from Node B: {}", msg.view()); + log::debug(test_cat, "Node A received response from Node B: {}", msg.span()); CHECK(bt_decode(msg.body())); }}; auto node_a_bp_cb = [&](message msg) { - log::debug(test_cat, "Node A received request from Node C: {}", msg.view()); + log::debug(test_cat, "Node A received request from Node C: {}", msg.span()); CHECK(bt_decode(msg.body())); msg.respond(msg.body()); }; auto node_b_bp_cb = [&](message msg) { - log::debug(test_cat, "Node B received request from Node A: {}", msg.view()); + log::debug(test_cat, "Node B received request from Node A: {}", msg.span()); CHECK(bt_decode(msg.body())); - log::debug(test_cat, "Node B chaining request to Node C", msg.view()); + log::debug(test_cat, "Node B chaining request to Node C", msg.span()); auto body = msg.body_str(); node_b_bp->command(TEST_ENDPOINT, std::move(body), [prev = std::move(msg)](message msg) mutable { - log::debug(test_cat, "Node B received response from Node C: {}", msg.view()); + log::debug(test_cat, "Node B received response from Node C: {}", msg.span()); prev.respond(msg.body()); }); }; auto node_c_bp_cb = [&](message msg) { - log::debug(test_cat, "Node C received request from Node B: {}", msg.view()); + log::debug(test_cat, "Node C received request from Node B: {}", msg.span()); CHECK(bt_decode(msg.body())); - log::debug(test_cat, "Node C chaining request to Node A", msg.view()); + log::debug(test_cat, "Node C chaining request to Node A", msg.span()); auto body = msg.body_str(); node_c_bp->command(TEST_ENDPOINT, std::move(body), [prev = std::move(msg)](message msg) mutable { - log::debug(test_cat, "Node C received response from Node A: {}", msg.view()); + log::debug(test_cat, "Node C received response from Node A: {}", msg.span()); prev.respond(msg.body()); }); }; diff --git a/tests/speedtest-client.cpp b/tests/speedtest-client.cpp index fd53817a..462e65a0 100644 --- a/tests/speedtest-client.cpp +++ b/tests/speedtest-client.cpp @@ -111,7 +111,7 @@ int main(int argc, char* argv[]) std::atomic failed = false; size_t next_buf = 0; - std::basic_string hash; + std::vector hash; uint8_t checksum = 0; gnutls_hash_hd_t sent_hasher, recv_hasher; diff --git a/tests/speedtest-server.cpp b/tests/speedtest-server.cpp index d35f5425..277f6b32 100644 --- a/tests/speedtest-server.cpp +++ b/tests/speedtest-server.cpp @@ -128,8 +128,7 @@ int main(int argc, char* argv[]) if (info.received >= info.expected) { - std::basic_string final_hash; - final_hash.resize(33); + std::vector final_hash(33); gnutls_hash_output(info.hasher, final_hash.data()); final_hash[32] = info.checksum; diff --git a/tests/utils.hpp b/tests/utils.hpp index 77ce5680..efef5492 100644 --- a/tests/utils.hpp +++ b/tests/utils.hpp @@ -9,6 +9,7 @@ using namespace oxenc; #include #include #include +#include #include #include