Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] - Retyping #152

Draft
wants to merge 18 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 51 additions & 14 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -1,20 +1,35 @@
BasedOnStyle: Google

AccessModifierOffset: -2

# alignment
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: 'false'
AlignConsecutiveDeclarations: 'false'
AlignEscapedNewlines: Left
AlignOperands: AlignAfterOperator
AlignTrailingComments: 'true'

# inlining
AllowAllArgumentsOnNextLine: 'true'
AllowShortBlocksOnASingleLine: 'false'
AllowShortCaseLabelsOnASingleLine: 'false'
AllowShortFunctionsOnASingleLine: Inline
AllowShortFunctionsOnASingleLine: 'Inline'
AllowShortIfStatementsOnASingleLine: 'false'
AllowShortLoopsOnASingleLine: 'false'
RequiresClausePosition: 'OwnLine'

# breaking
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeConceptDeclarations: 'Always'
BreakBeforeTernaryOperators: 'true'
BreakConstructorInitializers: AfterColon
PenaltyBreakString: '3'

# bracing
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
Expand All @@ -33,29 +48,51 @@ BraceWrapping:
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeTernaryOperators: 'true'
BreakConstructorInitializers: AfterColon

ColumnLimit: 125
CompactNamespaces: 'true'
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
Cpp11BracedListStyle: 'true'
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: 'true'
NamespaceIndentation: All
CompactNamespaces: 'true'
PenaltyBreakString: '3'
QualifierAlignment: Left
RemoveSemicolon: true

#includes
SortIncludes: CaseInsensitive
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '".+\.h'
Priority: 2
- Regex: '^<(oxenc|oxen)'
Priority: 3
- Regex: '^<(event2|ngtcp2)'
Priority: 4
- Regex: '<winsock2\.h>'
Priority: 5
- Regex: '<windows\.h>'
Priority: 6
- Regex: '^<CLI'
Priority: 7
- Regex: '^<catch2'
Priority: 8
- Regex: '^<.*\.h(pp)?>$'
Priority: 9
- Regex: '(<)(.)+(>)'
Priority: 10

# spacing
SpaceBeforeParens: ControlStatements
SpacesInAngles: 'false'
SpacesInContainerLiterals: 'false'
SpacesInParentheses: 'false'
SpacesInSquareBrackets: 'false'

Standard: c++20
UseTab: Never
SortIncludes: true
ColumnLimit: 125
IndentWidth: 4
AccessModifierOffset: -2
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
QualifierAlignment: Left

RemoveSemicolon: true
UseTab: Never

# treat pointers and reference declarations as if part of the type
DerivePointerAlignment: false
Expand Down
4 changes: 3 additions & 1 deletion .drone.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ local mac_builder(name,
'echo "Building on ${DRONE_STAGE_MACHINE}"',
apt_get_quiet + ' update',
apt_get_quiet + ' install -y eatmydata',
'eatmydata ' + apt_get_quiet + ' install --no-install-recommends -y git clang-format-15 jsonnet',
'eatmydata ' + apt_get_quiet + ' install --no-install-recommends -y git clang-format-16 jsonnet',
'./utils/ci/lint-check.sh',
],
}],
Expand All @@ -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'),
Expand Down
23 changes: 17 additions & 6 deletions external/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
61 changes: 36 additions & 25 deletions include/oxen/quic/address.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#pragma once

#include "formattable.hpp"
#include "ip.hpp"
#include "types.hpp"

#include <oxenc/endian.h>

#include <compare>

#include "formattable.hpp"
#include "ip.hpp"
#include "utils.hpp"

