From bdb89474acbe9cb18fe12401e9ed52d72e46f151 Mon Sep 17 00:00:00 2001 From: Peter Eisenlohr Date: Mon, 7 Sep 2026 19:13:55 +0000 Subject: [PATCH 1/2] cleanup: move the last ngtcp2 example helpers into h3_common src/ngtcp2/ was the final remnant of the vendored ngtcp2 examples. Its five helpers all belong to the HTTP/3 backend and nothing else, so they move into anyhttp::http3 next to the other shared QUIC/HTTP/3 building blocks, keeping the provenance and MIT note in a banner comment: network.h -> sockaddr_union, Address util.{h,cc} -> timestamp(), straddr(), format_hex() shared.{h,cc}-> msghdr_get_local_addr(), set_port() Two of them are simplified rather than transplanted verbatim: format_hex() collapses from three iterator-constrained overloads plus a 512-byte lookup table to one format_hex(const uint8_t*, size_t), as both call sites only ever pass cid.data/cid.datalen, and straddr() reports through loge() and builds its result with std::format instead of std::cerr and manual appends. h3_session.cpp is already in anyhttp::http3 and calls them unqualified; h3_server.cpp and h3_client.cpp pull the names in with using declarations alongside the existing log_headers/make_nv ones. to_ngtcp2_address() becomes to_address(), the type it produces no longer being ngtcp2::Address. The vendored sources drop out of src/CMakeLists.txt (the *.cpp glob covers h3_common.cpp) and out of the coverage ignore regex. src/ngtcp2/README.md also noted that the devcontainer installs the upstream examples as osslclient and osslserver; that note moves to HTTP3.md, where it already pointed. Co-Authored-By: Claude Opus 5 --- CMakeLists.txt | 2 +- HTTP3.md | 5 ++ include/anyhttp/h3_common.hpp | 46 ++++++++++++++ src/CMakeLists.txt | 5 -- src/h3_client.cpp | 8 +-- src/h3_common.cpp | 108 +++++++++++++++++++++++++++++++++ src/h3_server.cpp | 40 ++++++------ src/h3_session.cpp | 17 +++--- src/ngtcp2/README.md | 12 ---- src/ngtcp2/network.h | 50 --------------- src/ngtcp2/shared.cc | 85 -------------------------- src/ngtcp2/shared.h | 44 -------------- src/ngtcp2/util.cc | 64 -------------------- src/ngtcp2/util.h | 111 ---------------------------------- 14 files changed, 192 insertions(+), 405 deletions(-) delete mode 100644 src/ngtcp2/README.md delete mode 100644 src/ngtcp2/network.h delete mode 100644 src/ngtcp2/shared.cc delete mode 100644 src/ngtcp2/shared.h delete mode 100644 src/ngtcp2/util.cc delete mode 100644 src/ngtcp2/util.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e4c361a..f60785f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,7 +116,7 @@ if (ENABLE_COVERAGE) set(COVERAGE_HTML_DIR "${CMAKE_BINARY_DIR}/coverage_report") set(COVERAGE_MERGE_SCRIPT "${CMAKE_SOURCE_DIR}/cmake/merge_profraw.cmake") set(COVERAGE_TEST_BIN "${CMAKE_BINARY_DIR}/test/test_all") - set(LLVM_COV_IGNORE_REGEX "/usr/|${CMAKE_BINARY_DIR}/|${CMAKE_SOURCE_DIR}/test/|${CMAKE_SOURCE_DIR}/src/ngtcp2/") + set(LLVM_COV_IGNORE_REGEX "/usr/|${CMAKE_BINARY_DIR}/|${CMAKE_SOURCE_DIR}/test/") add_custom_target(coverage COMMAND ${CMAKE_COMMAND} -E rm -rf ${COVERAGE_RAW_DIR} ${COVERAGE_HTML_DIR} diff --git a/HTTP3.md b/HTTP3.md index 01ffb65..ecd1be1 100644 --- a/HTTP3.md +++ b/HTTP3.md @@ -1,5 +1,10 @@ # HTTP/3 Manual Testing +`osslclient` and `osslserver` are the [ngtcp2](https://github.com/ngtcp2/ngtcp2) example +client and server; the devcontainer image builds them from upstream and installs them as +`/usr/local/bin/osslclient` and `/usr/local/bin/osslserver`. A few small helpers from the +same examples live in `anyhttp/h3_common.hpp`. + ```sh osslserver ::1 8080 pki/out/server-key.pem pki/out/server-chain.pem ``` diff --git a/include/anyhttp/h3_common.hpp b/include/anyhttp/h3_common.hpp index 63e6b1e..492eb98 100644 --- a/include/anyhttp/h3_common.hpp +++ b/include/anyhttp/h3_common.hpp @@ -1,7 +1,13 @@ #pragma once #include +#include +#include +#include +#include + +#include #include #include #include @@ -46,6 +52,46 @@ void log_headers(std::string_view log_prefix, /// still pays for the formatting, while a NULL one makes ngtcp2 skip that work entirely. void ngtcp2_log_printf(void* user, const char* fmt, ...) noexcept; +// ================================================================================================= +// +// Below: helpers taken from the ngtcp2 examples (https://github.com/ngtcp2/ngtcp2, examples/, +// v1.25.0, MIT licensed), reduced to what anyhttp actually uses. They used to be vendored +// verbatim under src/ngtcp2/. +// + +/// A socket address of any of the families we speak, as ngtcp2 hands them around. +union sockaddr_union +{ + sockaddr_storage storage; + sockaddr sa; + sockaddr_in6 in6; + sockaddr_in in; +}; + +/// A socket address together with its actual length and the interface it was seen on. +struct Address +{ + socklen_t len; + union sockaddr_union su; + uint32_t ifindex; +}; + +/// Returns the local (destination) address of the packet described by \p msg, as delivered by +/// IP(V6)_PKTINFO. \p family is the address family the packet was received from. +std::optional
msghdr_get_local_addr(msghdr* msg, int family); + +/// Copies the port of \p src into \p dst. +void set_port(Address& dst, const Address& src); + +/// The current steady clock reading in nanoseconds, which is the timestamp ngtcp2 expects. +ngtcp2_tstamp timestamp(); + +/// Stringifies \p sa of length \p salen in the format "[IP]:PORT". +std::string straddr(const sockaddr* sa, socklen_t salen); + +/// Formats \p len bytes at \p data as lowercase hex, for logging connection IDs. +std::string format_hex(const uint8_t* data, size_t len); + // ================================================================================================= } // namespace anyhttp::http3 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 780e5c8..e7414a2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,11 +22,6 @@ target_sources(anyhttp PRIVATE ${anyhttp_sources}) target_include_directories(anyhttp PUBLIC ../include) target_include_directories(anyhttp PRIVATE "/opt/nghttp3/build/include") -# -# Small helpers taken from the ngtcp2 examples (see ngtcp2/README.md). -# -target_sources(anyhttp PRIVATE ngtcp2/shared.cc ngtcp2/util.cc) - target_link_libraries(anyhttp PRIVATE Threads::Threads) target_link_libraries(anyhttp PRIVATE OpenSSL::SSL) target_link_libraries(anyhttp PRIVATE Boost::thread Boost::atomic Boost::url Boost::filesystem) diff --git a/src/h3_client.cpp b/src/h3_client.cpp index e40b504..68d7719 100644 --- a/src/h3_client.cpp +++ b/src/h3_client.cpp @@ -63,14 +63,14 @@ #include #include -#include "ngtcp2/util.h" - using namespace std::chrono_literals; using namespace boost::asio; namespace errc = boost::system::errc; +using anyhttp::http3::format_hex; using anyhttp::http3::log_headers; using anyhttp::http3::make_nv; +using anyhttp::http3::straddr; namespace anyhttp::client { @@ -442,7 +442,7 @@ int Http3ClientSession::init(asio::ip::udp::endpoint remote) return -1; } - log_prefix_ = std::format("h3:{}", ngtcp2::util::straddr(remote.data(), remote.size())); + log_prefix_ = std::format("h3:{}", straddr(remote.data(), remote.size())); ngtcp2_cid scid{}; scid.datalen = 17; @@ -485,7 +485,7 @@ int Http3ClientSession::init(asio::ip::udp::endpoint remote) if (setup_tls(tls_context().ctx, false /* client */) != 0) return -1; - logi("[{}] connecting, scid={}", log_prefix_, ngtcp2::util::format_hex(scid.data, scid.datalen)); + logi("[{}] connecting, scid={}", log_prefix_, format_hex(scid.data, scid.datalen)); return 0; } diff --git a/src/h3_common.cpp b/src/h3_common.cpp index 7662782..c384de1 100644 --- a/src/h3_common.cpp +++ b/src/h3_common.cpp @@ -6,9 +6,15 @@ #include +#include + #include +#include +#include #include #include +#include +#include namespace anyhttp::http3 { @@ -53,6 +59,108 @@ void ngtcp2_log_printf(void* /*user*/, const char* fmt, ...) noexcept spdlog::trace("{}", buf.data()); } +// ================================================================================================= +// +// Below: helpers taken from the ngtcp2 examples, see anyhttp/h3_common.hpp. +// + +std::optional
msghdr_get_local_addr(msghdr* msg, int family) +{ + switch (family) + { + case AF_INET: + for (auto cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) + { + if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_PKTINFO) + continue; + + in_pktinfo pktinfo; + std::memcpy(&pktinfo, CMSG_DATA(cmsg), sizeof(pktinfo)); + Address res{.len = sizeof(res.su.in), + .ifindex = static_cast(pktinfo.ipi_ifindex)}; + res.su.in.sin_family = AF_INET; + res.su.in.sin_addr = pktinfo.ipi_addr; + return res; + } + return {}; + + case AF_INET6: + for (auto cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) + { + if (cmsg->cmsg_level != IPPROTO_IPV6 || cmsg->cmsg_type != IPV6_PKTINFO) + continue; + + in6_pktinfo pktinfo; + std::memcpy(&pktinfo, CMSG_DATA(cmsg), sizeof(pktinfo)); + Address res{.len = sizeof(res.su.in6), + .ifindex = static_cast(pktinfo.ipi6_ifindex)}; + res.su.in6.sin6_family = AF_INET6; + res.su.in6.sin6_addr = pktinfo.ipi6_addr; + return res; + } + return {}; + } + + return {}; +} + +void set_port(Address& dst, const Address& src) +{ + switch (dst.su.storage.ss_family) + { + case AF_INET: + assert(AF_INET == src.su.storage.ss_family); + dst.su.in.sin_port = src.su.in.sin_port; + return; + + case AF_INET6: + assert(AF_INET6 == src.su.storage.ss_family); + dst.su.in6.sin6_port = src.su.in6.sin6_port; + return; + + default: + assert(0); + } +} + +ngtcp2_tstamp timestamp() +{ + using namespace std::chrono; + return static_cast( + duration_cast(steady_clock::now().time_since_epoch()).count()); +} + +std::string straddr(const sockaddr* sa, socklen_t salen) +{ + std::array host; + std::array port; + + auto rv = getnameinfo(sa, salen, host.data(), host.size(), port.data(), port.size(), + NI_NUMERICHOST | NI_NUMERICSERV); + if (rv != 0) + { + loge("getnameinfo: {}", gai_strerror(rv)); + return {}; + } + + return std::format("[{}]:{}", host.data(), port.data()); +} + +std::string format_hex(const uint8_t* data, size_t len) +{ + constexpr char xdigits[] = "0123456789abcdef"; + + std::string res; + res.reserve(len * 2); + for (size_t i = 0; i < len; ++i) + { + res += xdigits[data[i] >> 4]; + res += xdigits[data[i] & 0xf]; + } + + return res; +} + // ================================================================================================= } // namespace anyhttp::http3 diff --git a/src/h3_server.cpp b/src/h3_server.cpp index 15df393..57ff096 100644 --- a/src/h3_server.cpp +++ b/src/h3_server.cpp @@ -81,16 +81,19 @@ #include #include -#include "ngtcp2/shared.h" -#include "ngtcp2/util.h" - using namespace std::chrono_literals; using namespace boost::asio; namespace errc = boost::system::errc; +using anyhttp::http3::Address; +using anyhttp::http3::format_hex; using anyhttp::http3::log_headers; using anyhttp::http3::make_nv; +using anyhttp::http3::msghdr_get_local_addr; using anyhttp::http3::QUIC_SCIDLEN; +using anyhttp::http3::set_port; +using anyhttp::http3::sockaddr_union; +using anyhttp::http3::straddr; namespace anyhttp::server { @@ -99,7 +102,7 @@ namespace anyhttp::server struct Endpoint { - ngtcp2::Address addr; + Address addr; int fd; // Testing aid, see server::Config::drop_rate_rx/tx. @@ -332,7 +335,7 @@ class Http3ServerStream : public http3::Http3Stream class Http3ServerSession : public http3::Http3Session { public: - Http3ServerSession(Http3ServerImpl& server, Endpoint ep, ngtcp2::Address remote); + Http3ServerSession(Http3ServerImpl& server, Endpoint ep, Address remote); ~Http3ServerSession() override; // @@ -353,8 +356,7 @@ class Http3ServerSession : public http3::Http3Session // int init(const ngtcp2_cid& dcid, const ngtcp2_cid& scid, uint32_t version, const ngtcp2_pkt_info& pi, std::span data); - int on_read(const ngtcp2_pkt_info& pi, std::span data, - const ngtcp2::Address& remote); + int on_read(const ngtcp2_pkt_info& pi, std::span data, const Address& remote); /// Called from Http3ServerImpl::process_quic_batch() when a packet arrives during the /// closing period. @@ -380,7 +382,7 @@ class Http3ServerSession : public http3::Http3Session Http3ServerImpl& server_; Endpoint ep_; bool owns_fd_ = false; // ep_.fd was dup()ed in the ctor, close it in the dtor - ngtcp2::Address remote_; + Address remote_; ngtcp2_cid scid_{}; asio::steady_timer done_signal_; // used to wake do_session() on connection close @@ -390,9 +392,9 @@ class Http3ServerSession : public http3::Http3Session namespace { -std::optional to_ngtcp2_address(const sockaddr_storage& src, socklen_t len) +std::optional
to_address(const sockaddr_storage& src, socklen_t len) { - ngtcp2::Address addr{}; + Address addr{}; if (len > sizeof(addr.su)) return std::nullopt; std::memcpy(&addr.su, &src, len); @@ -412,7 +414,7 @@ struct QuicBatch struct Datagram { ngtcp2_pkt_info pi; - ngtcp2::Address remote; + Address remote; std::vector data; }; @@ -573,13 +575,13 @@ void Http3ServerStream::submit_response(unsigned int status, const Fields& user_ // Http3ServerSession implementation // ================================================================================================= -Http3ServerSession::Http3ServerSession(Http3ServerImpl& server, Endpoint ep, ngtcp2::Address remote) +Http3ServerSession::Http3ServerSession(Http3ServerImpl& server, Endpoint ep, Address remote) : http3::Http3Session(server.config().use_strand ? asio::any_io_executor{asio::make_strand(server.get_executor())} : server.get_executor()), server_(server), ep_(ep), remote_(remote), done_signal_(get_executor()) { - log_prefix_ = std::format("h3:{}", ngtcp2::util::straddr(&remote_.su.sa, remote_.len)); + log_prefix_ = std::format("h3:{}", straddr(&remote_.su.sa, remote_.len)); // // Own a dup() of the shared UDP fd rather than borrowing the server's. Sends happen from this @@ -749,7 +751,7 @@ int Http3ServerSession::init(const ngtcp2_cid& dcid, const ngtcp2_cid& scid, uin return -1; logi("[{}] new connection, scid={} version=0x{:x}", log_prefix_, - ngtcp2::util::format_hex(scid_.data, scid_.datalen), version); + format_hex(scid_.data, scid_.datalen), version); return on_read(pi, data, remote_); } @@ -757,7 +759,7 @@ int Http3ServerSession::init(const ngtcp2_cid& dcid, const ngtcp2_cid& scid, uin // ------------------------------------------------------------------------------------------------- int Http3ServerSession::on_read(const ngtcp2_pkt_info& pi, std::span data, - const ngtcp2::Address& remote) + const Address& remote) { ngtcp2_path path{ {const_cast(&ep_.addr.su.sa), ep_.addr.len}, @@ -938,7 +940,7 @@ void Http3ServerImpl::erase_quic_session(Http3ServerSession* h) int Http3ServerImpl::udp_on_read(Endpoint& ep) { - ngtcp2::sockaddr_union su; + sockaddr_union su; std::array buf; ngtcp2_pkt_info pi{}; @@ -978,13 +980,13 @@ int Http3ServerImpl::udp_on_read(Endpoint& ep) if (nread < 22) continue; - auto local_addr = ngtcp2::msghdr_get_local_addr(&msg, su.storage.ss_family); + auto local_addr = msghdr_get_local_addr(&msg, su.storage.ss_family); if (!local_addr) { logw("could not obtain local address from cmsg"); continue; } - ngtcp2::set_port(*local_addr, ep.addr); + set_port(*local_addr, ep.addr); ep.addr = *local_addr; // When UDP_GRO is enabled the kernel may coalesce several datagrams @@ -1001,7 +1003,7 @@ int Http3ServerImpl::udp_on_read(Endpoint& ep) } } - auto remote = to_ngtcp2_address(su.storage, msg.msg_namelen); + auto remote = to_address(su.storage, msg.msg_namelen); if (!remote) { logw("unsupported remote address family"); diff --git a/src/h3_session.cpp b/src/h3_session.cpp index cbc0d21..bba8b1e 100644 --- a/src/h3_session.cpp +++ b/src/h3_session.cpp @@ -4,8 +4,8 @@ // h3_client.cpp. // #include "anyhttp/h3_session.hpp" -#include "anyhttp/h3_stream.hpp" #include "anyhttp/h3_common.hpp" +#include "anyhttp/h3_stream.hpp" #include "anyhttp/literals.hpp" #include "anyhttp/tls.hpp" @@ -18,8 +18,6 @@ #include #include -#include "ngtcp2/util.h" - using namespace std::chrono_literals; using namespace boost::asio; @@ -288,7 +286,7 @@ int Http3Session::write_streams() size_t gso_size = 0; auto nwrite = ngtcp2_conn_write_aggregate_pkt2(conn_, &ps.path, &pi, tx_buf_.data(), tx_buf_.size(), - &gso_size, &write_pkt_cb, 0, ngtcp2::util::timestamp()); + &gso_size, &write_pkt_cb, 0, timestamp()); if (nwrite < 0) { mloge("ngtcp2_conn_write_aggregate_pkt2: {}", ngtcp2_strerror(static_cast(nwrite))); @@ -325,7 +323,7 @@ void Http3Session::arm_timer_from_ngtcp2() return; } - auto now = ngtcp2::util::timestamp(); + auto now = timestamp(); asio::steady_timer::duration delay = expiry <= now ? std::chrono::nanoseconds{1} : std::chrono::nanoseconds{expiry - now}; @@ -341,7 +339,7 @@ void Http3Session::arm_timer_from_ngtcp2() int Http3Session::handle_expiry() { - auto now = ngtcp2::util::timestamp(); + auto now = timestamp(); if (auto rv = ngtcp2_conn_handle_expiry(conn_, now); rv != 0) { // @@ -368,8 +366,7 @@ int Http3Session::on_read(const ngtcp2_path& path, const ngtcp2_pkt_info& pi, { mlogd("on_read: {} bytes", data.size()); - auto rv = - ngtcp2_conn_read_pkt(conn_, &path, &pi, data.data(), data.size(), ngtcp2::util::timestamp()); + auto rv = ngtcp2_conn_read_pkt(conn_, &path, &pi, data.data(), data.size(), timestamp()); if (rv != 0) { if (rv == NGTCP2_ERR_DRAINING) @@ -401,7 +398,7 @@ std::span Http3Session::write_connection_close(std::span ngtcp2_path_storage_zero(&ps); auto nwrite = ngtcp2_conn_write_connection_close(conn_, &ps.path, &pi, buf.data(), buf.size(), - &last_error_, ngtcp2::util::timestamp()); + &last_error_, timestamp()); if (nwrite <= 0) return {}; return buf.first(static_cast(nwrite)); @@ -442,7 +439,7 @@ void Http3Session::fill_settings(ngtcp2_settings& settings, ngtcp2_transport_par std::chrono::nanoseconds idle_timeout) { ngtcp2_settings_default(&settings); - settings.initial_ts = ngtcp2::util::timestamp(); + settings.initial_ts = timestamp(); if (spdlog::default_logger_raw()->should_log(spdlog::level::trace)) settings.log_printf = &http3::ngtcp2_log_printf; diff --git a/src/ngtcp2/README.md b/src/ngtcp2/README.md deleted file mode 100644 index 040c0b8..0000000 --- a/src/ngtcp2/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# ngtcp2 example helpers - -A few small helpers extracted from the [ngtcp2](https://github.com/ngtcp2/ngtcp2) examples -(`examples/`, v1.25.0), reduced to what the anyhttp library actually uses: - -* `network.h` -- `sockaddr_union` and `Address` -* `util.{h,cc}` -- `format_hex()`, `timestamp()`, `straddr()` -* `shared.{h,cc}` -- `msghdr_get_local_addr()`, `set_port()` - -The full example client and server used to be vendored here as `ngtcp-client`/`ngtcp-server`. -They are gone; the devcontainer image builds the upstream examples instead and installs them -as `/usr/local/bin/osslclient` and `/usr/local/bin/osslserver` -- see [HTTP3.md](../../HTTP3.md). diff --git a/src/ngtcp2/network.h b/src/ngtcp2/network.h deleted file mode 100644 index 857c887..0000000 --- a/src/ngtcp2/network.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * ngtcp2 - * - * Copyright (c) 2017 ngtcp2 contributors - * Copyright (c) 2016 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NETWORK_H -#define NETWORK_H - -#include -#include -#include - -namespace ngtcp2 { - -union sockaddr_union { - sockaddr_storage storage; - sockaddr sa; - sockaddr_in6 in6; - sockaddr_in in; -}; - -struct Address { - socklen_t len; - union sockaddr_union su; - uint32_t ifindex; -}; - -} // namespace ngtcp2 - -#endif // !defined(NETWORK_H) diff --git a/src/ngtcp2/shared.cc b/src/ngtcp2/shared.cc deleted file mode 100644 index a75286f..0000000 --- a/src/ngtcp2/shared.cc +++ /dev/null @@ -1,85 +0,0 @@ -/* - * ngtcp2 - * - * Copyright (c) 2019 ngtcp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "shared.h" - -#include -#include - -namespace ngtcp2 { - -std::optional
msghdr_get_local_addr(msghdr *msg, int family) { - switch (family) { - case AF_INET: - for (auto cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { - in_pktinfo pktinfo; - memcpy(&pktinfo, CMSG_DATA(cmsg), sizeof(pktinfo)); - Address res{ - .len = sizeof(res.su.in), - .ifindex = static_cast(pktinfo.ipi_ifindex), - }; - auto &sa = res.su.in; - sa.sin_family = AF_INET; - sa.sin_addr = pktinfo.ipi_addr; - return res; - } - } - return {}; - case AF_INET6: - for (auto cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) { - in6_pktinfo pktinfo; - memcpy(&pktinfo, CMSG_DATA(cmsg), sizeof(pktinfo)); - Address res{ - .len = sizeof(res.su.in6), - .ifindex = static_cast(pktinfo.ipi6_ifindex), - }; - auto &sa = res.su.in6; - sa.sin6_family = AF_INET6; - sa.sin6_addr = pktinfo.ipi6_addr; - return res; - } - } - return {}; - } - return {}; -} - -void set_port(Address &dst, const Address &src) { - switch (dst.su.storage.ss_family) { - case AF_INET: - assert(AF_INET == src.su.storage.ss_family); - dst.su.in.sin_port = src.su.in.sin_port; - return; - case AF_INET6: - assert(AF_INET6 == src.su.storage.ss_family); - dst.su.in6.sin6_port = src.su.in6.sin6_port; - return; - default: - assert(0); - } -} - -} // namespace ngtcp2 diff --git a/src/ngtcp2/shared.h b/src/ngtcp2/shared.h deleted file mode 100644 index 4d6e48a..0000000 --- a/src/ngtcp2/shared.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * ngtcp2 - * - * Copyright (c) 2017 ngtcp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef SHARED_H -#define SHARED_H - -#include - -#include "network.h" - -namespace ngtcp2 { - -// msghdr_get_local_addr returns the local (destination) address of the packet -// described by |msg|, as delivered by IP(V6)_PKTINFO. |family| is the address -// family from which the packet was received. -std::optional
msghdr_get_local_addr(msghdr *msg, int family); - -// set_port copies the port of |src| into |dst|. -void set_port(Address &dst, const Address &src); - -} // namespace ngtcp2 - -#endif // !defined(SHARED_H) diff --git a/src/ngtcp2/util.cc b/src/ngtcp2/util.cc deleted file mode 100644 index ed7379e..0000000 --- a/src/ngtcp2/util.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* - * ngtcp2 - * - * Copyright (c) 2017 ngtcp2 contributors - * Copyright (c) 2012 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "util.h" - -#include - -#include -#include -#include - -namespace ngtcp2 { - -namespace util { - -ngtcp2_tstamp timestamp() { - return static_cast( - std::chrono::duration_cast( - std::chrono::steady_clock::now().time_since_epoch()) - .count()); -} - -std::string straddr(const sockaddr *sa, socklen_t salen) { - std::array host; - std::array port; - - auto rv = getnameinfo(sa, salen, host.data(), host.size(), port.data(), - port.size(), NI_NUMERICHOST | NI_NUMERICSERV); - if (rv != 0) { - std::cerr << "getnameinfo: " << gai_strerror(rv) << std::endl; - return ""; - } - std::string res = "["; - res.append(host.data(), strlen(host.data())); - res += "]:"; - res.append(port.data(), strlen(port.data())); - return res; -} - -} // namespace util - -} // namespace ngtcp2 diff --git a/src/ngtcp2/util.h b/src/ngtcp2/util.h deleted file mode 100644 index ec05e28..0000000 --- a/src/ngtcp2/util.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * ngtcp2 - * - * Copyright (c) 2017 ngtcp2 contributors - * Copyright (c) 2012 nghttp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef UTIL_H -#define UTIL_H - -#include - -#include -#include -#include -#include - -#include - -namespace ngtcp2 { - -namespace util { - -inline constexpr auto hexdigits = []() { - constexpr char LOWER_XDIGITS[] = "0123456789abcdef"; - - std::array tbl; - - for (size_t i = 0; i < 256; ++i) { - tbl[i * 2] = LOWER_XDIGITS[static_cast(i >> 4)]; - tbl[i * 2 + 1] = LOWER_XDIGITS[static_cast(i & 0xf)]; - } - - return tbl; -}(); - -// format_hex converts a range [|first|, |last|) in hex format, and -// stores the result in another range, beginning at |result|. It -// returns an output iterator to the element past the last element -// stored. -template -requires(std::indirectly_writable && - sizeof(std::iter_value_t) == sizeof(uint8_t)) -constexpr O format_hex(I first, I last, O result) { - for (; first != last; ++first) { - result = std::ranges::copy_n( - hexdigits.data() + static_cast(*first) * 2, 2, result) - .out; - } - - return result; -} - -// format_hex converts a range [|first|, |first| + |n|) in hex format, -// and stores the result in another range, beginning at |result|. It -// returns an output iterator to the element past the last element -// stored. -template -requires(std::indirectly_writable && - sizeof(std::iter_value_t) == sizeof(uint8_t)) -constexpr O format_hex(I first, std::iter_difference_t n, O result) { - return format_hex(first, std::ranges::next(first, n), std::move(result)); -} - -// format_hex converts a range [|first|, |first| + |n|) in hex format, -// and returns it. -template -requires(sizeof(std::iter_value_t) == sizeof(uint8_t)) -constexpr std::string format_hex(I first, std::iter_difference_t n) { - if (n <= 0) { - return {}; - } - - std::string res; - - res.resize(static_cast(n * 2)); - - format_hex(std::move(first), std::move(n), std::ranges::begin(res)); - - return res; -} - -// timestamp returns the current timestamp of steady clock, in nanoseconds. -ngtcp2_tstamp timestamp(); - -// straddr stringifies |sa| of length |salen| in a format "[IP]:PORT". -std::string straddr(const sockaddr *sa, socklen_t salen); - -} // namespace util - -} // namespace ngtcp2 - -#endif // !defined(UTIL_H) From db6892c253c845a382d341fde8c9659eb3126c32 Mon Sep 17 00:00:00 2001 From: Peter Eisenlohr Date: Mon, 7 Sep 2026 21:21:13 +0000 Subject: [PATCH 2/2] cleanup: update .gitignore to include _codeql_detected_source_root and remove the corresponding file --- .gitignore | 1 + _codeql_detected_source_root | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 120000 _codeql_detected_source_root diff --git a/.gitignore b/.gitignore index 6c89aab..cbf2c11 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ Testing *.junit .claude callgrind.* +_codeql_detected_source_root cmake_test_discovery_*.json googletest_discovery_*.json keylog.log diff --git a/_codeql_detected_source_root b/_codeql_detected_source_root deleted file mode 120000 index 945c9b4..0000000 --- a/_codeql_detected_source_root +++ /dev/null @@ -1 +0,0 @@ -. \ No newline at end of file