enable profiling on clients by default (#1421)

* enable client relay profiling by default

* macos dns fixes

* improve peer profiling algorithm to track timeouts vs failures

* remove debug ioctl call in tuntap code

* use ub_wait instead of ub_process as that was what was there before

* const correctness

* DRY out checking for SIIT

* typofix

* correct name
pull/1433/head
Jeff 4 years ago committed by GitHub
parent 32f4287df6
commit dcb48db5fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -255,7 +255,7 @@ namespace llarp
{
(void)params;
static constexpr Default ProfilingValueDefault{false};
static constexpr Default ProfilingValueDefault{true};
static constexpr Default ReachableDefault{true};
static constexpr Default HopsDefault{4};
static constexpr Default PathsDefault{6};

@ -66,11 +66,8 @@ namespace llarp
Proxy::HandleUDPRecv_server(llarp_udp_io* u, const SockAddr& from, ManagedBuffer buf)
{
Buffer_t msgbuf = CopyBuffer(buf.underlying);
auto self = static_cast<Proxy*>(u->user)->shared_from_this();
// yes we use the server loop here because if the server loop is not the
// client loop we'll crash again
LogicCall(
self->m_ServerLogic, [self, from, msgbuf]() { self->HandlePktServer(from, msgbuf); });
auto self = static_cast<Proxy*>(u->user);
self->HandlePktServer(from, msgbuf);
}
void
@ -140,7 +137,8 @@ namespace llarp
void
Proxy::SendServerMessageBufferTo(const SockAddr& to, const llarp_buffer_t& buf)
{
llarp_ev_udp_sendto(&m_Server, to, buf);
if (llarp_ev_udp_sendto(&m_Server, to, buf) < 0)
llarp::LogError("dns reply failed");
}
void
@ -244,7 +242,6 @@ namespace llarp
return;
}
TX tx = {hdr.id, from};
Message msg(hdr);
if (!msg.Decode(&pkt))
{

@ -16,58 +16,28 @@ namespace llarp::dns
UnboundResolver::Reset()
{
started = false;
if (runner)
{
runner->join();
runner.reset();
}
if (unboundContext)
{
DeregisterPollFD();
ub_ctx_delete(unboundContext);
}
unboundContext = nullptr;
}
void
UnboundResolver::DeregisterPollFD()
{
#ifdef _WIN32
runnerThread->join();
#else
eventLoop->deregister_poll_fd_readable(ub_fd(unboundContext));
#endif
}
void
UnboundResolver::RegisterPollFD()
{
#ifdef _WIN32
runnerThread = std::make_unique<std::thread>([self = shared_from_this()]() {
while (self->started)
{
using namespace std::chrono_literals;
std::this_thread::sleep_for(20ms);
ub_wait(self->unboundContext);
}
});
#else
eventLoop->register_poll_fd_readable(
ub_fd(unboundContext), [=]() { ub_process(unboundContext); });
#endif
}
UnboundResolver::UnboundResolver(llarp_ev_loop_ptr loop, ReplyFunction reply, FailFunction fail)
: unboundContext(nullptr)
, started(false)
, eventLoop(loop)
#ifdef _WIN32
// on win32 we use another thread for io because LOL windows
, replyFunc([loop, reply](auto source, auto buf) {
loop->call_soon([source, buf, reply]() { reply(source, buf); });
})
, failFunc([loop, fail](auto source, auto message) {
loop->call_soon([source, message, fail]() { fail(source, message); });
})
#else
, replyFunc(reply)
, failFunc(fail)
#endif
{}
// static callback
@ -88,10 +58,9 @@ namespace llarp::dns
ub_resolve_free(result);
return;
}
llarp_buffer_t buf;
buf.base = buf.cur = static_cast<byte_t*>(result->answer_packet);
buf.sz = result->answer_len;
std::vector<byte_t> pkt(result->answer_len);
std::copy_n(static_cast<byte_t*>(result->answer_packet), pkt.size(), pkt.data());
llarp_buffer_t buf(pkt);
MessageHeader hdr;
hdr.Decode(&buf);
@ -100,10 +69,7 @@ namespace llarp::dns
buf.cur = buf.base;
hdr.Encode(&buf);
std::vector<byte_t> buf_copy(buf.sz);
std::copy_n(buf.base, buf.sz, buf_copy.begin());
this_ptr->replyFunc(lookup->source, std::move(buf_copy));
this_ptr->replyFunc(lookup->source, std::move(pkt));
ub_resolve_free(result);
}
@ -123,12 +89,16 @@ namespace llarp::dns
return false;
}
#ifdef _WIN32
ub_ctx_async(unboundContext, 1);
#endif
runner = std::make_unique<std::thread>([&]() {
while (started)
{
if (unboundContext)
ub_wait(unboundContext);
std::this_thread::sleep_for(25ms);
}
});
started = true;
RegisterPollFD();
return true;
}

