Skip to content
Merged
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
7 changes: 5 additions & 2 deletions include/bitcoin/network/async/time.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,18 @@ typedef steady_clock::time_point time_point;
/// C++20: std::chrono::system_clock measures Unix Time.
typedef std::chrono::system_clock wall_clock;

/// Current zulu (utc) time using the wall clock.
/// Current zulu (utc) time using the wall clock, as time_t.
BCT_API time_t zulu_time() NOEXCEPT;

/// Current zulu (utc) time using the wall clock, cast to uint32_t.
BCT_API uint32_t unix_time() NOEXCEPT;

/// Standard date-time string, e.g. Sun Oct 17 04:41:13 2010, locale dependent.
/// Current local date-time text, locale dependent (Sun Oct 17 04:41:13 2010).
BCT_API std::string local_time() NOEXCEPT;

/// Specified zulu (utc) time as, conversion to local date-time text.
BCT_API std::string BCT_API to_local_time(uint32_t zulu) NOEXCEPT;

} // namespace network
} // namespace libbitcoin

Expand Down
31 changes: 19 additions & 12 deletions include/bitcoin/network/config/utilities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,21 @@ namespace libbitcoin {
namespace network {
namespace config {

/// IPv6 normalizes IPv4 addresses as "mapped" addresses, i.e. mapped into the
/// IPv6 address space. P2P protocol encodes all addresses in this normal form.
/// For serialization purposes we encode/decode only to/from denormalized form.
/// IPv6 "host names" are not bracketed, however IPv6 addresses are bracked.
/// IPv6 supports embedding of an IPv4 address (4 bytes) into IPv6 encodings
/// (16 bytes). The two formats, "compatible" and "mapped" embed the same
/// address differently, with the distinction being the level of support of the
/// device. This is problematic for addresses, as they are device independent.
/// P2P protocol is 16 bytes and allows for either encoding, however the
/// "compatible" concoding is deprecated, so we produce only mapped encoding
/// for P2P serialization. However, as both formats are send via P2P we decode
/// from all three IPv6 encodings (native, compatible, mapped). For human
/// readability we serialize adresses as text, for both logging and shutdown
/// persistence. We refer to this format as denormalized, as it supports only
/// native IPv4 and native IPv6 serialization. IPv6 host names are "bracketed".
/// This provides distinction from the port number (otherwise conflating ":").
/// This form is referred to as "literal" IPv6 encoding (from IPv6 URIs). All
/// addresses must be literal encodings, all host names are serialized as non-
/// literal, and deserialized as either literal or non-literal.
/// text addresses are literal encodings, and all host names are serialized as
/// non-literal, and deserialized as either literal or non-literal.

/// datatracker.ietf.org/doc/html/rfc4291
constexpr size_t ipv4_size = 4;
Expand All @@ -59,25 +66,25 @@ constexpr bool is_v4(const messages::ip_address& ip) NOEXCEPT
}

/// Member if subnet addresses contain host.
bool is_member(const asio::address& ip, const asio::address& subnet,
BCT_API bool is_member(const asio::address& ip, const asio::address& subnet,
uint8_t cidr) NOEXCEPT;

/// Unmap IPv6-mapped addresses.
asio::address denormalize(const asio::address& ip) NOEXCEPT;

/// Denormalizes to IPv4 (unmapped), literal emits unbracketed.
std::string to_host(const asio::address& ip) NOEXCEPT;
std::string to_literal(const asio::address& ip) NOEXCEPT;
asio::address from_host(const std::string& host) NOEXCEPT(false);
BCT_API std::string to_host(const asio::address& ip) NOEXCEPT;
BCT_API std::string to_literal(const asio::address& ip) NOEXCEPT;
BCT_API asio::address from_host(const std::string& host) NOEXCEPT(false);

/// Not denormalizing.
messages::ip_address to_address(const asio::address& ip) NOEXCEPT;
asio::address from_address(const messages::ip_address& address) NOEXCEPT;

/// Parsers.
bool parse_authority(asio::address& ip, uint16_t& port, uint8_t& cidr,
BCT_API bool parse_authority(asio::address& ip, uint16_t& port, uint8_t& cidr,
const std::string& value) NOEXCEPT;
bool parse_endpoint(std::string& scheme, std::string& host, uint16_t& port,
BCT_API bool parse_endpoint(std::string& scheme, std::string& host, uint16_t& port,
const std::string& value) NOEXCEPT;

} // namespace config
Expand Down
2 changes: 1 addition & 1 deletion include/bitcoin/network/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ enum error_t
file_load,
file_save,
file_system,
file_payload,
file_exception,

// general I/O failures
bad_stream,
Expand Down
5 changes: 4 additions & 1 deletion include/bitcoin/network/net/hosts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class BCT_API hosts
/// Take one random host from the table (non-const).
virtual void take(const address_item_handler& handler) NOEXCEPT;

/// Save a random set of hosts (e.g obtained from peer), count of accept.
/// Save random subset of hosts (e.g obtained from peer), count of accept.
virtual size_t save(const messages::address_items& hosts) NOEXCEPT;

/// Obtain a random set of hosts (e.g for relay to peer).
Expand All @@ -93,6 +93,9 @@ class BCT_API hosts
BC_POP_WARNING()
}

// Push a buffer entry if the line is valid.
void push_valid(const std::string& line) NOEXCEPT;

// These are thread safe.
const std::filesystem::path file_path_;
std::atomic<size_t> count_{};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class BCT_API protocol_address_in_31402
void start() NOEXCEPT override;

protected:
virtual messages::address::cptr filter(
const messages::address_items& message) const NOEXCEPT;

virtual void handle_receive_address(const code& ec,
const messages::address::cptr& message) NOEXCEPT;
virtual void handle_save_address(const code& ec,
Expand Down
3 changes: 3 additions & 0 deletions include/bitcoin/network/protocols/protocol_seed_31402.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ class BCT_API protocol_seed_31402
virtual bool complete() const NOEXCEPT;
virtual void handle_timer(const code& ec) NOEXCEPT;

virtual messages::address::cptr filter(
const messages::address_items& message) const NOEXCEPT;

virtual void handle_send_get_address(const code& ec) NOEXCEPT;
virtual void handle_receive_address(const code& ec,
const messages::address::cptr& address) NOEXCEPT;
Expand Down
1 change: 0 additions & 1 deletion include/bitcoin/network/sessions/session.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,6 @@ class BCT_API session
// These are thread safe (mostly).
p2p& network_;
const size_t key_;
const duration timeout_;
std::atomic_bool stopped_{ true };

// These are not thread safe.
Expand Down
5 changes: 2 additions & 3 deletions include/bitcoin/network/settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ struct BCT_API settings
uint32_t connect_batch_size;
uint32_t retry_timeout_seconds;
uint32_t connect_timeout_seconds;
uint32_t channel_handshake_seconds;
uint32_t channel_germination_seconds;
uint32_t handshake_timeout_seconds;
uint32_t seeding_timeout_seconds;
uint32_t channel_heartbeat_minutes;
uint32_t channel_inactivity_minutes;
uint32_t channel_expiration_minutes;
Expand All @@ -79,7 +79,6 @@ struct BCT_API settings
virtual bool inbound_enabled() const NOEXCEPT;
virtual bool outbound_enabled() const NOEXCEPT;
virtual bool advertise_enabled() const NOEXCEPT;

virtual size_t maximum_payload() const NOEXCEPT;
virtual duration retry_timeout() const NOEXCEPT;
virtual duration connect_timeout() const NOEXCEPT;
Expand Down
4 changes: 2 additions & 2 deletions src/async/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <algorithm>
#include <thread>

#ifdef _MSC_VER
#ifdef HAVE_MSC
#include <windows.h>
#else
#include <unistd.h>
Expand Down Expand Up @@ -62,7 +62,7 @@ void set_priority(thread_priority priority) NOEXCEPT
{
const auto prioritization = get_priority(priority);

#if defined(_MSC_VER)
#if defined(HAVE_MSC)
SetThreadPriority(GetCurrentThread(), prioritization);
#elif defined(PRIO_THREAD)
setpriority(PRIO_THREAD, pthread_self(), prioritization);
Expand Down
21 changes: 18 additions & 3 deletions src/async/time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ uint32_t unix_time() NOEXCEPT
static bool local_time(tm& out_local, time_t zulu) NOEXCEPT
{
// localtime not threadsafe due to static buffer return, use localtime_s.
#ifdef _MSC_VER
#ifdef HAVE_MSC
// proprietary msvc implemention, parameters swapped, returns errno_t.
return localtime_s(&out_local, &zulu) == 0;
#else
Expand All @@ -51,10 +51,11 @@ static bool local_time(tm& out_local, time_t zulu) NOEXCEPT
#endif
}

std::string local_time() NOEXCEPT
// local
static std::string local_time(time_t zulu) NOEXCEPT
{
tm out_local{};
if (!local_time(out_local, zulu_time()))
if (!local_time(out_local, zulu))
return "";

// %c writes standard date and time string, e.g.
Expand All @@ -65,7 +66,21 @@ std::string local_time() NOEXCEPT

// std::strftime is required because gcc doesn't implement std::put_time.
// Returns number of characters, zero implies failure and undefined buffer.
BC_PUSH_WARNING(NO_ARRAY_TO_POINTER_DECAY)
return is_zero(std::strftime(buffer, size, format, &out_local)) ? "" : buffer;
BC_POP_WARNING()
}

std::string local_time() NOEXCEPT
{
return local_time(zulu_time());
}

std::string to_local_time(uint32_t zulu) NOEXCEPT
{
BC_PUSH_WARNING(NO_STATIC_CAST)
return local_time(static_cast<time_t>(zulu));
BC_POP_WARNING()
}

} // namespace network
Expand Down
27 changes: 16 additions & 11 deletions src/config/utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ static_assert(array_count<ip::address_v4::bytes_type> == ipv4_size);
static_assert(array_count<ip::address_v6::bytes_type> == ipv6_size);
static_assert(is_same_type<ip::address_v6::bytes_type, messages::ip_address>);

// Because system::deserialize doesn't convert empty to zero.
template <typename Integer>
inline bool to_integer(Integer& out, const std::string& in) NOEXCEPT
{
// system::deserialize doesn't convert empty to zero.
if (in.empty())
{
out = Integer{};
Expand All @@ -50,6 +50,7 @@ inline bool to_integer(Integer& out, const std::string& in) NOEXCEPT
return system::deserialize(out, in);
}

// For calling consistency.
inline bool to_string(std::string& to, std::string&& from) NOEXCEPT
{
to = std::move(from);
Expand Down Expand Up @@ -85,10 +86,11 @@ using namespace boost;
#define HOST "([^:?/\\\\]+)"
#define PORT ":([1-9][0-9]{0,4})"
#define CIDR "\\/([1-9][0-9]{0,2})"
////#define IPV6E4 "\\[([0-9a-f:.]+)]"

BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)

// Excludes ipv4 mapped, unbracketed, and ports allowed by make_address.
// Excludes ipv4 mapped/compat, unbracketed, and ports allowed by make_address.
bool parse_host(asio::address& ip, const std::string& value) NOEXCEPT
{
static const regex regular
Expand All @@ -101,7 +103,7 @@ bool parse_host(asio::address& ip, const std::string& value) NOEXCEPT
&& make_address(ip, (*token)[1]);
}

// Excludes ipv4 mapped to ipv6.
// Excludes ipv4 mapped/compat to ipv6.
bool parse_authority(asio::address& ip, uint16_t& port, uint8_t& cidr,
const std::string& value) NOEXCEPT
{
Expand All @@ -119,7 +121,7 @@ bool parse_authority(asio::address& ip, uint16_t& port, uint8_t& cidr,
(ip.is_v6() && cidr <= maximum_cidr_ip6));
}

// Excludes ipv4 mapped to ipv6.
// Excludes ipv4 mapped/compat to ipv6.
bool parse_endpoint(std::string& scheme, std::string& host, uint16_t& port,
const std::string& value) NOEXCEPT
{
Expand All @@ -140,6 +142,11 @@ BC_POP_WARNING()
// asio/asio conversions.
// ----------------------------------------------------------------------------

inline bool is_embedded_v4(const asio::ipv6& ip6) NOEXCEPT
{
return ip6.is_v4_mapped() || ip6.is_v4_compatible();
}

static asio::ipv6 to_v6(const asio::ipv4& ip4) NOEXCEPT
{
try
Expand All @@ -152,16 +159,16 @@ static asio::ipv6 to_v6(const asio::ipv4& ip4) NOEXCEPT
}
}

// Convert IPv6-mapped to IPV4 (ensures consistent matching).
// Convert IPv6-mapped to IPV4 (ensures consistent internal matching).
// Reduce 4 encodings (IPv6, IPv6-mapped, IPv6-compat, IPv4) to 2 (IPv6, IPv4).
asio::address denormalize(const asio::address& ip) NOEXCEPT
{
if (ip.is_v6())
{
try
{
// Must extract the ipv6 object before calling to_ipv4().
const auto ip6 = ip.to_v6();
if (ip6.is_v4_mapped()) return { ip6.to_v4() };
if (is_embedded_v4(ip6)) return { ip6.to_v4() };
}
catch (std::exception)
{
Expand All @@ -173,14 +180,12 @@ asio::address denormalize(const asio::address& ip) NOEXCEPT

// asio/string host conversions.
// ----------------------------------------------------------------------------
// IPv4-Compatible IPv6 address are deprecated, support only IPv4-Mapped.
// rfc-editor.org/rfc/rfc4291

inline std::string to_host(const asio::ipv6& ip6) NOEXCEPT
{
try
{
return ip6.to_string();
return is_embedded_v4(ip6) ? to_host(ip6.to_v4()) : ip6.to_string();
}
catch (std::exception)
{
Expand Down Expand Up @@ -221,7 +226,7 @@ std::string to_literal(const asio::address& ip) NOEXCEPT
return (host.find(":") == std::string::npos) ? host : ("[" + host + "]");
}

// Rejects ipv6 mapped to ipv4 and unbracketed ipv6.
// Rejects ipv6 mapped/compat to ipv4 and unbracketed ipv6.
asio::address from_host(const std::string& host) NOEXCEPT(false)
{
asio::address out{};
Expand Down
2 changes: 1 addition & 1 deletion src/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ DEFINE_ERROR_T_MESSAGE_MAP(error)
{ file_load, "failed to load file" },
{ file_save, "failed to save file" },
{ file_system, "file system error" },
{ file_payload, "file payload error" },
{ file_exception, "file exception" },

// general I/O failures
{ bad_stream, "bad data stream" },
Expand Down
Loading