Ryan Tharp 6 years ago
commit 5248283128

1
.gitignore vendored

@ -37,3 +37,4 @@ testnet_tmp
vsproject/
daemon.ini
lokinet

@ -67,6 +67,7 @@
"shared_mutex": "cpp",
"complex": "cpp",
"variant": "cpp",
"any": "cpp"
"any": "cpp",
"tuntap.h": "c"
}
}

@ -1,32 +1,21 @@
cmake_minimum_required(VERSION 2.8.10)
# Lowest version - debian stable is 3.7.2
cmake_minimum_required(VERSION 3.7.0)
set(PROJECT_NAME lokinet)
project(${PROJECT_NAME} C CXX ASM)
option(USE_LIBABYSS "enable libabyss" OFF)
macro(add_cflags)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARGN}")
endmacro(add_cflags)
# Require C++11
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
macro(add_cxxflags)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARGN}")
endmacro(add_cxxflags)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
if(COMPILER_SUPPORTS_CXX11)
add_cxxflags("-std=c++11")
else()
message(ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
add_cxxflags("-fpermissive")
add_compile_options( -fpermissive )
if (WOW64_CROSS_COMPILE OR WIN64_CROSS_COMPILE)
if (USING_CLANG)
add_cxxflags("-Wno-unused-command-line-argument -Wno-c++11-narrowing")
add_cflags("-Wno-unused-command-line-argument")
add_compile_options(-Wno-unused-command-line-argument -Wno-c++11-narrowing)
# because clang is insane enough to inline whole sections of the C++ library!
# May have been fixed in llvm-7.
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-multiple-definition --rtlib=libgcc")
@ -37,15 +26,12 @@ if(DEBIAN)
add_definitions(-DDEBIAN)
endif()
if(ANDROID)
set(THREAD_LIB "-pthread")
else()
set(THREAD_LIB pthread)
endif()
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
if(STATIC_LINK)
add_cflags("-static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive")
add_cxxflags("-static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive")
add_compile_options( -static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive )
endif()
if(DNS_PORT)
@ -62,11 +48,10 @@ if(TESTNET)
add_definitions(-DTESTNET=1)
endif()
add_cflags("-Wall")
add_cxxflags("-Wall")
add_compile_options( -Wall )
set(OPTIMIZE_FLAGS "-O3")
set(DEBUG_FLAGS "-O0 -g3")
set(OPTIMIZE_FLAGS -O3 )
set(DEBUG_FLAGS -O0 -g3 )
if(ASAN)
set(DEBUG_FLAGS "${DEBUG_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
@ -85,8 +70,7 @@ if(SHADOW)
set(CMAKE_MODULE_PATH "${SHADOW_ROOT}/share/cmake/Modules")
include_directories(${CMAKE_MODULE_PATH})
include(ShadowTools)
add_cxxflags("-fno-inline -fno-strict-aliasing")
add_cflags("-fno-inline -fno-strict-aliasing")
add_compile_options( -fno-inline -fno-strict-aliasing )
add_definitions(-DTESTNET=true)
add_definitions(-DSHADOW_TESTNET)
include_directories(${SHADOW_ROOT}/include)
@ -94,19 +78,16 @@ endif()
if(CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")
set(OPTIMIZE_FLAGS "")
add_cflags("${DEBUG_FLAGS}")
add_cxxflags("${DEBUG_FLAGS}")
add_compile_options( ${DEBUG_FLAGS} )
endif()
set(CRYPTO_FLAGS "-march=native")
set(CMAKE_ASM_FLAGS "-march=native")
add_cflags("-Wall -Wno-deprecated-declarations ${OPTIMIZE_FLAGS} ${CRYPTO_FLAGS}")
add_cxxflags("-Wall -Wno-deprecated-declarations ${OPTIMIZE_FLAGS} ${CRYPTO_FLAGS}")
add_compile_options( -Wall -Wno-deprecated-declarations ${OPTIMIZE_FLAGS} ${CRYPTO_FLAGS} )
if(SHADOW)
add_cflags("-fPIC")
add_cxxflags("-fPIC")
add_compile_options( -fPIC)
endif()
if(NOT GIT_VERSION)
@ -131,7 +112,7 @@ if(JEMALLOC)
endif()
#set(FS_LIB stdc++fs)
set(LIBS ${THREAD_LIB} ${MALLOC_LIB} ${FS_LIB})
set(LIBS Threads::Threads ${MALLOC_LIB} ${FS_LIB})
set(LIB lokinet)
set(SHARED_LIB ${LIB})
@ -311,7 +292,7 @@ set(CHACHA_SRC
crypto/salsa20/xmm6int/salsa20_xmm6int-sse2.c
crypto/xchacha20/hchacha.c
crypto/xchacha20/stream_xchacha20.c)
set(CSRNG_SRC
crypto/csrng/randombytes_salsa20_random.c
crypto/csrng/randombytes.c)
@ -327,7 +308,7 @@ set(BLAKE2B_SRC
crypto/blake2b/blake2b-ref.c
crypto/blake2b/generichash_blake2b.c)
set(X25519_SRC
set(X25519_SRC
crypto/curve25519/crypto_scalarmult.c
crypto/curve25519/ref10/x25519_ref10.c
crypto/curve25519/ref10/ed25519_ref10.c
@ -534,9 +515,9 @@ if(WITH_STATIC)
add_library(${STATIC_LIB} STATIC ${LIB_SRC})
add_library(${PLATFORM_LIB} STATIC ${LIB_PLATFORM_SRC})
if(USE_LIBABYSS)
target_link_libraries(${PLATFORM_LIB} ${THREAD_LIB} ${ABYSS_LIB})
target_link_libraries(${PLATFORM_LIB} Threads::Threads ${ABYSS_LIB})
else()
target_link_libraries(${PLATFORM_LIB} ${THREAD_LIB})
target_link_libraries(${PLATFORM_LIB} Threads::Threads)
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
target_link_libraries(${PLATFORM_LIB} -lcap)
@ -555,9 +536,9 @@ if(WITH_STATIC)
target_link_libraries(${TEST_EXE} ${STATIC_LINK_LIBS} gtest_main ${STATIC_LIB} ${PLATFORM_LIB} ws2_32 iphlpapi)
endif(WIN32)
if (WIN32)
target_link_libraries(${DNS_EXE} ${STATIC_LIB} ${PLATFORM_LIB} ${THREAD_LIB} ws2_32 iphlpapi)
target_link_libraries(${DNS_EXE} ${STATIC_LIB} ${PLATFORM_LIB} Threads::Threads ws2_32 iphlpapi)
endif(WIN32)
target_link_libraries(${DNS_EXE} ${STATIC_LIB} ${PLATFORM_LIB} ${THREAD_LIB})
target_link_libraries(${DNS_EXE} ${STATIC_LIB} ${PLATFORM_LIB} Threads::Threads)
endif(NOT WITH_SHARED)
endif(WITH_STATIC)
if(ANDROID)
@ -570,9 +551,9 @@ if(WITH_STATIC)
if (WIN32)
set(${LIBS} ${LIBS} ws2_32 iphlpapi)
endif(WIN32)
target_link_libraries(${SHARED_LIB} ${LIBS} ${THREAD_LIB})
target_link_libraries(${SHARED_LIB} ${LIBS} Threads::Threads)
target_link_libraries(${EXE} ${SHARED_LIB})
target_link_libraries(${RC_EXE} ${SHARED_LIB})
target_link_libraries(${DNS_EXE} ${SHARED_LIB} ${THREAD_LIB})
target_link_libraries(${DNS_EXE} ${SHARED_LIB} Threads::Threads)
endif(WITH_SHARED)
endif(SHADOW)

@ -10,6 +10,8 @@ PREFIX ?= /usr/local
CC ?= cc
CXX ?= c++
SETCAP ?= which setcap && setcap cap_net_admin=+eip
SHADOW_ROOT ?= $(HOME)/.shadow
SHADOW_BIN=$(SHADOW_ROOT)/bin/shadow
SHADOW_CONFIG=$(REPO)/shadow.config.xml
@ -142,7 +144,7 @@ install:
rm -f $(PREFIX)/bin/lokinet
cp $(EXE) $(PREFIX)/bin/lokinet
chmod 755 $(PREFIX)/bin/lokinet
setcap cap_net_admin=+eip $(PREFIX)/bin/lokinet
$(SETCAP) $(PREFIX)/bin/lokinet || true
rm -f $(PREFIX)/bin/lokinet-bootstrap
cp $(REPO)/lokinet-bootstrap $(PREFIX)/bin/lokinet-bootstrap
chmod 755 $(PREFIX)/bin/lokinet-bootstrap

@ -0,0 +1,18 @@
#!/usr/sbin/dtrace -s
syscall:::entry
/pid == $target/
{
@calls[ustack(10), probefunc] = count();
}
profile:::tick-1sec
{
/** print */
printa(@calls);
/** clear */
clear(@calls);
trunc(@calls, 15);
}

45
debian/lokinet.1 vendored

@ -1,35 +1,58 @@
.TH "lokinet" "1" "Aug 09, 2018"
.TH "lokinet" "1" "Oct 28, 2018"
.SH "NAME"
lokinet \- Reference implementation for LLARP.
.SH "SYNOPSIS"
.B lokinet
[\fIconfig.ini\fR]
[\fI options ... \fR] [\fI config.ini \fR]
.SH "DESCRIPTION"
.PP
For a number of years, work has been proceeding in order to bring prefection
to the crudely concieved idea of a packet based onion routing protocol with a
cryptoeconomic insentive sybil resistence that not only would be able to
cryptoeconomical sybil resistence incentive that not only would be able to
provide low latency anonymous internet access but also be capable of
automatically tunneling all local network traffic over said mixnet. Such an a
program would be the turbo encab-, rather, lokinet. Now basically the only new
principal involved is that now instead of restricting the user to using TCP and
program would be the turbo encabu...\fBlokinet\fR . Now basically the only new
principle involved is that now instead of restricting the user to using TCP and
exposing a socks proxy or transparent proxy like Tor, an ip tunnel is provided
with a dns resolver for intercepting lookups for the .loki tld. The original
implementation was in C but eventually devolved into C++ in such a way that
there is a public C api but internally entirely implemented with C++11 wrapped
with a foriegn function interface. The latter being more rapidly developable,
but I digres.
but I digress ...
.SH "OPTIONS"
.IP \fB-g\fR
Generate config file
.IP \fB-f\fR
Force overwrite of existing config file
.IP \fB-r\fR
Configure to be a relay
.RE
.SH "FILES"
daemon.ini
.RS 4
default configuration file (auto generated if not present)
.I $HOME/.lokinet/
.IP
The default runtime directory
.RE
.I $HOME/.lokinet/lokinet.ini
.IP
The default config file.
.RE
.SH "SEE ALSO"
Documentation for lokinet configuration with loki service nodes.
.SH "AUTHOR"
This manual page was written by Jeff <\m[blue]\fBjeff@i2p\&.rocks\fR\m[]> for ubuntu xenial.
This manual page was written by Jeff <\m[blue]\fBjeff@i2p\&.rocks\fR\m[]>
.PP
Permission is granted to copy, distribute and/or modify this document under the terms of the same license of lokinet source code.
.RE
See the LICENSE file for more information.
See the LICENSE file for more information.

@ -413,6 +413,7 @@ transfer one or more dht messages directly without a previously made path.
v: 0
}
link immediate SML message (LISM)
transfer an SML message between nodes
@ -425,8 +426,20 @@ transfer an SML message between nodes
----
Stateles Mesh Layer (SML)
As a censor circumvention method layer 4 (udp) or layer 2 (ethernet)
network bridges are used to stateless route messages to the main onion
routing network in a stateless manner such that these network bridges
can be cacsaded many layers deep. The incentive to run these would be
the ability to hide your traffic shape in the shape of others without
the need to excess node churn.
stateless mesh discovery protocol (SMDP)
protocol for detecting and discovering mesh local
topology and where the mainline network is.
TODO: implement me
stateless mesh layer (SML)
@ -436,11 +449,16 @@ uses ethernet.
SML messages MUST be contained inside a LISM when not over ethernet.
SML message MUST be routed to the recipiant if we are not the recipiant based
on the currently unspecified stateless routing protocol.
TODO: implement routing protocol :^)
{
a: protocol_id_uint16
r: "<32 bytes public identity key of recipiant>",
s: "<32 bytes public identity key of sender>",
t: "<1024 bytes payload>",
t: "<1280 bytes payload>",
v: 0,
z: "<64 bytes signature generated by sender>"
}
@ -448,18 +466,18 @@ SML messages MUST be contained inside a LISM when not over ethernet.
protocol values:
0 - mesh discovery
t is a SMDP frame
t is a SMDP frame (todo: specify me)
1 - direct chat
t is a NUL padded plaintext chat message for node opers to communicate between
nodes.
2 - direct snode to snode ip traffic
t is an ip packet for "0 hop" communication between service nodes.
3 - relayed data packet
2 - relayed data packet
t is a udp packet relayed from a client behind a client.
3 - snode to snode direct ip traffic
t is an ip packet for "0 hop" direct ip traffic between service nodes
---
routing layer:

@ -41,7 +41,8 @@ namespace llarp
size_t MaxSize = 1024 >
struct CoDelQueue
{
CoDelQueue(const std::string& name) : m_name(name)
CoDelQueue(const std::string& name, const PutTime& put)
: m_name(name), _putTime(put)
{
}
@ -67,9 +68,9 @@ namespace llarp
return false;
}
PutTime()(m_Queue[m_QueueIdx]);
_putTime(m_Queue[m_QueueIdx]);
if(firstPut == 0)
firstPut = GetTime()(m_Queue[m_QueueIdx]);
firstPut = _getTime(m_Queue[m_QueueIdx]);
++m_QueueIdx;
return true;
@ -84,9 +85,9 @@ namespace llarp
return;
T* t = &m_Queue[m_QueueIdx];
new(t) T(std::forward< Args >(args)...);
PutTime()(m_Queue[m_QueueIdx]);
_putTime(m_Queue[m_QueueIdx]);
if(firstPut == 0)
firstPut = GetTime()(m_Queue[m_QueueIdx]);
firstPut = _getTime(m_Queue[m_QueueIdx]);
++m_QueueIdx;
}
@ -123,7 +124,7 @@ namespace llarp
if(f(*item))
break;
--m_QueueIdx;
auto dlt = start - GetTime()(*item);
auto dlt = start - _getTime(*item);
// llarp::LogInfo("CoDelQueue::Process - dlt ", dlt);
lowest = std::min(dlt, lowest);
if(m_QueueIdx == 0)
@ -156,6 +157,8 @@ namespace llarp
size_t m_QueueIdx = 0;
T m_Queue[MaxSize];
std::string m_name;
GetTime _getTime;
PutTime _putTime;
}; // namespace util
} // namespace util
} // namespace llarp

