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
13 changes: 10 additions & 3 deletions src/event/Loop.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "io/uring/Queue.hxx"
#endif

#include <limits.h> // for INT_MAX

#ifdef HAVE_URING

class EventLoop::UringPoll final : Uring::Operation {
Expand Down Expand Up @@ -346,9 +348,14 @@ EventLoop::RunOneIdle() noexcept
static constexpr int
ExportTimeoutMS(Event::Duration timeout) noexcept
{
return timeout >= timeout.zero()
? static_cast<int>(std::chrono::ceil<std::chrono::milliseconds>(timeout).count())
: -1;
if (timeout < timeout.zero())
return -1;

const auto ms = std::chrono::ceil<std::chrono::milliseconds>(timeout).count();
if (ms > INT_MAX)
return INT_MAX;

return static_cast<int>(ms);
}

#ifdef HAVE_URING
Expand Down
27 changes: 27 additions & 0 deletions src/net/IPv4Address.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,37 @@
#include "IPv4Address.hxx"

#include <cassert>
#include <cstring> // for strlen()
#include <cstdio> // for sprintf()

#ifndef _WIN32
#include <arpa/inet.h> // for inet_ntop()
#endif

IPv4Address::IPv4Address(SocketAddress src) noexcept
:address(src.CastTo<struct sockaddr_in>())
{
assert(!src.IsNull());
assert(src.GetFamily() == AF_INET);
}

const char *
IPv4Address::Format(std::span<char> buffer) const noexcept
{
if (buffer.size() <= 7) [[unlikely]]
return nullptr;

char *p = buffer.data();

if (inet_ntop(AF_INET, &address.sin_addr,
p, buffer.size() - 7) == nullptr)
return nullptr;

const unsigned port = GetPort();
if (port != 0) {
p += std::strlen(p);
std::sprintf(p, ":%u", port);
}

return buffer.data();
}
8 changes: 8 additions & 0 deletions src/net/IPv4Address.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -232,4 +232,12 @@ public:
return IPv4Address(ConstructInAddrBE(GetNumericAddressBE() & other.GetNumericAddressBE()),
GetPort() & other.GetPort());
}

/**
* Format this object as a C string into the given buffer.
*
* @return the C string on success, nullptr on error
*/
[[nodiscard]]
const char *Format(std::span<char> buffer) const noexcept;
};
30 changes: 29 additions & 1 deletion src/net/IPv6Address.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
#include "IPv4Address.hxx"

#include <cassert>
#include <cstring> // for strlen()
#include <cstdio> // for sprintf()

#include <string.h>
#ifndef _WIN32
#include <arpa/inet.h> // for inet_ntop()
#endif

IPv6Address::IPv6Address(SocketAddress src) noexcept
:address(src.CastTo<struct sockaddr_in6>())
Expand Down Expand Up @@ -65,3 +69,27 @@ IPv6Address::operator&(const IPv6Address &other) const
sizeof(result));
return result;
}

const char *
IPv6Address::Format(std::span<char> buffer) const noexcept
{
if (buffer.size() <= 9) [[unlikely]]
return nullptr;

char *p = buffer.data();

const unsigned port = GetPort();
if (port != 0)
*p++ = '[';

if (inet_ntop(AF_INET6, &address.sin6_addr,
p, buffer.size() - 9) == nullptr)
return nullptr;

if (port != 0) {
p += std::strlen(p);
std::sprintf(p, "]:%u", port);
}

return buffer.data();
}
8 changes: 8 additions & 0 deletions src/net/IPv6Address.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,14 @@ public:
[[gnu::pure]]
IPv6Address operator&(const IPv6Address &other) const;

/**
* Format this object as a C string into the given buffer.
*
* @return the C string on success, nullptr on error
*/
[[nodiscard]]
const char *Format(std::span<char> buffer) const noexcept;

private:
/**
* Helper function for MaskFromPrefix().
Expand Down
24 changes: 24 additions & 0 deletions src/net/InetAddress.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "IPv6Address.hxx"
#endif

#include <span>

/**
* A class that can store either an IPv4 or an IPv6 address.
*/
Expand Down Expand Up @@ -116,4 +118,26 @@ public:
return {};
}
}

/**
* Format this object as a C string into the given buffer.
*
* @return the C string on success, nullptr on error
*/
[[nodiscard]]
const char *Format(std::span<char> buffer) const noexcept {
switch (GetFamily()) {
case AF_INET:
return v4.Format(buffer);

#ifdef HAVE_IPV6
case AF_INET6:
return v6.Format(buffer);
#endif

default:
[[unlikely]]
return nullptr;
}
}
};
Loading