basic router profiling and fix ip rewrite

pull/15/head
Jeff Becker 6 years ago
parent 76e87aa608
commit 6986f04418
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -354,6 +354,7 @@ set(LIB_SRC
llarp/path.cpp
llarp/pathbuilder.cpp
llarp/pathset.cpp
llarp/profiling.cpp
llarp/proofofwork.cpp
llarp/relay_commit.cpp
llarp/relay_up_down.cpp

@ -124,13 +124,13 @@ namespace llarp
void
src(uint32_t ip)
{
Header()->saddr = ip;
Header()->saddr = htonl(ip);
}
void
dst(uint32_t ip)
{
Header()->daddr = ip;
Header()->daddr = htonl(ip);
}
// update ip packet checksum

@ -73,6 +73,13 @@ bool
llarp_nodedb_get_rc(struct llarp_nodedb *n, const llarp::RouterID &pk,
llarp::RouterContact &result);
/**
remove rc by public key from nodedb
returns true if removed
*/
bool
llarp_nodedb_del_rc(struct llarp_nodedb *n, const llarp::RouterID &pk);
/// struct for async rc verification
struct llarp_async_verify_rc;

@ -0,0 +1,67 @@
#ifndef LLARP_PROFILING_HPP
#define LLARP_PROFILING_HPP
#include <llarp/bencode.hpp>
#include <llarp/threading.hpp>
#include <llarp/router_id.hpp>
#include <map>
namespace llarp
{
struct RouterProfile : public IBEncodeMessage
{
static constexpr size_t MaxSize = 128;
uint64_t connectTimeoutCount = 0;
uint64_t connectGoodCount = 0;
RouterProfile() : IBEncodeMessage(){};
~RouterProfile(){};
bool
BEncode(llarp_buffer_t* buf) const;
bool
DecodeKey(llarp_buffer_t k, llarp_buffer_t* buf);
bool
IsGood() const;
};
struct Profiling : public IBEncodeMessage
{
Profiling() : IBEncodeMessage(){};
~Profiling()
{
}
bool
IsBad(const RouterID& r);
void
MarkSuccess(const RouterID& r);
void
MarkTimeout(const RouterID& r);
bool
BEncode(llarp_buffer_t* buf) const;
bool
DecodeKey(llarp_buffer_t k, llarp_buffer_t* buf);
bool
Load(const char* fname);
bool
Save(const char* fname);
private:
typedef llarp::util::Lock lock_t;
typedef llarp::util::Mutex mtx_t;
mtx_t m_ProfilesMutex;
std::map< RouterID, RouterProfile > m_Profiles;
};
} // namespace llarp
#endif

@ -143,12 +143,12 @@ namespace llarp
llarp::LogError(Name(), " failed to set up tun interface");
return false;
}
m_OurIP = inet_addr(tunif.ifaddr);
m_NextIP = ntohl(m_OurIP);
m_OurIP = ntohl(inet_addr(tunif.ifaddr));
m_NextIP = m_OurIP;
uint32_t mask = tunif.netmask;
uint32_t baseaddr = (ntohl(m_OurIP) & netmask_ipv4_bits(mask));
m_MaxIP = (ntohl(baseaddr) | ~ntohl(netmask_ipv4_bits(mask)));
uint32_t baseaddr = (htonl(m_OurIP) & netmask_ipv4_bits(mask));
m_MaxIP = (htonl(baseaddr) | ~htonl(netmask_ipv4_bits(mask)));
char buf[128] = {0};
llarp::LogInfo(Name(), " set ", tunif.ifname, " to have address ",
inet_ntop(AF_INET, &m_OurIP, buf, sizeof(buf)));
@ -210,7 +210,7 @@ namespace llarp
pkt.dst(usIP);
pkt.UpdateChecksum();
llarp::LogInfo(Name(), " handle data message ", msg->payload.size(),
" bytes from ", inet_ntoa({themIP}));
" bytes from ", inet_ntoa({htonl(themIP)}));
llarp_ev_tun_async_write(&tunif, pkt.buf, pkt.sz);
/*
@ -235,7 +235,7 @@ namespace llarp
TunEndpoint::ObtainIPForAddr(const service::Address &addr)
{
llarp_time_t now = llarp_time_now_ms();
uint32_t nextIP;
uint32_t nextIP = 0;
{
// previously allocated address
auto itr = m_AddrToIP.find(addr);
@ -246,11 +246,14 @@ namespace llarp
return itr->second;
}
}
// allocate new address
if(m_NextIP < m_MaxIP)
{
nextIP = ++m_NextIP;
m_AddrToIP.insert(std::make_pair(addr, nextIP));
m_IPToAddr.insert(std::make_pair(nextIP, addr));
llarp::LogInfo(Name(), " mapped ", addr, " to ",
inet_ntoa({htonl(nextIP)}));
}
else
{

@ -347,6 +347,12 @@ namespace llarp
static uint64
OnError(utp_callback_arguments* arg)
{
BaseSession* session =
static_cast< BaseSession* >(utp_get_userdata(arg->socket));
if(arg->error_code == UTP_ETIMEDOUT)
{
session->Router()->OnConnectTimeout(session->GetPubKey());
}
llarp::LogError(utp_error_code_names[arg->error_code]);
return 0;
}

@ -27,6 +27,18 @@ struct llarp_nodedb
entries;
fs::path nodePath;
bool
Remove(const llarp::PubKey &pk)
{
llarp::util::Lock lock(access);
auto itr = entries.find(pk);
if(itr == entries.end())
return false;
entries.erase(itr);
fs::remove(fs::path(getRCFilePath(pk)));
return true;
}
void
Clear()
{
@ -393,6 +405,12 @@ llarp_nodedb_num_loaded(struct llarp_nodedb *n)
return n->entries.size();
}
bool
llarp_nodedb_del_rc(struct llarp_nodedb *n, const llarp::RouterID &pk)
{
return n->Remove(pk);
}
bool
llarp_nodedb_select_random_hop(struct llarp_nodedb *n,
const llarp::RouterContact &prev,

@ -342,6 +342,7 @@ namespace llarp
intro.router = hops[hsz - 1].rc.pubkey;
// TODO: or is it rxid ?
intro.pathID = hops[hsz - 1].txID;
EnterState(ePathBuilding);
}
void
@ -386,6 +387,19 @@ namespace llarp
if(Expired(now))
return;
if(_status == ePathBuilding)
{
if(now < buildStarted)
return;
auto dlt = now - buildStarted;
if(dlt >= PATH_BUILD_TIMEOUT)
{
llarp::LogInfo("timed out with ", dlt, " ms");
EnterState(ePathTimeout);
return;
}
}
if(now < m_LastLatencyTestTime)
return;
auto dlt = now - m_LastLatencyTestTime;
@ -398,13 +412,16 @@ namespace llarp
SendRoutingMessage(&latency, r);
}
// check to see if this path is dead
if(m_CheckForDead)
if(_status == ePathEstablished)
{
if(m_CheckForDead(this, dlt))
if(m_CheckForDead)
{
if(m_CheckForDead(this, dlt))
EnterState(ePathTimeout);
}
else if(dlt >= 10000)
EnterState(ePathTimeout);
}
else if(dlt >= 10000)
EnterState(ePathTimeout);
}
bool
@ -433,8 +450,6 @@ namespace llarp
if(_status == ePathEstablished)
return now - buildStarted > hops[0].lifetime;
else if(_status == ePathBuilding)
return now - buildStarted > PATH_BUILD_TIMEOUT;
else if(_status == ePathTimeout)
return false;
else
return true;

@ -143,7 +143,6 @@ namespace llarp
return;
}
ctx->path->EnterState(llarp::path::ePathBuilding);
// persist session with router until this path is done
router->PersistSessionUntil(remote, ctx->path->ExpireTime());
// add own path

@ -22,11 +22,7 @@ namespace llarp
{
for(auto& item : m_Paths)
{
auto st = item.second->_status;
if(st == ePathTimeout || st == ePathEstablished)
{
item.second->Tick(now, r);
}
item.second->Tick(now, r);
}
}
@ -71,17 +67,23 @@ namespace llarp
Path*
PathSet::GetPathByRouter(const RouterID& id) const
{
auto itr = m_Paths.begin();
Path* chosen = nullptr;
auto itr = m_Paths.begin();
while(itr != m_Paths.end())
{
if(itr->second->IsReady())
{
if(itr->second->Endpoint() == id)
return itr->second;
{
if(chosen == nullptr)
chosen = itr->second;
else if(chosen->intro.latency > itr->second->intro.latency)
chosen = itr->second;
}
}
++itr;
}
return nullptr;
return chosen;
}
Path*

@ -0,0 +1,125 @@
#include <llarp/profiling.hpp>
#include <fstream>
namespace llarp
{
bool
RouterProfile::BEncode(llarp_buffer_t* buf) const
{
if(!bencode_start_dict(buf))
return false;
if(!BEncodeWriteDictInt("g", connectGoodCount, buf))
return false;
if(!BEncodeWriteDictInt("t", connectTimeoutCount, buf))
return false;
if(!BEncodeWriteDictInt("v", version, buf))
return false;
return bencode_end(buf);
}
bool
RouterProfile::DecodeKey(llarp_buffer_t k, llarp_buffer_t* buf)
{
bool read = false;
if(!BEncodeMaybeReadDictInt("g", connectGoodCount, read, k, buf))
return false;
if(!BEncodeMaybeReadDictInt("t", connectTimeoutCount, read, k, buf))
return false;
if(!BEncodeMaybeReadDictInt("v", version, read, k, buf))
return false;
return read;
}
bool
RouterProfile::IsGood() const
{
return connectTimeoutCount <= connectGoodCount;
}
bool
Profiling::IsBad(const RouterID& r)
{
lock_t lock(m_ProfilesMutex);
auto itr = m_Profiles.find(r);
if(itr == m_Profiles.end())
return false;
return !itr->second.IsGood();
}
void
Profiling::MarkTimeout(const RouterID& r)
{
lock_t lock(m_ProfilesMutex);
m_Profiles[r].connectTimeoutCount += 1;
}
void
Profiling::MarkSuccess(const RouterID& r)
{
lock_t lock(m_ProfilesMutex);
m_Profiles[r].connectGoodCount += 1;
}
bool
Profiling::Save(const char* fname)
{
lock_t lock(m_ProfilesMutex);
size_t sz = (m_Profiles.size() * (RouterProfile::MaxSize + 32 + 8)) + 8;
byte_t* tmp = new byte_t[sz];
auto buf = llarp::InitBuffer(tmp, sz);
auto res = BEncode(&buf);
if(res)
{
buf.sz = buf.cur - buf.base;
std::ofstream f;
f.open(fname);
if(f.is_open())
{
f.write((char*)buf.base, buf.sz);
}
}
delete[] tmp;
return res;
}
bool
Profiling::BEncode(llarp_buffer_t* buf) const
{
if(!bencode_start_dict(buf))
return false;
auto itr = m_Profiles.begin();
while(itr != m_Profiles.end())
{
if(!itr->first.BEncode(buf))
return false;
if(!itr->second.BEncode(buf))
return false;
++itr;
}
return bencode_end(buf);
}
bool
Profiling::DecodeKey(llarp_buffer_t k, llarp_buffer_t* buf)
{
if(k.sz != 32)
return false;
RouterProfile profile;
if(!profile.BDecode(buf))
return false;
RouterID pk = k.base;
return m_Profiles.insert(std::make_pair(pk, profile)).second;
}
bool
Profiling::Load(const char* fname)
{
lock_t lock(m_ProfilesMutex);
m_Profiles.clear();
return BDecodeReadFile(fname, *this);
}
} // namespace llarp

@ -375,6 +375,14 @@ llarp_router::TryEstablishTo(const llarp::RouterID &remote)
}
}
void
llarp_router::OnConnectTimeout(const llarp::RouterID &remote)
{
routerProfiling.MarkTimeout(remote);
if(routerProfiling.IsBad(remote))
llarp_nodedb_del_rc(nodedb, remote);
}
void
llarp_router::HandleDHTLookupForTryEstablishTo(
const std::vector< llarp::RouterContact > &results)
@ -431,17 +439,14 @@ llarp_router::Tick()
if(inboundLinks.size() == 0)
{
auto N = llarp_nodedb_num_loaded(nodedb);
if(N >= 4)
{
paths.BuildPaths();
}
else
if(N < 4)
{
llarp::LogInfo(
"We need at least 4 service nodes to build paths but we have ", N);
auto explore = std::max(NumberOfConnectedRouters(), 1UL);
dht->impl.Explore(explore);
}
paths.BuildPaths();
hiddenServiceContext.Tick();
}
else if(NumberOfConnectedRouters() < minConnectedRouters)
@ -601,6 +606,7 @@ llarp_router::async_verify_RC(const llarp::RouterContact &rc)
void
llarp_router::Run()
{
routerProfiling.Load(routerProfilesFile.string().c_str());
// zero out router contact
sockaddr *dest = (sockaddr *)&this->ip4addr;
llarp::Addr publicAddr(*dest);
@ -845,7 +851,10 @@ void
llarp_stop_router(struct llarp_router *router)
{
if(router)
{
router->Close();
router->routerProfiling.Save(router->routerProfilesFile.string().c_str());
}
}
void
@ -1004,6 +1013,10 @@ namespace llarp
}
else if(StrEq(section, "network"))
{
if(StrEq(key, "profiles"))
{
self->routerProfilesFile = fs::path(val);
}
if(StrEq(key, "min-connected"))
{
self->minConnectedRouters = std::max(atoi(val), 0);

@ -18,6 +18,7 @@
#include <llarp/routing/handler.hpp>
#include <llarp/service.hpp>
#include <llarp/establish_job.hpp>
#include <llarp/profiling.hpp>
#include "crypto.hpp"
#include "fs.hpp"
@ -93,6 +94,9 @@ struct llarp_router
std::unique_ptr< llarp::ILinkLayer > outboundLink;
std::list< std::unique_ptr< llarp::ILinkLayer > > inboundLinks;
llarp::Profiling routerProfiling;
fs::path routerProfilesFile = "profiles.dat";
typedef std::queue< std::vector< byte_t > > MessageQueue;
/// outbound message queue
@ -167,6 +171,9 @@ struct llarp_router
return llarp::seckey_topublic(identity);
}
void
OnConnectTimeout(const llarp::RouterID &remote);
bool
HasPendingConnectJob(const llarp::RouterID &remote);

Loading…
Cancel
Save