@ -385,6 +385,9 @@ namespace llarp
return ++ids;
}
llarp_time_t
Now();
private:
void
ExploreNetworkVia(const Key_t& peer);

@ -16,6 +16,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <tuntap.h>
#include <llarp/time.h>
/**
* ev.h
*
@ -45,6 +46,10 @@ llarp_ev_loop_run_single_process(struct llarp_ev_loop *ev,
struct llarp_threadpool *tp,
struct llarp_logic *logic);
/// get the current time on the event loop
llarp_time_t
llarp_ev_loop_time_now_ms(struct llarp_ev_loop *ev);
/// stop event loop and wait for it to complete all jobs
void
llarp_ev_loop_stop(struct llarp_ev_loop *ev);
@ -57,6 +62,7 @@ struct llarp_udp_io
void *user;
void *impl;
struct llarp_ev_loop *parent;
/// called every event loop tick after reads
void (*tick)(struct llarp_udp_io *);
// sockaddr * is the source

@ -3,6 +3,7 @@
#include <llarp/buffer.h>
#include <llarp/time.h>
#include <llarp/net.hpp>
#include <llarp/ev.h>
#ifndef _WIN32
// unix, linux
@ -101,10 +102,14 @@ namespace llarp
struct PutTime
{
llarp_ev_loop* loop;
PutTime(llarp_ev_loop* evloop) : loop(evloop)
{
}
void
operator()(IPv4Packet& pkt) const
{
pkt.timestamp = llarp_time_now_ms();
pkt.timestamp = llarp_ev_loop_time_now_ms(loop);
}
};

@ -18,7 +18,12 @@ namespace llarp
struct ILinkLayer
{
virtual ~ILinkLayer();
/// get current time via event loop
llarp_time_t
now() const
{
return llarp_ev_loop_time_now_ms(m_Loop);
}
bool
HasSessionTo(const PubKey& pk);
@ -111,11 +116,11 @@ namespace llarp
// timer cancelled
if(left)
return;
static_cast< ILinkLayer* >(user)->OnTick(orig, llarp_time_now_ms());
static_cast< ILinkLayer* >(user)->OnTick(orig);
}
void
OnTick(uint64_t interval, llarp_time_t now);
OnTick(uint64_t interval);
void
ScheduleTick(uint64_t interval);
@ -129,7 +134,8 @@ namespace llarp
void
PutSession(ILinkSession* s);
llarp_logic* m_Logic = nullptr;
llarp_logic* m_Logic = nullptr;
llarp_ev_loop* m_Loop = nullptr;
Addr m_ourAddr;
llarp_udp_io m_udp;
SecretKey m_SecretKey;

@ -19,11 +19,11 @@ llarp_init_single_process_logic(struct llarp_threadpool* tp);
/// single threaded tick
void
llarp_logic_tick(struct llarp_logic* logic);
llarp_logic_tick(struct llarp_logic* logic, llarp_time_t now);
/// isolated tick
void
llarp_logic_tick_async(struct llarp_logic* logic);
llarp_logic_tick_async(struct llarp_logic* logic, llarp_time_t now);
void
llarp_free_logic(struct llarp_logic** logic);

@ -271,7 +271,7 @@ namespace llarp
}
void
EnterState(PathStatus st);
EnterState(PathStatus st, llarp_time_t now);
llarp_time_t
ExpireTime() const
@ -374,16 +374,16 @@ namespace llarp
/// called from router tick function
void
ExpirePaths();
ExpirePaths(llarp_time_t now);
/// called from router tick function
/// builds all paths we need to build at current tick
void
BuildPaths();
BuildPaths(llarp_time_t now);
/// called from router tick function
void
TickPaths();
TickPaths(llarp_time_t now);
/// track a path builder with this context
void

@ -29,7 +29,10 @@ namespace llarp
size_t hop);
virtual bool
ShouldBuildMore() const;
ShouldBuildMore(llarp_time_t now) const;
llarp_time_t
Now() const;
void
BuildOne();

@ -66,9 +66,13 @@ namespace llarp
size_t
NumInStatus(PathStatus st) const;
/// get time from event loop
virtual llarp_time_t
Now() const = 0;
/// return true if we should build another path
virtual bool
ShouldBuildMore() const;
ShouldBuildMore(llarp_time_t now) const;
/// return true if we should publish a new hidden service descriptor
virtual bool

@ -17,7 +17,7 @@ namespace llarp
~PoW();
bool
IsValid(llarp_shorthash_func hashfunc) const;
IsValid(llarp_shorthash_func hashfunc, llarp_time_t now) const;
bool
DecodeKey(llarp_buffer_t k, llarp_buffer_t* val);

@ -46,7 +46,7 @@ namespace llarp
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf);
bool
SignIntroSet(IntroSet& i, llarp_crypto* c) const;
SignIntroSet(IntroSet& i, llarp_crypto* c, llarp_time_t now) const;
bool
Sign(llarp_crypto*, byte_t* sig, llarp_buffer_t buf) const;

@ -148,7 +148,7 @@ namespace llarp
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf);
bool
Verify(llarp_crypto* crypto) const;
Verify(llarp_crypto* crypto, llarp_time_t now) const;
};
} // namespace service
} // namespace llarp

@ -6,6 +6,7 @@
#include <llarp/service/handler.hpp>
#include <llarp/service/protocol.hpp>
#include <llarp/path.hpp>
#include <llarp/ev.h>
// minimum time between interoset shifts
#ifndef MIN_SHIFT_INTERVAL
@ -263,7 +264,7 @@ namespace llarp
ReadyToSend() const;
bool
ShouldBuildMore() const;
ShouldBuildMore(llarp_time_t now) const;
/// tick internal state
/// return true to mark as dead
@ -455,7 +456,7 @@ namespace llarp
{
RouterLookupJob(Endpoint* p)
{
started = llarp_time_now_ms();
started = p->Now();
txid = p->GenTXID();
}
@ -511,8 +512,9 @@ namespace llarp
llarp_time_t lastModified = 0;
std::set< IntroSet > result;
Tag tag;
Endpoint* parent;
CachedTagResult(const Tag& t) : tag(t)
CachedTagResult(const Tag& t, Endpoint* p) : tag(t), parent(p)
{
}

@ -32,7 +32,7 @@ namespace llarp
/// determine if this request has timed out
bool
IsTimedOut(llarp_time_t now, llarp_time_t timeout = 10000) const
IsTimedOut(llarp_time_t now, llarp_time_t timeout = 20000) const
{
if(now <= m_created)
return false;

@ -2,6 +2,7 @@
#define LLARP_TIMER_H
#include <llarp/common.h>
#include <llarp/threadpool.h>
#include <llarp/time.h>
/** called with userptr, original timeout, left */
typedef void (*llarp_timer_handler_func)(void *, uint64_t, uint64_t);
@ -32,6 +33,11 @@ llarp_timer_remove_job(struct llarp_timer_context *t, uint32_t id);
void
llarp_timer_stop(struct llarp_timer_context *t);
/// set timer's timestamp, if now is 0 use the current time from system clock,
/// llarp_time_t now
void
llarp_timer_set_time(struct llarp_timer_context *t, llarp_time_t now);
// blocking run timer and send events to thread pool
void
llarp_timer_run(struct llarp_timer_context *t, struct llarp_threadpool *pool);
@ -43,7 +49,7 @@ llarp_timer_tick_all(struct llarp_timer_context *t);
/// tick all timers into a threadpool asynchronously
void
llarp_timer_tick_all_async(struct llarp_timer_context *t,
struct llarp_threadpool *pool);
struct llarp_threadpool *pool, llarp_time_t now);
void
llarp_free_timer(struct llarp_timer_context **t);