@ -24,12 +24,9 @@ namespace llarp::dns
{
private:
ub_ctx* unboundContext;
#ifdef _WIN32
/// windows needs to run as blocking in another thread to work at all becuase LOL windows
std::unique_ptr<std::thread> runnerThread;
#endif
std::atomic<bool> started;
std::unique_ptr<std::thread> runner;
llarp_ev_loop_ptr eventLoop;
ReplyFunction replyFunc;
@ -38,11 +35,6 @@ namespace llarp::dns
void
Reset();
void
DeregisterPollFD();
void
RegisterPollFD();
public:
UnboundResolver(llarp_ev_loop_ptr eventLoop, ReplyFunction replyFunc, FailFunction failFunc);

@ -474,13 +474,20 @@ namespace libuv
if (self == nullptr)
return -1;
auto buf = uv_buf_init((char*)ptr, sz);
return uv_udp_try_send(&self->m_Handle, &buf, 1, to);
auto ret = uv_udp_try_send(
&self->m_Handle, &buf, 1, (const sockaddr*)static_cast<const sockaddr_in*>(to));
if (ret < 0)
{
llarp::LogError("udp sendto failed: ", uv_strerror(ret));
}
return ret;
}
bool
Bind()
{
auto ret = uv_udp_bind(&m_Handle, m_Addr, 0);
auto ret =
uv_udp_bind(&m_Handle, (const sockaddr*)static_cast<const sockaddr_in*>(m_Addr), 0);
if (ret)
{
llarp::LogError("failed to bind to ", m_Addr, " ", uv_strerror(ret));

@ -1,5 +1,5 @@
#include <net/sock_addr.hpp>
#include <net/net_bits.hpp>
#include <util/str.hpp>
#include <util/logging/logger.hpp>
#include <util/mem.hpp>
@ -12,10 +12,15 @@ namespace llarp
/// shared utility functions
///
constexpr auto addrIsV4 = [](const in6_addr& addr) -> bool {
return addr.s6_addr[10] == 0xff and addr.s6_addr[11] == 0xff;
};
void
SockAddr::init()
{
llarp::Zero(&m_addr, sizeof(m_addr));
llarp::Zero(&m_addr4, sizeof(m_addr4));
}
void
@ -96,7 +101,8 @@ namespace llarp
// avoid byte order conversion (this is NBO -> NBO)
memcpy(m_addr.sin6_addr.s6_addr + 12, &other.sin_addr.s_addr, sizeof(in_addr));
m_addr.sin6_port = other.sin_port;
m_addr4.sin_addr.s_addr = other.sin_addr.s_addr;
m_addr4.sin_port = other.sin_port;
m_empty = false;
return *this;
@ -113,7 +119,13 @@ namespace llarp
init();
memcpy(&m_addr, &other, sizeof(sockaddr_in6));
if (addrIsV4(other.sin6_addr))
setIPv4(
other.sin6_addr.s6_addr[12],
other.sin6_addr.s6_addr[13],
other.sin6_addr.s6_addr[14],
other.sin6_addr.s6_addr[15]);
setPort(ntohs(other.sin6_port));
m_empty = false;
return *this;
@ -130,7 +142,8 @@ namespace llarp
init();
memcpy(&m_addr.sin6_addr.s6_addr, &other.s6_addr, sizeof(m_addr.sin6_addr.s6_addr));
if (addrIsV4(other))
setIPv4(other.s6_addr[12], other.s6_addr[13], other.s6_addr[14], other.s6_addr[15]);
m_empty = false;
return *this;
@ -141,6 +154,11 @@ namespace llarp
return (sockaddr*)&m_addr;
}
SockAddr::operator const sockaddr_in*() const
{
return &m_addr4;
}
SockAddr::operator const sockaddr_in6*() const
{
return &m_addr;
@ -244,15 +262,9 @@ namespace llarp
// treat SIIT like IPv4
constexpr auto MaxIPv4PlusPortStringSize = 22;
str.reserve(MaxIPv4PlusPortStringSize);
// TODO: ensure these don't each incur a memory allocation
str.append(std::to_string(ip6[12]));
str.append(1, '.');
str.append(std::to_string(ip6[13]));
str.append(1, '.');
str.append(std::to_string(ip6[14]));
str.append(1, '.');
str.append(std::to_string(ip6[15]));
char buf[128] = {0x0};
inet_ntop(AF_INET, &m_addr4.sin_addr.s_addr, buf, sizeof(buf));
str.append(buf);
}
else
{
@ -281,7 +293,7 @@ namespace llarp
void
SockAddr::setIPv4(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
m_addr.sin6_family = AF_INET6;
m_addr.sin6_family = AF_INET;
uint8_t* ip6 = m_addr.sin6_addr.s6_addr;
llarp::Zero(ip6, sizeof(m_addr.sin6_addr.s6_addr));
@ -292,7 +304,9 @@ namespace llarp
ip6[13] = b;
ip6[14] = c;
ip6[15] = d;
const auto ip = ipaddr_ipv4_bits(a, b, c, d);
m_addr4.sin_addr.s_addr = htonl(ip.h);
m_addr4.sin_family = AF_INET;
m_empty = false;
}
@ -300,6 +314,7 @@ namespace llarp
SockAddr::setPort(uint16_t port)
{
m_addr.sin6_port = htons(port);
m_addr4.sin_port = htons(port);
}
uint16_t

@ -49,6 +49,7 @@ namespace llarp
operator=(const in6_addr& addr);
operator const sockaddr*() const;
operator const sockaddr_in*() const;
operator const sockaddr_in6*() const;
bool
@ -82,6 +83,7 @@ namespace llarp
private:
bool m_empty = true;
sockaddr_in6 m_addr;
sockaddr_in m_addr4;
void
init();

@ -476,7 +476,7 @@ namespace llarp
void
Builder::HandlePathBuildTimeout(Path_ptr p)
{
m_router->routerProfiling().MarkPathFail(p.get());
m_router->routerProfiling().MarkPathTimeout(p.get());
PathSet::HandlePathBuildTimeout(p);
DoPathBuildBackoff();
}

@ -15,6 +15,8 @@ namespace llarp
return false;
if (!BEncodeWriteDictInt("p", pathSuccessCount, buf))
return false;
if (!BEncodeWriteDictInt("q", pathTimeoutCount, buf))
return false;
if (!BEncodeWriteDictInt("s", pathFailCount, buf))
return false;
if (!BEncodeWriteDictInt("t", connectTimeoutCount, buf))
@ -43,6 +45,8 @@ namespace llarp
return false;
if (!BEncodeMaybeReadDictInt("p", pathSuccessCount, read, k, buf))
return false;
if (!BEncodeMaybeReadDictInt("q", pathTimeoutCount, read, k, buf))
return false;
return read;
}
@ -53,14 +57,14 @@ namespace llarp
connectTimeoutCount /= 2;
pathSuccessCount /= 2;
pathFailCount /= 2;
pathTimeoutCount /= 2;
lastDecay = llarp::time_now_ms();
}
void
RouterProfile::Tick()
{
// 15 seconds
static constexpr auto updateInterval = 15s;
static constexpr auto updateInterval = 30min;
const auto now = llarp::time_now_ms();
if (lastDecay < now && now - lastDecay > updateInterval)
Decay();
@ -92,7 +96,8 @@ namespace llarp
bool
RouterProfile::IsGoodForPath(uint64_t chances) const
{
return checkIsGood(pathFailCount, pathSuccessCount, chances);
return checkIsGood(pathFailCount, pathSuccessCount, chances)
and checkIsGood(pathTimeoutCount, pathSuccessCount, chances);
}
Profiling::Profiling() : m_DisableProfiling(false)
@ -119,7 +124,7 @@ namespace llarp
auto itr = m_Profiles.find(r);
if (itr == m_Profiles.end())
return false;
return !itr->second.IsGoodForConnect(chances);
return not itr->second.IsGoodForConnect(chances);
}
bool
@ -131,7 +136,7 @@ namespace llarp
auto itr = m_Profiles.find(r);
if (itr == m_Profiles.end())
return false;
return !itr->second.IsGoodForPath(chances);
return not itr->second.IsGoodForPath(chances);
}
bool
@ -143,7 +148,7 @@ namespace llarp
auto itr = m_Profiles.find(r);
if (itr == m_Profiles.end())
return false;
return !itr->second.IsGood(chances);
return not itr->second.IsGood(chances);
}
void
@ -201,6 +206,22 @@ namespace llarp
}
}
void
Profiling::MarkPathTimeout(path::Path* p)
{
util::Lock lock(m_ProfilesMutex);
size_t idx = 0;
for (const auto& hop : p->hops)
{
if (idx)
{
m_Profiles[hop.rc.pubkey].pathTimeoutCount += 1;
m_Profiles[hop.rc.pubkey].lastUpdated = llarp::time_now_ms();
}
++idx;
}
}
void
Profiling::MarkPathSuccess(path::Path* p)
{
@ -208,6 +229,10 @@ namespace llarp
const auto sz = p->hops.size();
for (const auto& hop : p->hops)
{
// redeem previous fails by halfing the fail count and setting timeout to zero
m_Profiles[hop.rc.pubkey].pathFailCount /= 2;
m_Profiles[hop.rc.pubkey].pathTimeoutCount = 0;
// mark success at hop
m_Profiles[hop.rc.pubkey].pathSuccessCount += sz;
m_Profiles[hop.rc.pubkey].lastUpdated = llarp::time_now_ms();
}

@ -18,6 +18,7 @@ namespace llarp
uint64_t connectGoodCount = 0;
uint64_t pathSuccessCount = 0;
uint64_t pathFailCount = 0;
uint64_t pathTimeoutCount = 0;
llarp_time_t lastUpdated = 0s;
llarp_time_t lastDecay = 0s;
uint64_t version = LLARP_PROTO_VERSION;
@ -68,6 +69,9 @@ namespace llarp
void
MarkConnectSuccess(const RouterID& r) EXCLUDES(m_ProfilesMutex);
void
MarkPathTimeout(path::Path* p) EXCLUDES(m_ProfilesMutex);
void
MarkPathFail(path::Path* p) EXCLUDES(m_ProfilesMutex);

@ -100,7 +100,6 @@ tuntap_start(struct device *dev, int mode, int tun)
}
dev->tun_fd = fd;
tuntap_set_debug(dev, 0);
return 0;
clean:
@ -370,38 +369,3 @@ tuntap_set_nonblocking(struct device *dev, int set)
}
return 0;
}
int
tuntap_set_debug(struct device *dev, int set)
{
/* Only accept started device */
if(dev->tun_fd == -1)
{
tuntap_log(TUNTAP_LOG_NOTICE, "Device is not started");
return 0;
}
#if defined(__linux__)
if(ioctl(dev->tun_fd, TUNSETDEBUG, &set) == -1)
{
switch(set)
{
case 0:
tuntap_log(TUNTAP_LOG_WARN, "Can't unset debug");
break;
case 1:
tuntap_log(TUNTAP_LOG_WARN, "Can't set debug");
break;
default:
tuntap_log(TUNTAP_LOG_ERR, "Invalid parameter 'set'");
}
return -1;
}
return 0;
#else
(void)set;
tuntap_log(TUNTAP_LOG_NOTICE,
"Your system does not support tuntap_set_debug()");
return -1;
#endif
}

Loading…
Cancel
Save