#if defined(__OpenBSD__) || defined(__DragonFly__)
// These systems are known to disallow dual stack binding, and so on such systems when
// invoked with an empty address we default to the IPv4 any address rather than the IPv6 any
Expand All @@ -25,8 +25,17 @@ namespace oxen::quic
{
inline constexpr std::array<uint8_t, 16> _ipv6_any_addr = {0};

template <typename T>
concept RawSockAddr = std::same_as<T, sockaddr> || std::same_as<T, sockaddr_in> || std::same_as<T, sockaddr_in6>;
struct Address;

inline namespace concepts
{
template <typename T>
concept raw_sockaddr_type =
std::same_as<T, sockaddr> || std::same_as<T, sockaddr_in> || std::same_as<T, sockaddr_in6>;

template <typename T>
concept quic_address_type = std::derived_from<T, Address>;
} // namespace concepts

// Holds an address, with a ngtcp2_addr held for easier passing into ngtcp2 functions
struct Address
Expand Down Expand Up @@ -71,7 +80,7 @@ namespace oxen::quic
explicit Address(const ipv6& v6, uint16_t port = 0);

// Assignment from a sockaddr pointer; we copy the sockaddr's contents
template <RawSockAddr T>
template <concepts::raw_sockaddr_type T>
Address& operator=(const T* s)
{
_addr.addrlen = std::is_same_v<T, sockaddr>
Expand Down Expand Up @@ -215,12 +224,12 @@ namespace oxen::quic
// pointer to other things (like bool) won't occur.
//
// If the given pointer is mutated you *must* call update_socklen() afterwards.
template <RawSockAddr T>
template <concepts::raw_sockaddr_type T>
operator T*()
{
return reinterpret_cast<T*>(&_sock_addr);
}
template <RawSockAddr T>
template <concepts::raw_sockaddr_type T>
operator const T*() const
{
return reinterpret_cast<const T*>(&_sock_addr);
Expand Down Expand Up @@ -283,28 +292,32 @@ namespace oxen::quic
struct RemoteAddress : public Address
{
private:
ustring remote_pubkey;
std::vector<unsigned char> _remote_pubkey;

public:
RemoteAddress() = delete;

template <typename... Opt>
RemoteAddress(std::string_view remote_pk, Opt&&... opts) :
Address{std::forward<Opt>(opts)...}, remote_pubkey{to_usv(remote_pk)}
{}
Address{std::forward<Opt>(opts)...}, _remote_pubkey(remote_pk.size())
{
std::memcpy(_remote_pubkey.data(), remote_pk.data(), remote_pk.size());
}

template <typename... Opt>
RemoteAddress(ustring_view remote_pk, Opt&&... opts) : Address{std::forward<Opt>(opts)...}, remote_pubkey{remote_pk}
{}
RemoteAddress(uspan remote_pk, Opt&&... opts) : Address{std::forward<Opt>(opts)...}
{
_remote_pubkey.assign(remote_pk.data(), remote_pk.data() + remote_pk.size());
}

ustring_view view_remote_key() const { return remote_pubkey; }
const ustring& get_remote_key() const& { return remote_pubkey; }
ustring&& get_remote_key() && { return std::move(remote_pubkey); }
uspan view_remote_key() const { return _remote_pubkey; }
const std::vector<unsigned char>& get_remote_key() const& { return _remote_pubkey; }
std::vector<unsigned char>&& get_remote_key() && { return std::move(_remote_pubkey); }

RemoteAddress(const RemoteAddress& obj) : Address{obj}, remote_pubkey{obj.remote_pubkey} {}
RemoteAddress(const RemoteAddress& obj) : Address{obj}, _remote_pubkey{obj._remote_pubkey} {}
RemoteAddress& operator=(const RemoteAddress& obj)
{
remote_pubkey = obj.remote_pubkey;
_remote_pubkey = obj._remote_pubkey;
Address::operator=(obj);
_copy_internals(obj);
return *this;
Expand Down Expand Up @@ -366,12 +379,10 @@ namespace oxen::quic

namespace std
{
inline constexpr size_t inverse_golden_ratio = sizeof(size_t) >= 8 ? 0x9e37'79b9'7f4a'7c15 : 0x9e37'79b9;

template <>
struct hash<oxen::quic::Address>
{
size_t operator()(const oxen::quic::Address& addr) const
size_t operator()(const oxen::quic::Address& addr) const noexcept
{
std::string_view addr_data;
uint16_t port;
Expand All @@ -390,18 +401,18 @@ namespace std
}

auto h = hash<string_view>{}(addr_data);
h ^= hash<decltype(port)>{}(port) + inverse_golden_ratio + (h << 6) + (h >> 2);
h ^= hash<decltype(port)>{}(port) + oxen::quic::inverse_golden_ratio + (h << 6) + (h >> 2);
return h;
}
};

template <>
struct hash<oxen::quic::Path>
{
size_t operator()(const oxen::quic::Path& addr) const
size_t operator()(const oxen::quic::Path& addr) const noexcept
{
auto h = hash<oxen::quic::Address>{}(addr.local);
h ^= hash<oxen::quic::Address>{}(addr.remote) + inverse_golden_ratio + (h << 6) + (h >> 2);
h ^= hash<oxen::quic::Address>{}(addr.remote) + oxen::quic::inverse_golden_ratio + (h << 6) + (h >> 2);
return h;
}
};
Expand Down
Loading