@ -230,7 +230,7 @@ extern "C"
tuntap_sys_set_ipv4_tap(struct device *, t_tun_in_addr *, uint32_t);
int
tuntap_sys_set_ipv4_tun(struct device *dev, t_tun_in_addr *s4,
t_tun_in_addr *s4dest, uint32_t bits);
t_tun_in_addr *s4dest, uint32_t bits, int netmask);
#endif
int

@ -49,6 +49,12 @@ namespace abyss
void
RemoveConn(IRPCHandler* handler);
llarp_time_t
now() const
{
return llarp_ev_loop_time_now_ms(m_loop);
}
protected:
virtual IRPCHandler*
CreateHandler(ConnImpl* connimpl) const = 0;

@ -48,7 +48,7 @@ namespace abyss
: _conn(c), _parent(p)
{
handler = nullptr;
m_LastActive = llarp_time_now_ms();
m_LastActive = p->now();
m_ReadTimeout = readtimeout;
// set up tcp members
_conn->user = this;
@ -265,7 +265,7 @@ namespace abyss
return false;
}
m_LastActive = llarp_time_now_ms();
m_LastActive = _parent->now();
if(m_State < eReadHTTPBody)
{
const char* end = strstr(buf, "\r\n");
@ -395,11 +395,11 @@ namespace abyss
void
BaseReqHandler::Tick()
{
auto now = llarp_time_now_ms();
auto itr = m_Conns.begin();
auto _now = now();
auto itr = m_Conns.begin();
while(itr != m_Conns.end())
{
if((*itr)->ShouldClose(now))
if((*itr)->ShouldClose(_now)
itr = m_Conns.erase(itr);
else
++itr;

@ -115,7 +115,7 @@ namespace llarp
if(ctx->services)
{
// expire intro sets
auto now = llarp_time_now_ms();
auto now = ctx->Now();
auto &nodes = ctx->services->nodes;
auto itr = nodes.begin();
while(itr != nodes.end())
@ -244,7 +244,7 @@ namespace llarp
void
Context::CleanupTX()
{
auto now = llarp_time_now_ms();
auto now = Now();
llarp::LogDebug("DHT tick");
pendingRouterLookups.Expire(now);
@ -285,7 +285,7 @@ namespace llarp
router->SendToOrQueue(peer, &m);
if(keepalive)
{
auto now = llarp_time_now_ms();
auto now = Now();
router->PersistSessionUntil(peer, now + 10000);
}
}
@ -323,7 +323,7 @@ namespace llarp
bool
Validate(const service::IntroSet &value) const
{
if(!value.Verify(parent->Crypto()))
if(!value.Verify(parent->Crypto(), parent->Now()))
{
llarp::LogWarn("Got invalid introset from service lookup");
return false;
@ -547,7 +547,7 @@ namespace llarp
bool
Validate(const service::IntroSet &introset) const
{
if(!introset.Verify(parent->Crypto()))
if(!introset.Verify(parent->Crypto(), parent->Now()))
{
llarp::LogWarn("got invalid introset from tag lookup");
return false;
@ -824,5 +824,11 @@ namespace llarp
return &router->crypto;
}
llarp_time_t
Context::Now()
{
return llarp_ev_loop_time_now_ms(router->netloop);
}
} // namespace dht
} // namespace llarp

@ -28,7 +28,7 @@ namespace llarp
for(const auto &introset : I)
{
if(!introset.Verify(crypto))
if(!introset.Verify(crypto, dht.Now()))
{
llarp::LogWarn(
"Invalid introset while handling direct GotIntro "

@ -44,20 +44,21 @@ namespace llarp
llarp_dht_context *ctx,
std::vector< std::unique_ptr< IMessage > > &replies) const
{
auto now = ctx->impl.Now();
if(S > 5)
{
llarp::LogWarn("invalid S value ", S, " > 5");
return false;
}
auto &dht = ctx->impl;
if(!I.Verify(&dht.router->crypto))
if(!I.Verify(&dht.router->crypto, now))
{
llarp::LogWarn("invalid introset: ", I);
// don't propogate or store
replies.emplace_back(new GotIntroMessage({}, txID));
return true;
}
if(I.W && !I.W->IsValid(dht.router->crypto.shorthash))
if(I.W && !I.W->IsValid(dht.router->crypto.shorthash, now))
{
llarp::LogWarn("proof of work not good enough for IntroSet");
// don't propogate or store
@ -71,7 +72,7 @@ namespace llarp
"failed to calculate hidden service address for PubIntro message");
return false;
}
auto now = llarp_time_now_ms();
now += llarp::service::MAX_INTROSET_TIME_DELTA;
if(I.IsExpired(now))
{

@ -30,6 +30,7 @@ llarp_ev_loop_alloc(struct llarp_ev_loop **ev)
*ev = new llarp_win32_loop;
#endif
(*ev)->init();
(*ev)->_now = llarp_time_now_ms();
}
void
@ -44,9 +45,10 @@ llarp_ev_loop_run(struct llarp_ev_loop *ev, struct llarp_logic *logic)
{
while(ev->running())
{
ev->_now = llarp_time_now_ms();
ev->tick(EV_TICK_INTERVAL);
if(ev->running())
llarp_logic_tick(logic);
llarp_logic_tick(logic, ev->_now);
}
return 0;
}
@ -58,10 +60,11 @@ llarp_ev_loop_run_single_process(struct llarp_ev_loop *ev,
{
while(ev->running())
{
ev->_now = llarp_time_now_ms();
ev->tick(EV_TICK_INTERVAL);
if(ev->running())
{
llarp_logic_tick_async(logic);
llarp_logic_tick_async(logic, ev->_now);
llarp_threadpool_tick(tp);
}
}
@ -85,6 +88,12 @@ llarp_ev_close_udp(struct llarp_udp_io *udp)
return -1;
}
llarp_time_t
llarp_ev_loop_time_now_ms(struct llarp_ev_loop *loop)
{
return loop->_now;
}
void
llarp_ev_loop_stop(struct llarp_ev_loop *loop)
{
@ -120,8 +129,8 @@ bool
llarp_tcp_conn_async_write(struct llarp_tcp_conn *conn, const void *pkt,
size_t sz)
{
const byte_t *ptr = (const byte_t *)pkt;
llarp::tcp_conn *impl = static_cast< llarp::tcp_conn * >(conn->impl);
const byte_t *ptr = (const byte_t *)pkt;
llarp::tcp_conn *impl = static_cast< llarp::tcp_conn * >(conn->impl);
if(impl->_shouldClose)
return false;
while(sz > EV_WRITE_BUF_SZ)
@ -227,9 +236,8 @@ namespace llarp
} // namespace llarp
llarp::ev_io*
llarp_ev_loop::bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* bindaddr)
llarp::ev_io *
llarp_ev_loop::bind_tcp(llarp_tcp_acceptor *tcp, const sockaddr *bindaddr)
{
int fd = ::socket(bindaddr->sa_family, SOCK_STREAM, 0);
if(fd == -1)
@ -237,7 +245,7 @@ llarp_ev_loop::bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* bindaddr)
socklen_t sz = sizeof(sockaddr_in);
if(bindaddr->sa_family == AF_INET6)
{
sz = sizeof(sockaddr_in6);
sz = sizeof(sockaddr_in6);
}
else if(bindaddr->sa_family == AF_UNIX)
{
@ -253,7 +261,7 @@ llarp_ev_loop::bind_tcp(llarp_tcp_acceptor* tcp, const sockaddr* bindaddr)
::close(fd);
return nullptr;
}
llarp::ev_io* serv = new llarp::tcp_serv(this, fd, tcp);
llarp::ev_io *serv = new llarp::tcp_serv(this, fd, tcp);
tcp->impl = serv;
return serv;
}

@ -29,11 +29,10 @@
namespace llarp
{
struct ev_io
{
{
struct WriteBuffer
{
llarp_time_t timestamp = 0;
llarp_time_t timestamp = 0;
size_t bufsz;
byte_t buf[EV_WRITE_BUF_SZ];
@ -52,19 +51,19 @@ namespace llarp
struct GetTime
{
llarp_time_t
operator()(const WriteBuffer& w) const
llarp_time_t operator()(const WriteBuffer & buf) const
{
return w.timestamp;
return buf.timestamp;
}
};
struct PutTime
{
void
operator()(WriteBuffer& w) const
llarp_ev_loop * loop;
PutTime(llarp_ev_loop * l ) : loop(l) {}
void operator()(WriteBuffer & buf)
{
w.timestamp = llarp_time_now_ms();
buf.timestamp = llarp_ev_loop_time_now_ms(loop);
}
};
@ -239,11 +238,11 @@ namespace llarp
{
if(_shouldClose)
return -1;
#ifdef __linux__
#ifdef __linux__
return ::send(fd, buf, sz, MSG_NOSIGNAL); // ignore sigpipe
#else
return ::send(fd, buf, sz, 0 );
#endif
#else
return ::send(fd, buf, sz, 0);
#endif
}
int
@ -303,7 +302,7 @@ namespace llarp
struct llarp_ev_loop
{
byte_t readbuf[EV_READ_BUF_SZ];
llarp_time_t _now = 0;
virtual bool
init() = 0;
virtual int

@ -79,8 +79,8 @@ namespace llarp
{
llarp_tun_io* t;
device* tunif;
tun(llarp_tun_io* tio)
: ev_io(-1, new LossyWriteQueue_t("tun_write_queue"))
tun(llarp_tun_io* tio, llarp_ev_loop* l)
: ev_io(-1, new LossyWriteQueue_t("tun_write_queue", l))
, t(tio)
, tunif(tuntap_init())
@ -309,7 +309,7 @@ struct llarp_epoll_loop : public llarp_ev_loop
llarp::ev_io*
create_tun(llarp_tun_io* tun)
{
llarp::tun* t = new llarp::tun(tun);
llarp::tun* t = new llarp::tun(tun, this);
if(t->setup())
{
return t;

@ -97,12 +97,10 @@ namespace llarp
{
llarp_tun_io* t;
device* tunif;
tun(llarp_tun_io* tio)
: ev_io(-1, new LossyWriteQueue_t("kqueue_tun_write"))
, t(tio)
, tunif(tuntap_init())
{
};
tun(llarp_tun_io* tio, llarp_ev_loop* l)
: ev_io(-1, new LossyWriteQueue_t("kqueue_tun_write", l))
, t(tio)
, tunif(tuntap_init()){};
int
sendto(const sockaddr* to, const void* data, size_t sz)
@ -110,6 +108,7 @@ namespace llarp
return -1;
}
#ifdef __APPLE__
virtual ssize_t
do_write(void* buf, size_t sz)
{
@ -122,6 +121,7 @@ namespace llarp
vecs[1].iov_len = sz;
return writev(fd, vecs, 2);
}
#endif
void
flush_write()
@ -145,9 +145,14 @@ namespace llarp
int
read(void* buf, size_t sz)
{
#ifdef __APPLE__
const size_t offset = 4;
#else
const size_t offset = 0;
#endif
ssize_t ret = tuntap_read(tunif, buf, sz);
if(ret > 4 && t->recvpkt)
t->recvpkt(t, ((byte_t*)buf) + 4, ret - 4);
t->recvpkt(t, ((byte_t*)buf) + offset, ret - offset);
return ret;
}
@ -189,7 +194,7 @@ struct llarp_kqueue_loop : public llarp_ev_loop
llarp::ev_io*
create_tun(llarp_tun_io* tun)
{
llarp::tun* t = new llarp::tun(tun);
llarp::tun* t = new llarp::tun(tun, this);
if(t->setup())
return t;
delete t;
@ -219,7 +224,7 @@ struct llarp_kqueue_loop : public llarp_ev_loop
int result;
timespec t;
t.tv_sec = 0;
t.tv_nsec = ms * 1000UL;
t.tv_nsec = ms * 1000000UL;
result = kevent(kqueuefd, nullptr, 0, events, 1024, &t);
// result: 0 is a timeout
if(result > 0)

@ -19,8 +19,8 @@ namespace llarp
{
TunEndpoint::TunEndpoint(const std::string &nickname, llarp_router *r)
: service::Endpoint(nickname, r)
, m_UserToNetworkPktQueue(nickname + "_sendq")
, m_NetworkToUserPktQueue(nickname + "_recvq")
, m_UserToNetworkPktQueue(nickname + "_sendq", r->netloop)
, m_NetworkToUserPktQueue(nickname + "_recvq", r->netloop)
{
tunif.user = this;
tunif.netmask = DefaultTunNetmask;
@ -369,7 +369,7 @@ namespace llarp
huint32_t
TunEndpoint::ObtainIPForAddr(const service::Address &addr)
{
llarp_time_t now = llarp_time_now_ms();
llarp_time_t now = Now();
huint32_t nextIP = {0};
{
@ -440,7 +440,7 @@ namespace llarp
void
TunEndpoint::MarkIPActive(huint32_t ip)
{
m_IPActivity[ip] = std::max(llarp_time_now_ms(), m_IPActivity[ip]);
m_IPActivity[ip] = std::max(Now(), m_IPActivity[ip]);
}
void
@ -452,9 +452,8 @@ namespace llarp
void
TunEndpoint::handleTickTun(void *u)
{
auto now = llarp_time_now_ms();
TunEndpoint *self = static_cast< TunEndpoint * >(u);
self->TickTun(now);
self->TickTun(self->Now());
}
void

@ -30,6 +30,7 @@ namespace llarp
ILinkLayer::Configure(llarp_ev_loop* loop, const std::string& ifname, int af,
uint16_t port)
{
m_Loop = loop;
m_udp.user = this;
m_udp.recvfrom = &ILinkLayer::udp_recv_from;
m_udp.tick = &ILinkLayer::udp_tick;
@ -47,13 +48,13 @@ namespace llarp
void
ILinkLayer::Pump()
{
auto now = llarp_time_now_ms();
auto _now = now();
{
Lock lock(m_AuthedLinksMutex);
auto itr = m_AuthedLinks.begin();
while(itr != m_AuthedLinks.end())
{
if(!itr->second->TimedOut(now))
if(!itr->second->TimedOut(_now))
{
itr->second->Pump();
++itr;
@ -68,7 +69,7 @@ namespace llarp
auto itr = m_Pending.begin();
while(itr != m_Pending.end())
{
if(!(*itr)->TimedOut(now))
if(!(*itr)->TimedOut(_now))
{
(*itr)->Pump();
++itr;
@ -261,9 +262,9 @@ namespace llarp
}
void
ILinkLayer::OnTick(uint64_t interval, llarp_time_t now)
ILinkLayer::OnTick(uint64_t interval)
{
Tick(now);
Tick(now());
ScheduleTick(interval);
}

@ -180,23 +180,7 @@ namespace llarp
EncryptThenHash(const byte_t* ptr, uint32_t sz, bool isLastFragment);
bool
QueueWriteBuffers(llarp_buffer_t buf)
{
if(sendq.size() >= MaxSendQueueSize)
return false;
llarp::LogDebug("write ", buf.sz, " bytes to ", remoteAddr);
lastActive = llarp_time_now_ms();
size_t sz = buf.sz;
byte_t* ptr = buf.base;
while(sz)
{
uint32_t s = std::min(FragmentBodyPayloadSize, sz);
EncryptThenHash(ptr, s, ((sz - s) == 0));
ptr += s;
sz -= s;
}
return true;
}
QueueWriteBuffers(llarp_buffer_t buf);
void
Connect()
@ -578,7 +562,7 @@ namespace llarp
SendQueueBacklog = [&]() -> size_t { return sendq.size(); };
SendKeepAlive = [&]() -> bool {
auto now = llarp_time_now_ms();
auto now = parent->now();
if(sendq.size() == 0 && state == eSessionReady && now > lastActive
&& now - lastActive > (sessionTimeout / 4))
{
@ -600,7 +584,7 @@ namespace llarp
return this->IsTimedOut(now) || this->state == eClose;
};
GetPubKey = std::bind(&BaseSession::RemotePubKey, this);
lastActive = llarp_time_now_ms();
lastActive = parent->now();
// Pump = []() {};
Pump = std::bind(&BaseSession::PumpWrite, this);
Tick = std::bind(&BaseSession::TickImpl, this, std::placeholders::_1);
@ -661,6 +645,25 @@ namespace llarp
return true;
}
bool
BaseSession::QueueWriteBuffers(llarp_buffer_t buf)
{
if(sendq.size() >= MaxSendQueueSize)
return false;
llarp::LogDebug("write ", buf.sz, " bytes to ", remoteAddr);
lastActive = parent->now();
size_t sz = buf.sz;
byte_t* ptr = buf.base;
while(sz)
{
uint32_t s = std::min(FragmentBodyPayloadSize, sz);
EncryptThenHash(ptr, s, ((sz - s) == 0));
ptr += s;
sz -= s;
}
return true;
}
bool
BaseSession::OutboundLIM(const LinkIntroMessage* msg)
{
@ -949,7 +952,7 @@ namespace llarp
void
BaseSession::Alive()
{
lastActive = llarp_time_now_ms();
lastActive = parent->now();
}
} // namespace utp

@ -27,16 +27,17 @@ llarp_init_single_process_logic(struct llarp_threadpool* tp)
}
void
llarp_logic_tick(struct llarp_logic* logic)
llarp_logic_tick(struct llarp_logic* logic, llarp_time_t now)
{
llarp_timer_set_time(logic->timer, now);
llarp_timer_tick_all(logic->timer);
llarp_threadpool_tick(logic->thread);
}
void
llarp_logic_tick_async(struct llarp_logic* logic)
llarp_logic_tick_async(struct llarp_logic* logic, llarp_time_t now)
{
llarp_timer_tick_all_async(logic->timer, logic->thread);
llarp_timer_tick_all_async(logic->timer, logic->thread, now);
llarp_threadpool_tick(logic->thread);
}

@ -234,10 +234,9 @@ namespace llarp
}
void
PathContext::ExpirePaths()
PathContext::ExpirePaths(llarp_time_t now)
{
util::Lock lock(m_TransitPaths.first);
auto now = llarp_time_now_ms();
auto& map = m_TransitPaths.second;
auto itr = map.begin();
while(itr != map.end())
@ -258,11 +257,11 @@ namespace llarp
}
void
PathContext::BuildPaths()
PathContext::BuildPaths(llarp_time_t now)
{
for(auto& builder : m_PathBuilders)
{
if(builder->ShouldBuildMore())
if(builder->ShouldBuildMore(now))
{
builder->BuildOne();
}
@ -270,9 +269,8 @@ namespace llarp
}
void
PathContext::TickPaths()
PathContext::TickPaths(llarp_time_t now)
{
auto now = llarp_time_now_ms();
for(auto& builder : m_PathBuilders)
builder->Tick(now, m_Router);
}
@ -357,7 +355,7 @@ namespace llarp
// initialize parts of the introduction
intro.router = hops[hsz - 1].rc.pubkey;
intro.pathID = hops[hsz - 1].txID;
EnterState(ePathBuilding);
EnterState(ePathBuilding, parent->Now());
}
void
@ -397,7 +395,7 @@ namespace llarp
}
void
Path::EnterState(PathStatus st)
Path::EnterState(PathStatus st, llarp_time_t now)
{
if(st == ePathTimeout)
{
@ -406,7 +404,7 @@ namespace llarp
else if(st == ePathBuilding)
{
llarp::LogInfo("path ", Name(), " is building");
buildStarted = llarp_time_now_ms();
buildStarted = now;
}
_status = st;
}
@ -425,7 +423,7 @@ namespace llarp
if(dlt >= PATH_BUILD_TIMEOUT)
{
r->routerProfiling.MarkPathFail(this);
EnterState(ePathTimeout);
EnterState(ePathTimeout, now);
return;
}
}
@ -452,19 +450,19 @@ namespace llarp
if(m_CheckForDead(this, dlt))
{
r->routerProfiling.MarkPathFail(this);
EnterState(ePathTimeout);
EnterState(ePathTimeout, now);
}
}
else
{
r->routerProfiling.MarkPathFail(this);
EnterState(ePathTimeout);
EnterState(ePathTimeout, now);
}
}
else if(dlt >= 10000 && m_LastRecvMessage == 0)
{
r->routerProfiling.MarkPathFail(this);
EnterState(ePathTimeout);
EnterState(ePathTimeout, now);
}
}
}
@ -581,14 +579,15 @@ namespace llarp
Path::HandlePathConfirmMessage(
const llarp::routing::PathConfirmMessage* msg, llarp_router* r)
{
auto now = r->Now();
if(_status == ePathBuilding)
{
// finish initializing introduction
intro.expiresAt = buildStarted + hops[0].lifetime;
// confirm that we build the path
EnterState(ePathEstablished);
EnterState(ePathEstablished, now);
llarp::LogInfo("path is confirmed tx=", TXID(), " rx=", RXID(),
" took ", llarp_time_now_ms() - buildStarted, " ms");
" took ", now - buildStarted, " ms");
if(m_BuiltHook)
m_BuiltHook(this);
m_BuiltHook = nullptr;
@ -602,7 +601,7 @@ namespace llarp
llarp::routing::PathLatencyMessage latency;
latency.T = llarp_randint();
m_LastLatencyTestID = latency.T;
m_LastLatencyTestTime = llarp_time_now_ms();
m_LastLatencyTestTime = now;
return SendRoutingMessage(&latency, r);
}
llarp::LogWarn("got unwarrented path confirm message on tx=", RXID(),
@ -617,7 +616,7 @@ namespace llarp
{
if(m_DataHandler(this, frame))
{
m_LastRecvMessage = llarp_time_now_ms();
m_LastRecvMessage = m_PathSet->Now();
return true;
}
}
@ -628,7 +627,7 @@ namespace llarp
Path::HandlePathLatencyMessage(
const llarp::routing::PathLatencyMessage* msg, llarp_router* r)
{
auto now = llarp_time_now_ms();
auto now = r->Now();
// TODO: reanimate dead paths if they get this message
if(msg->L == m_LastLatencyTestID && _status == ePathEstablished)
{

@ -191,10 +191,9 @@ namespace llarp
}
bool
Builder::ShouldBuildMore() const
Builder::ShouldBuildMore(llarp_time_t now) const
{
auto now = llarp_time_now_ms();
return llarp::path::PathSet::ShouldBuildMore() && now > lastBuild
return llarp::path::PathSet::ShouldBuildMore(now) && now > lastBuild
&& now - lastBuild > buildIntervalLimit;
}
@ -236,10 +235,16 @@ namespace llarp
return true;
}
llarp_time_t
Builder::Now() const
{
return router->Now();
}
void
Builder::Build(const std::vector< RouterContact >& hops)
{
lastBuild = llarp_time_now_ms();
lastBuild = Now();
// async generate keys
AsyncPathKeyExchangeContext< Builder >* ctx =
new AsyncPathKeyExchangeContext< Builder >(&router->crypto);

@ -12,8 +12,9 @@ namespace llarp
}
bool
PathSet::ShouldBuildMore() const
PathSet::ShouldBuildMore(llarp_time_t now) const
{
(void)now;
return m_Paths.size() < m_NumPaths;
}
@ -160,7 +161,7 @@ namespace llarp
void
PathSet::HandlePathBuilt(Path* path)
{
auto dlt = llarp_time_now_ms() - path->buildStarted;
auto dlt = Now() - path->buildStarted;
llarp::LogInfo("Path build took ", dlt, "ms for tx=", path->TXID(),
" rx=", path->RXID());
}

@ -26,10 +26,8 @@ namespace llarp
}
bool
PoW::IsValid(llarp_shorthash_func hashfunc) const
PoW::IsValid(llarp_shorthash_func hashfunc, llarp_time_t now) const
{
auto now = llarp_time_now_ms();
if(now - timestamp > (uint64_t(extendedLifetime) * 1000))
return false;

@ -179,7 +179,7 @@ namespace llarp
}
~LRCMFrameDecrypt()
{
{
delete decrypter;
}
@ -226,6 +226,7 @@ namespace llarp
static void
HandleDecrypted(llarp_buffer_t* buf, LRCMFrameDecrypt* self)
{
auto now = self->context->Router()->Now();
auto& info = self->hop->info;
if(!buf)
{
@ -265,7 +266,7 @@ namespace llarp
self->context->Crypto()->shorthash(self->hop->nonceXOR,
llarp::Buffer(self->hop->pathKey));
if(self->record.work
&& self->record.work->IsValid(self->context->Crypto()->shorthash))
&& self->record.work->IsValid(self->context->Crypto()->shorthash, now))
{
llarp::LogDebug("LRCM extended lifetime by ",
self->record.work->extendedLifetime, " seconds for ",
@ -280,7 +281,7 @@ namespace llarp
}
// TODO: check if we really want to accept it
self->hop->started = llarp_time_now_ms();
self->hop->started = now;
size_t sz = self->frames[0].size();
// shift

@ -468,8 +468,8 @@ void
llarp_router::Tick()
{
// llarp::LogDebug("tick router");
auto now = llarp_time_now_ms();
paths.ExpirePaths();
auto now = llarp_ev_loop_time_now_ms(netloop);
paths.ExpirePaths(now);
{
auto itr = m_PersistingSessions.begin();
while(itr != m_PersistingSessions.end())
@ -502,14 +502,14 @@ llarp_router::Tick()
auto explore = std::max(NumberOfConnectedRouters(), size_t(1));
dht->impl.Explore(explore);
}
paths.BuildPaths();
paths.BuildPaths(now);
hiddenServiceContext.Tick();
}
if(NumberOfConnectedRouters() < minConnectedRouters)
{
ConnectToRandomRouters(minConnectedRouters);
}
paths.TickPaths();
paths.TickPaths(now);
}
void

@ -242,6 +242,13 @@ struct llarp_router
void
Tick();
/// get time from event loop
llarp_time_t
Now() const
{
return llarp_ev_loop_time_now_ms(netloop);
}
/// schedule ticker to call i ms from now
void
ScheduleTicker(uint64_t i = 1000);

@ -273,13 +273,13 @@ namespace llarp
}
bool
Identity::SignIntroSet(IntroSet& i, llarp_crypto* crypto) const
Identity::SignIntroSet(IntroSet& i, llarp_crypto* crypto, llarp_time_t now) const
{
if(i.I.size() == 0)
return false;
// set timestamp
// TODO: round to nearest 1000 ms
i.T = llarp_time_now_ms();
i.T = now;
// set service info
i.A = pub;
// set public encryption key
@ -297,7 +297,7 @@ namespace llarp
}
bool
IntroSet::Verify(llarp_crypto* crypto) const
IntroSet::Verify(llarp_crypto* crypto, llarp_time_t now) const
{
byte_t tmp[MAX_INTROSET_SIZE];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
@ -312,10 +312,9 @@ namespace llarp
if(!A.Verify(crypto, buf, Z))
return false;
// validate PoW
if(W && !W->IsValid(crypto->shorthash))
if(W && !W->IsValid(crypto->shorthash, now))
return false;
// valid timestamps
auto now = llarp_time_now_ms();
// add max clock skew
now += MAX_INTROSET_TIME_DELTA;
for(const auto& intro : I)

@ -1,6 +1,7 @@
#include <llarp/handlers/tun.hpp>
#include <llarp/service/context.hpp>
#include <llarp/service/endpoint.hpp>
#include "router.hpp"
namespace llarp
{
@ -22,7 +23,7 @@ namespace llarp
void
Context::Tick()
{
auto now = llarp_time_now_ms();
auto now = m_Router->Now();
auto itr = m_Endpoints.begin();
while(itr != m_Endpoints.end())
{

@ -102,7 +102,7 @@ namespace llarp
{
llarp::LogWarn("could not publish descriptors for endpoint ", Name(),
" because we couldn't get enough valid introductions");
if(ShouldBuildMore() || forceRebuild)
if(ShouldBuildMore(now) || forceRebuild)
ManualRebuild(1);
return;
}
@ -117,7 +117,7 @@ namespace llarp
return;
}
m_IntroSet.topic = m_Tag;
if(!m_Identity.SignIntroSet(m_IntroSet, &m_Router->crypto))
if(!m_Identity.SignIntroSet(m_IntroSet, &m_Router->crypto, now))
{
llarp::LogWarn("failed to sign introset for endpoint ", Name());
return;
@ -300,7 +300,7 @@ namespace llarp
std::set< IntroSet > remote;
for(const auto& introset : msg->I)
{
if(!introset.Verify(crypto))
if(!introset.Verify(crypto, Now()))
{
if(m_Identity.pub == introset.A && m_CurrentPublishTX == msg->T)
{
@ -358,7 +358,7 @@ namespace llarp
itr = m_Sessions.insert(std::make_pair(tag, Session{})).first;
}
itr->second.remote = info;
itr->second.lastUsed = llarp_time_now_ms();
itr->second.lastUsed = Now();
}
bool
@ -380,7 +380,7 @@ namespace llarp
itr = m_Sessions.insert(std::make_pair(tag, Session{})).first;
}
itr->second.intro = intro;
itr->second.lastUsed = llarp_time_now_ms();
itr->second.lastUsed = Now();
}
bool
@ -430,7 +430,7 @@ namespace llarp
itr = m_Sessions.insert(std::make_pair(tag, Session{})).first;
}
itr->second.sharedKey = k;
itr->second.lastUsed = llarp_time_now_ms();
itr->second.lastUsed = Now();
}
bool
@ -469,7 +469,7 @@ namespace llarp
Endpoint::CachedTagResult::HandleResponse(
const std::set< IntroSet >& introsets)
{
auto now = llarp_time_now_ms();
auto now = parent->Now();
for(const auto& introset : introsets)
if(result.insert(introset).second)
@ -505,7 +505,7 @@ namespace llarp
{
llarp::routing::DHTMessage* msg = new llarp::routing::DHTMessage();
msg->M.emplace_back(new llarp::dht::FindIntroMessage(tag, txid));
lastRequest = llarp_time_now_ms();
lastRequest = parent->Now();
return msg;
}
@ -563,7 +563,7 @@ namespace llarp
auto job = new PublishIntroSetJob(this, GenTXID(), m_IntroSet);
if(job->SendRequestViaPath(path, r))
{
m_LastPublishAttempt = llarp_time_now_ms();
m_LastPublishAttempt = Now();
return true;
}
return false;
@ -582,7 +582,7 @@ namespace llarp
void
Endpoint::IntroSetPublished()
{
m_LastPublish = llarp_time_now_ms();
m_LastPublish = Now();
llarp::LogInfo(Name(), " IntroSet publish confirmed");
}
@ -761,7 +761,7 @@ namespace llarp
{
llarp::LogWarn(Name(), " message ", seq, " dropped by endpoint ",
p->Endpoint(), " via ", dst);
if(MarkCurrentIntroBad(llarp_time_now_ms()))
if(MarkCurrentIntroBad(Now()))
{
llarp::LogInfo(Name(), " switched intros to ", remoteIntro.router,
" via ", remoteIntro.pathID);
@ -797,7 +797,7 @@ namespace llarp
, m_DataHandler(ep)
, m_Endpoint(ep)
{
createdAt = llarp_time_now_ms();
createdAt = ep->Now();
}
void
@ -822,7 +822,7 @@ namespace llarp
Endpoint::HandlePathDead(void* user)
{
Endpoint* self = static_cast< Endpoint* >(user);
self->RegenAndPublishIntroSet(llarp_time_now_ms(), true);
self->RegenAndPublishIntroSet(self->Now(), true);
}
bool
@ -845,7 +845,7 @@ namespace llarp
Endpoint::OnLookup(const Address& addr, const IntroSet* introset,
const RouterID& endpoint)
{
auto now = llarp_time_now_ms();
auto now = Now();
if(introset == nullptr || introset->IsExpired(now))
{
llarp::LogError(Name(), " failed to lookup ", addr.ToString(), " from ",
@ -958,7 +958,7 @@ namespace llarp
{
remoteIntro = m_NextIntro;
// prepare next intro
auto now = llarp_time_now_ms();
auto now = Now();
for(const auto& intro : currentIntroSet.I)
{
if(intro.ExpiresSoon(now))
@ -996,7 +996,7 @@ namespace llarp
llarp::LogInfo("introset is old, dropping");
return true;
}
auto now = llarp_time_now_ms();
auto now = Now();
if(i->IsExpired(now))
{
llarp::LogError("got expired introset from lookup from ", endpoint);
@ -1028,11 +1028,11 @@ namespace llarp
ProtocolType t)
{
// inbound converstation
auto now = Now();
{
auto itr = m_AddressToService.find(remote);
if(itr != m_AddressToService.end())
{
auto now = llarp_time_now_ms();
routing::PathTransferMessage transfer;
ProtocolFrame& f = transfer.T;
path::Path* p = nullptr;
@ -1211,7 +1211,7 @@ namespace llarp
Endpoint::OutboundContext::ShiftIntroduction()
{
bool success = false;
auto now = llarp_time_now_ms();
auto now = Now();
if(now - lastShift < MIN_SHIFT_INTERVAL)
return false;
bool shifted = false;
@ -1255,7 +1255,7 @@ namespace llarp
Endpoint::SendContext::AsyncEncryptAndSendTo(llarp_buffer_t data,
ProtocolType protocol)
{
auto now = llarp_time_now_ms();
auto now = m_Endpoint->Now();
if(remoteIntro.ExpiresSoon(now))
{
if(!MarkCurrentIntroBad(now))
@ -1409,7 +1409,7 @@ namespace llarp
{
llarp::LogDebug("sent data to ", remoteIntro.pathID, " on ",
remoteIntro.router);
lastGoodSend = llarp_time_now_ms();
lastGoodSend = m_Endpoint->Now();
}
else
llarp::LogError("Failed to send frame on path");
@ -1532,17 +1532,15 @@ namespace llarp
}
bool
Endpoint::OutboundContext::ShouldBuildMore() const
Endpoint::OutboundContext::ShouldBuildMore(llarp_time_t now) const
{
if(markedBad)
return false;
bool should = path::Builder::ShouldBuildMore();
bool should = path::Builder::ShouldBuildMore(now);
// determinte newest intro
Introduction intro;
if(!GetNewestIntro(intro))
return should;
auto now = llarp_time_now_ms();
// time from now that the newest intro expires at
if(now >= intro.expiresAt)
return should;
@ -1567,7 +1565,7 @@ namespace llarp
f.T = currentConvoTag;
f.S = m_Endpoint->GetSeqNoForConvo(f.T);
auto now = llarp_time_now_ms();
auto now = m_Endpoint->Now();
if(remoteIntro.ExpiresSoon(now))
{
// shift intro

@ -20,11 +20,11 @@ namespace llarp
bool done;
bool canceled;
timer(uint64_t ms = 0, void* _user = nullptr,
timer(llarp_time_t now, uint64_t ms = 0, void* _user = nullptr,
llarp_timer_handler_func _func = nullptr)
: user(_user)
, called_at(0)
, started(llarp_time_now_ms())
, started(now)
, timeout(ms)
, func(_func)
, done(false)
@ -62,6 +62,13 @@ struct llarp_timer_context
llarp::util::Condition* ticker = nullptr;
std::chrono::milliseconds nextTickLen = std::chrono::milliseconds(100);
llarp_time_t m_Now;
llarp_timer_context()
{
m_Now = llarp_time_now_ms();
}
uint32_t ids = 0;
bool _run = true;
@ -108,11 +115,12 @@ struct llarp_timer_context
call_later(void* user, llarp_timer_handler_func func, uint64_t timeout_ms)
{
llarp::util::Lock lock(timersMutex);
uint32_t id = ++ids;
timers.insert(
std::make_pair(id,
std::unique_ptr< llarp::timer >(
new llarp::timer(timeout_ms, user, func))));
new llarp::timer(m_Now, timeout_ms, user, func))));
return id;
}
@ -181,19 +189,27 @@ llarp_timer_cancel_job(struct llarp_timer_context* t, uint32_t id)
t->cancel(id);
}
void
llarp_timer_set_time(struct llarp_timer_context* t, llarp_time_t now)
{
if(now == 0)
now = llarp_time_now_ms();
t->m_Now = now;
}
void
llarp_timer_tick_all(struct llarp_timer_context* t)
{
if(!t->run())
return;
auto now = llarp_time_now_ms();
std::list< std::unique_ptr< llarp::timer > > hit;
{
llarp::util::Lock lock(t->timersMutex);
auto itr = t->timers.begin();
while(itr != t->timers.end())
{
if(now - itr->second->started >= itr->second->timeout
if(t->m_Now - itr->second->started >= itr->second->timeout
|| itr->second->canceled)
{
// timer hit
@ -208,7 +224,7 @@ llarp_timer_tick_all(struct llarp_timer_context* t)
{
if(h->func)
{
h->called_at = now;
h->called_at = t->m_Now;
h->exec();
}
}
@ -222,8 +238,9 @@ llarp_timer_tick_all_job(void* user)
void
llarp_timer_tick_all_async(struct llarp_timer_context* t,
struct llarp_threadpool* pool)
struct llarp_threadpool* pool, llarp_time_t now)
{
t->m_Now = now;
llarp_threadpool_queue_job(pool, {t, llarp_timer_tick_all_job});
}
@ -244,7 +261,7 @@ llarp_timer_run(struct llarp_timer_context* t, struct llarp_threadpool* pool)
{
llarp::util::Lock lock(t->timersMutex);
// we woke up
llarp_timer_tick_all_async(t, pool);
llarp_timer_tick_all_async(t, pool, llarp_time_now_ms());
}
}
}

@ -1,8 +1,8 @@
#!/bin/bash
#!/usr/bin/env sh
#
# this shell script will be replaced by a proper program in the future (probably)
#
if [ "X$1" = "X" ] ; then url="https://i2p.rocks/i2procks.signed" ; else url="$1" ; fi
echo "downloading $url"
wget -O $HOME/.lokinet/bootstrap.signed "$url" &> /dev/null || echo "failed to download bootstrap from $url"
wget -O $HOME/.lokinet/bootstrap.signed "$url" || echo "failed to download bootstrap from $url"

@ -17,14 +17,34 @@ Build requirements:
* C++ 17 capable C++ compiler
* rapidjson (if enabling jsonrpc server)
To build:
### Linux
build:
$ sudo apt install build-essential cmake git libcap-dev wget rapidjson-dev
$ git clone https://github.com/loki-project/loki-network
$ cd loki-network
$ make -j8 JSONRPC=ON
$ make -j8
install:
$ sudo make install
### FreeBSD
build:
$ pkg install wget cmake git
$ git clone https://github.com/loki-project/loki-network
$ cd loki-network
$ gmake -j8
install (root):
# gmake install
## Running
**DO NOT RUN AS ROOT**, run as normal user.
@ -37,9 +57,9 @@ to run as client:
to run as relay:
$ lokinet -r -g
$ lokinet-bootstrap
$ lokinet
$ lokinet -r -g
$ lokinet-bootstrap
$ lokinet
## Usage

@ -32,7 +32,7 @@ TEST_F(HiddenServiceTest, TestGenerateIntroSet)
ASSERT_TRUE(ident.pub.CalculateAddress(addr.data()));
llarp::service::IntroSet I;
auto now = llarp_time_now_ms();
I.T = now;
I.T = now;
while(I.I.size() < 10)
{
llarp::service::Introduction intro;
@ -41,8 +41,8 @@ TEST_F(HiddenServiceTest, TestGenerateIntroSet)
intro.pathID.Randomize();
I.I.push_back(intro);
}
ASSERT_TRUE(ident.SignIntroSet(I, Crypto()));
ASSERT_TRUE(I.Verify(Crypto()));
ASSERT_TRUE(ident.SignIntroSet(I, Crypto(), now));
ASSERT_TRUE(I.Verify(Crypto(), now));
};
TEST_F(HiddenServiceTest, TestAddressToFromString)

@ -186,9 +186,36 @@ tuntap_sys_set_ipv4_tap(struct device *dev, t_tun_in_addr *s4, uint32_t bits)
return 0;
}
static int
tuntap_sys_add_route(struct device *dev, t_tun_in_addr *s4, uint32_t bits,
int netmask)
{
struct sockaddr_in mask;
mask.sin_family = AF_INET;
mask.sin_addr.s_addr = bits;
mask.sin_len = sizeof(struct sockaddr_in);
char addrbuf[32] = {0};
char buf[1028] = {0};
inet_ntop(AF_INET, s4, addrbuf, sizeof(struct sockaddr_in));
const char *addr = addrbuf;
const char *netmask_str = inet_ntoa(mask.sin_addr);
/** because fuck this other stuff */
snprintf(buf, sizeof(buf), "ifconfig %s %s %s mtu 1380 netmask %s up",
dev->if_name, addr, addr, netmask_str);
tuntap_log(TUNTAP_LOG_INFO, buf);
system(buf);
snprintf(buf, sizeof(buf), "route add %s/%d -interface %s", addr, netmask,
dev->if_name);
tuntap_log(TUNTAP_LOG_INFO, buf);
system(buf);
return 0;
}
int
tuntap_sys_set_ipv4_tun(struct device *dev, t_tun_in_addr *s4,
t_tun_in_addr *s4dest, uint32_t bits)
t_tun_in_addr *s4dest, uint32_t bits, int netmask)
{
struct ifaliasreq ifrq;
struct sockaddr_in mask;
@ -226,7 +253,7 @@ tuntap_sys_set_ipv4_tun(struct device *dev, t_tun_in_addr *s4,
tuntap_log(TUNTAP_LOG_ERR, "Can't set IP address");
return -1;
}
return 0;
return tuntap_sys_add_route(dev, s4, bits, netmask);
}
int
@ -261,7 +288,7 @@ tuntap_sys_set_ifname(struct device *dev, const char *ifname, size_t len)
{
struct ifreq ifr;
char *newname;
//(void)strncpy(ifr.ifr_name, dev->if_name, IF_NAMESIZE);
//(void)strncpy(ifr.ifr_name, dev->if_name, IF_NAMESIZE);
strlcpy(ifr.ifr_name, dev->if_name, IF_NAMESIZE);
newname = strdup(ifname);
@ -271,9 +298,9 @@ tuntap_sys_set_ifname(struct device *dev, const char *ifname, size_t len)
return -1;
}
ifr.ifr_data = newname;
if (ioctl(dev->ctrl_sock, SIOCSIFNAME, &ifr) == -1)
{
perror(NULL);
if(ioctl(dev->ctrl_sock, SIOCSIFNAME, &ifr) == -1)
{
perror(NULL);
free(newname);
tuntap_log(TUNTAP_LOG_ERR, "Can't set interface name");
return -1;

@ -34,7 +34,7 @@
#ifndef _MSC_VER
extern "C" int
inet_pton(int af, const char *src, void *dst);
extern "C" const char *
extern "C" const char *
inet_ntop(int af, const void *src, char *dst, size_t size);
#endif
#else
@ -68,9 +68,9 @@ extern "C"
dev->tun_fd = TUNFD_INVALID_VALUE;
dev->ctrl_sock = -1;
dev->flags = 0;
#if defined(Windows)
memset(&dev->ovl[0], 0, sizeof(OVERLAPPED)*2);
#endif
#if defined(Windows)
memset(&dev->ovl[0], 0, sizeof(OVERLAPPED) * 2);
#endif
__tuntap_log = &tuntap_log_default;
return dev;
@ -143,7 +143,7 @@ extern "C"
errval = inet_pton(AF_INET, daddr, &(daddr4));
if(errval == 1)
{
return tuntap_sys_set_ipv4_tun(dev, &baddr4, &daddr4, mask);
return tuntap_sys_set_ipv4_tun(dev, &baddr4, &daddr4, mask, netmask);
}
else
{

Loading…
Cancel
Save