This commit is contained in:
Ryan Tharp 2018-09-20 12:45:19 +00:00
commit 29a304f928
27 changed files with 238 additions and 201 deletions

View File

@ -11,7 +11,7 @@ build:linux:
- linux
stage: build
before_script:
- apk add --update g++ make cmake linux-headers libsodium-dev ninja
- apk add --update g++ make cmake linux-headers libsodium-dev ninja libcap-dev
script:
- make
artifacts:

View File

@ -13,7 +13,7 @@ endmacro(add_cxxflags)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
if (WIN32 AND NOT MINGW)
if (MSVC)
CHECK_CXX_COMPILER_FLAG("/std:c++17" COMPILER_SUPPORTS_CXX17)
else()
CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX17)
@ -24,7 +24,7 @@ option(HAVE_CXX17_FILESYSTEM "Disable if your C++ compiler and runtime library l
if(COMPILER_SUPPORTS_CXX11 AND NOT HAVE_CXX17_FILESYSTEM)
add_cxxflags("-std=c++11")
elseif(COMPILER_SUPPORTS_CXX17 AND HAVE_CXX17_FILESYSTEM)
if (WIN32 AND NOT MINGW)
if (MSVC)
add_cxxflags("/std:c++17")
else()
add_cxxflags("-std=c++17")
@ -43,12 +43,22 @@ endif()
if(ANDROID)
set(THREAD_LIB "-pthread")
# finally removed pthread dependency for MSC++
elseif(WIN32 AND NOT MINGW)
elseif(MSVC)
set(THREAD_LIB)
else()
set(THREAD_LIB pthread)
endif()
if(MSVC)
option (BUILD_AVX2 "Enable AVX2 FPU vector instructions." OFF)
if (BUILD_AVX2)
add_cflags("/arch:AVX2")
add_cxxflags("/arch:AVX2")
else()
add_cflags("/arch:SSE2")
add_cxxflags("/arch:SSE2")
endif(BUILD_AVX2)
endif()
if(STATIC_LINK)
add_cflags("-static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive")
@ -61,12 +71,12 @@ else()
set(WITH_STATIC ON)
endif()
if (UNIX OR MINGW OR APPLE)
if (NOT MSVC)
add_cflags("-Wall")
add_cxxflags("-Wall")
endif()
if (WIN32 AND NOT MINGW)
if (MSVC)
set(OPTIMIZE_FLAGS "-Od")
set(DEBUG_FLAGS "-ZI")
else()
@ -98,7 +108,7 @@ if(SHADOW)
include_directories(${SHADOW_ROOT}/include)
endif()
if (WIN32 AND NOT MINGW)
if (MSVC)
add_cflags("-wd4996 -wd4244 -MP ${OPTIMIZE_FLAGS}")
add_cxxflags("-wd4996 -wd4244 -MP ${OPTIMIZE_FLAGS}")
else()
@ -182,7 +192,7 @@ if(UNIX)
else()
message(FATAL_ERROR "Your operating system is not supported yet")
endif()
elseif(WIN32 OR MINGW)
elseif(WIN32)
set(LIBTUNTAP_IMPL ${TT_ROOT}/tuntap-windows.c)
add_definitions(-DWIN32_LEAN_AND_MEAN)
add_definitions(-DWIN32)
@ -443,9 +453,8 @@ include_directories(vendor/cppbackport-master/lib)
include_directories(/usr/local/include)
include_directories(${sodium_INCLUDE_DIR})
if (WIN32 AND NOT MINGW)
if (MSVC)
include_directories(contrib/msc/include)
link_directories(contrib/msc/lib)
endif()
set(RC_EXE rcutil)
@ -453,23 +462,27 @@ set(DNS_EXE dns)
if(SHADOW)
add_shadow_plugin(shadow-plugin-${SHARED_LIB} ${EXE_SRC} ${LIB_SRC} ${LIB_PLATFORM_SRC} ${CPP_BACKPORT_SRC})
target_link_libraries(shadow-plugin-${SHARED_LIB} ${LIBS})
install(TARGETS shadow-plugin-${SHARED_LIB} DESTINATION plugins)
add_shadow_plugin(shadow-plugin-${SHARED_LIB} ${EXE_SRC} ${LIB_SRC} ${LIB_PLATFORM_SRC} ${CPP_BACKPORT_SRC})
target_link_libraries(shadow-plugin-${SHARED_LIB} ${LIBS})
install(TARGETS shadow-plugin-${SHARED_LIB} DESTINATION plugins)
else()
add_executable(${RC_EXE} ${RC_SRC})
add_executable(${EXE} ${EXE_SRC})
add_executable(${CLIENT_EXE} ${CLIENT_SRC})
add_executable(${EXE} ${EXE_SRC})
add_executable(${CLIENT_EXE} ${CLIENT_SRC})
add_executable(${DNS_EXE} ${DNS_SRC})
add_subdirectory(${GTEST_DIR})
include_directories(${GTEST_DIR}/include ${GTEST_DIR})
add_executable(${TEST_EXE} ${TEST_SRC})
if (MSVC)
target_link_libraries(${TEST_EXE} ${STATIC_LINK_LIBS} gtest_main ${STATIC_LIB} ws2_32 iphlpapi)
elseif (MINGW)
target_link_libraries(${TEST_EXE} ${STATIC_LINK_LIBS} gtest_main ${STATIC_LIB} stdc++fs iphlpapi ws2_32)
else()
target_link_libraries(${TEST_EXE} ${STATIC_LINK_LIBS} gtest_main ${STATIC_LIB})
endif(MSVC)
if(NOT WIN32)
add_subdirectory(${GTEST_DIR})
include_directories(${GTEST_DIR}/include ${GTEST_DIR})
add_executable(${TEST_EXE} ${TEST_SRC})
target_link_libraries(${TEST_EXE} ${STATIC_LINK_LIBS} gtest_main ${STATIC_LIB})
endif()
if(WITH_STATIC)
if(WITH_STATIC)
add_library(${STATIC_LIB} STATIC ${LIB_SRC})
if(NOT HAVE_CXX17_FILESYSTEM)
add_library(${BACKPORT_LIB} STATIC ${CPP_BACKPORT_SRC})
@ -493,7 +506,7 @@ else()
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} ${BACKPORT_LIB} ${PLATFORM_LIB} ws2_32 stdc++fs iphlpapi)
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} ${BACKPORT_LIB} ${PLATFORM_LIB} ws2_32 stdc++fs iphlpapi)
target_link_libraries(${RC_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} ${BACKPORT_LIB} ${PLATFORM_LIB} ws2_32 stdc++fs iphlpapi)
elseif(WIN32)
elseif(MSVC)
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} ${BACKPORT_LIB} ${PLATFORM_LIB} ws2_32 iphlpapi)
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} ${BACKPORT_LIB} ${PLATFORM_LIB} ws2_32 iphlpapi)
target_link_libraries(${RC_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} ${BACKPORT_LIB} ${PLATFORM_LIB} ws2_32 iphlpapi)
@ -506,7 +519,7 @@ else()
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} ${PLATFORM_LIB} ws2_32 stdc++fs iphlpapi)
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} ${PLATFORM_LIB} ws2_32 stdc++fs iphlpapi)
target_link_libraries(${RC_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} ${PLATFORM_LIB} ws2_32 stdc++fs iphlpapi)
elseif(WIN32)
elseif(MSVC)
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} ${PLATFORM_LIB} ws2_32 iphlpapi)
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} ${PLATFORM_LIB} ws2_32 iphlpapi)
target_link_libraries(${RC_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} ${PLATFORM_LIB} ws2_32 iphlpapi)
@ -532,7 +545,7 @@ else()
add_library(${SHARED_LIB} SHARED ${LIB_SRC} ${LIB_PLATFORM_SRC})
if (MINGW)
set(${LIBS} ${LIBS} ws2_32 stdc++fs iphlpapi)
elseif(WIN32)
elseif(MSVC)
set(${LIBS} ${LIBS} ws2_32 iphlpapi)
endif(MINGW)
target_link_libraries(${SHARED_LIB} ${LIBS} ${THREAD_LIB})

View File

@ -1,4 +1,5 @@
Copyright (c) 2018 Jeff Becker
Win32 port and portions copyright ©2018 Rick V.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -98,9 +98,12 @@ main(int argc, char *argv[])
std::error_code ec;
if(!fs::create_directories(basepath, ec))
{
llarp::LogError("failed to create '", basepath.string(),
"': ", ec.message());
return 1;
if(ec)
{
llarp::LogError("failed to create '", basepath.string(),
"': ", ec.message());
return 1;
}
}
if(!llarp_ensure_config(fpath.string().c_str(), basepath.string().c_str(),

View File

@ -5,6 +5,7 @@
#include <llarp/net.h>
#ifdef __cplusplus
#include <iostream>
#include <string>
#include <llarp/bits.hpp>
#endif
@ -45,7 +46,7 @@ struct llarp_xi
operator<<(std::ostream &out, const llarp_xi &xi)
{
char tmp[128] = {0};
if(inet_ntop(AF_INET6, &xi.address, tmp, sizeof(tmp)))
if(inet_ntop(AF_INET6, (void*)&xi.address, tmp, sizeof(tmp)))
out << std::string(tmp);
else
return out;

View File

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

View File

@ -168,4 +168,4 @@ namespace llarp
} // namespace service
} // namespace llarp
#endif
#endif

View File

@ -42,9 +42,11 @@
// hash.cpp needs socket definitions, which is why this networking specific
// code is inclued in utypes.h
#ifdef WIN32
#if defined WIN32 || defined _WIN32
#define _CRT_SECURE_NO_DEPRECATE
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>

View File

@ -19,90 +19,30 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <wspiapi.h>
#include "libutp_inet_ntop.h"
// we already have our own definition of these
// -despair
extern "C" {
const char* inet_ntop(int af, const void *src, char *dst, size_t size);
int inet_pton(int af, const char *src, void *dst);
}
//######################################################################
const char *libutp::inet_ntop(int af, const void *src, char *dest, size_t length)
{
if (af != AF_INET && af != AF_INET6)
{
return NULL;
}
SOCKADDR_STORAGE address;
DWORD address_length;
if (af == AF_INET)
{
address_length = sizeof(sockaddr_in);
sockaddr_in* ipv4_address = (sockaddr_in*)(&address);
ipv4_address->sin_family = AF_INET;
ipv4_address->sin_port = 0;
memcpy(&ipv4_address->sin_addr, src, sizeof(in_addr));
}
else // AF_INET6
{
address_length = sizeof(sockaddr_in6);
sockaddr_in6* ipv6_address = (sockaddr_in6*)(&address);
ipv6_address->sin6_family = AF_INET6;
ipv6_address->sin6_port = 0;
ipv6_address->sin6_flowinfo = 0;
// hmmm
ipv6_address->sin6_scope_id = 0;
memcpy(&ipv6_address->sin6_addr, src, sizeof(in6_addr));
}
DWORD string_length = (DWORD)(length);
int result;
result = WSAAddressToStringA((sockaddr*)(&address),
address_length, 0, dest,
&string_length);
// one common reason for this to fail is that ipv6 is not installed
return result == SOCKET_ERROR ? NULL : dest;
return inet_ntop(af, src, dest, length);
}
//######################################################################
int libutp::inet_pton(int af, const char* src, void* dest)
{
if (af != AF_INET && af != AF_INET6)
{
return -1;
}
SOCKADDR_STORAGE address;
int address_length = sizeof(SOCKADDR_STORAGE);
int result = WSAStringToAddressA((char*)(src), af, 0,
(sockaddr*)(&address),
&address_length);
if (af == AF_INET)
{
if (result != SOCKET_ERROR)
{
sockaddr_in* ipv4_address =(sockaddr_in*)(&address);
memcpy(dest, &ipv4_address->sin_addr, sizeof(in_addr));
}
else if (strcmp(src, "255.255.255.255") == 0)
{
((in_addr*)(dest))->s_addr = INADDR_NONE;
}
}
else // AF_INET6
{
if (result != SOCKET_ERROR)
{
sockaddr_in6* ipv6_address = (sockaddr_in6*)(&address);
memcpy(dest, &ipv6_address->sin6_addr, sizeof(in6_addr));
}
}
return result == SOCKET_ERROR ? -1 : 1;
return inet_pton(af, src, dest);
}

View File

@ -30,11 +30,6 @@
// ut_utils/src/sockaddr.cpp
// libutp/win32_inet_ntop.obj
//
// When we drop support for XP we can just #include <ws2tcpip.h>, and use the system functions
// For now, we will always use our functions on windows, on all builds
// The reason is: we would like the debug build to behave as much as the release build as possible
// It is much better to catch a problem in the debug build, than to link the system version
// in debug, and our version int he wild.
#if defined(_WIN32_WINNT)
#if _WIN32_WINNT >= 0x600 // Win32, post-XP

View File

@ -26,7 +26,9 @@
#include "utp_types.h"
#ifdef WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>

View File

@ -327,10 +327,9 @@ namespace llarp
bool
Validate(const service::IntroSet &value) const
{
if(!value.VerifySignature(parent->Crypto()))
if(!value.Verify(parent->Crypto()))
{
llarp::LogWarn(
"Got introset with invalid signature from service lookup");
llarp::LogWarn("Got invalid introset from service lookup");
return false;
}
if(value.A.Addr() != target)
@ -552,9 +551,9 @@ namespace llarp
bool
Validate(const service::IntroSet &introset) const
{
if(!introset.VerifySignature(parent->Crypto()))
if(!introset.Verify(parent->Crypto()))
{
llarp::LogWarn("got introset from tag lookup with invalid signature");
llarp::LogWarn("got invalid introset from tag lookup");
return false;
}
if(introset.topic != target)

View File

@ -28,10 +28,10 @@ namespace llarp
for(const auto &introset : I)
{
if(!introset.VerifySignature(crypto))
if(!introset.Verify(crypto))
{
llarp::LogWarn(
"Invalid introset signature while handling direct GotIntro "
"Invalid introset while handling direct GotIntro "
"from ",
From);
return false;

View File

@ -50,9 +50,9 @@ namespace llarp
return false;
}
auto &dht = ctx->impl;
if(!I.VerifySignature(&dht.router->crypto))
if(!I.Verify(&dht.router->crypto))
{
llarp::LogWarn("invalid introset signature, ", I);
llarp::LogWarn("invalid introset: ", I);
return false;
}
if(I.W && !I.W->IsValid(dht.router->crypto.shorthash))
@ -67,6 +67,13 @@ namespace llarp
"failed to calculate hidden service address for PubIntro message");
return false;
}
auto now = llarp_time_now_ms();
if(I.IsExpired(now))
{
// don't propogate or store expired introsets
replies.emplace_back(new GotIntroMessage({}, txID));
return true;
}
dht.services->PutNode(I);
replies.emplace_back(new GotIntroMessage({I}, txID));
Key_t peer;

View File

@ -214,10 +214,8 @@ namespace llarp
return true;
}))
llarp::LogInfo(Name(), " handle data message ", msg->payload.size(),
" bytes from ", inet_ntoa({htonl(themIP)}));
else
llarp::LogWarn(Name(), " dropped packet");
llarp::LogDebug(Name(), " handle data message ", msg->payload.size(),
" bytes from ", inet_ntoa({htonl(themIP)}));
return true;
}
@ -239,41 +237,46 @@ namespace llarp
// 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)}));
MarkIPActive(nextIP);
return nextIP;
}
else
{
// we are full
// expire least active ip
// TODO: prevent DoS
std::pair< uint32_t, llarp_time_t > oldest = {0, 0};
// find oldest entry
auto itr = m_IPActivity.begin();
while(itr != m_IPActivity.end())
do
{
if(itr->second <= now)
{
if((now - itr->second) > oldest.second)
{
oldest.first = itr->first;
oldest.second = itr->second;
}
}
++itr;
nextIP = ++m_NextIP;
} while(m_IPToAddr.find(nextIP) != m_IPToAddr.end()
&& m_NextIP < m_MaxIP);
if(nextIP < m_MaxIP)
{
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)}));
MarkIPActive(nextIP);
return nextIP;
}
// remap address
m_IPToAddr[oldest.first] = addr;
m_AddrToIP[addr] = oldest.first;
nextIP = oldest.first;
}
// we are full
// expire least active ip
// TODO: prevent DoS
std::pair< uint32_t, llarp_time_t > oldest = {0, 0};
// find oldest entry
auto itr = m_IPActivity.begin();
while(itr != m_IPActivity.end())
{
if(itr->second <= now)
{
if((now - itr->second) > oldest.second)
{
oldest.first = itr->first;
oldest.second = itr->second;
}
}
++itr;
}
// remap address
m_IPToAddr[oldest.first] = addr;
m_AddrToIP[addr] = oldest.first;
nextIP = oldest.first;
// mark ip active
m_IPActivity[nextIP] = std::max(m_IPActivity[nextIP], now);

View File

@ -3,6 +3,9 @@
#include <llarp/ip.hpp>
#include "llarp/buffer.hpp"
#include "mem.hpp"
#ifndef _WIN32
#include <netinet/in.h>
#endif
#include <llarp/endian.h>
#include <map>

View File

@ -67,9 +67,9 @@ namespace llarp
const std::array< EncryptedFrame, 8 >& frames)
{
llarp::LogDebug("fowarding LRCM to ", nextHop);
LR_CommitMessage* msg = new LR_CommitMessage();
msg->frames = frames;
return m_Router->SendToOrQueue(nextHop, msg);
LR_CommitMessage msg;
msg.frames = frames;
return m_Router->SendToOrQueue(nextHop, &msg);
}
template < typename Map_t, typename Key_t, typename CheckValue_t,
typename GetFunc_t >

View File

@ -21,7 +21,7 @@ namespace llarp
llarp_threadpool* worker = nullptr;
llarp_logic* logic = nullptr;
llarp_crypto* crypto = nullptr;
LR_CommitMessage* LRCM = nullptr;
LR_CommitMessage LRCM;
static void
HandleDone(void* u)
@ -39,7 +39,7 @@ namespace llarp
// current hop
auto& hop = ctx->path->hops[ctx->idx];
auto& frame = ctx->LRCM->frames[ctx->idx];
auto& frame = ctx->LRCM.frames[ctx->idx];
// generate key
ctx->crypto->encryption_keygen(hop.commkey);
hop.nonce.Randomize();
@ -121,11 +121,10 @@ namespace llarp
user = u;
result = func;
worker = pool;
LRCM = new LR_CommitMessage();
for(size_t idx = 0; idx < MAXHOPS; ++idx)
{
LRCM->frames[idx].Randomize();
LRCM.frames[idx].Randomize();
}
llarp_threadpool_queue_job(pool, {this, &GenerateNextKey});
}
@ -136,7 +135,7 @@ namespace llarp
{
auto remote = ctx->path->Upstream();
auto router = ctx->user->router;
if(!router->SendToOrQueue(remote, ctx->LRCM))
if(!router->SendToOrQueue(remote, &ctx->LRCM))
{
llarp::LogError("failed to send LRCM");
delete ctx;

View File

@ -184,17 +184,17 @@ llarp_router::SendToOrQueue(const llarp::RouterID &remote,
// queue buffer
auto &q = outboundMessageQueue[remote];
if(q.size() >= MaxPendingSendQueueSize)
if(q.size() < MaxPendingSendQueueSize)
{
buf.sz = buf.cur - buf.base;
q.emplace(buf.sz);
memcpy(q.back().data(), buf.base, buf.sz);
}
else
{
llarp::LogWarn("tried to queue a message to ", remote,
" but the queue is full so we drop it like it's hawt");
return false;
}
buf.sz = buf.cur - buf.base;
q.emplace(buf.sz);
memcpy(q.back().data(), buf.base, buf.sz);
llarp::RouterContact remoteRC;
// we don't have an open session to that router right now
if(llarp_nodedb_get_rc(nodedb, remote, remoteRC))

View File

@ -102,10 +102,10 @@ namespace llarp
bool
IntroSet::IsExpired(llarp_time_t now) const
{
auto highest = now;
llarp_time_t highest = 0;
for(const auto& i : I)
highest = std::max(i.expiresAt, highest);
return highest <= now;
return highest < now;
}
Introduction::~Introduction()
@ -290,7 +290,7 @@ namespace llarp
}
bool
IntroSet::VerifySignature(llarp_crypto* crypto) const
IntroSet::Verify(llarp_crypto* crypto) const
{
byte_t tmp[MAX_INTROSET_SIZE];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
@ -302,7 +302,33 @@ namespace llarp
// rewind and resize buffer
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
return A.Verify(crypto, buf, Z);
if(!A.Verify(crypto, buf, Z))
return false;
// validate PoW
if(W && !W->IsValid(crypto->shorthash))
return false;
// valid timestamps
auto now = llarp_time_now_ms();
for(const auto& intro : I)
{
if(intro.expiresAt > now
&& intro.expiresAt - now > DEFAULT_PATH_LIFETIME)
{
if(W && intro.expiresAt - W->extendedLifetime > DEFAULT_PATH_LIFETIME)
return false;
else if(W == nullptr)
{
llarp::LogWarn("intro has too high expire time");
return false;
}
}
}
if(IsExpired(now))
{
llarp::LogWarn("introset expired");
return false;
}
return true;
}
bool

View File

@ -274,10 +274,10 @@ namespace llarp
std::set< IntroSet > remote;
for(const auto& introset : msg->I)
{
if(!introset.VerifySignature(crypto))
if(!introset.Verify(crypto))
{
llarp::LogInfo("invalid introset signature for ", introset,
" on endpoint ", Name());
llarp::LogInfo("invalid introset ", introset, " on endpoint ",
Name());
if(m_Identity.pub == introset.A && m_CurrentPublishTX == msg->T)
{
IntroSetPublishFail();
@ -425,6 +425,7 @@ namespace llarp
Endpoint::~Endpoint()
{
}
bool
Endpoint::CachedTagResult::HandleResponse(
const std::set< IntroSet >& introsets)
@ -710,12 +711,12 @@ namespace llarp
llarp::LogWarn(Name(), " message ", seq, " dropped by endpoint ",
p->Endpoint(), " via ", dst);
// pick another intro
if(dst == remoteIntro.pathID)
if(dst == remoteIntro.pathID && remoteIntro.router == p->Endpoint())
{
MarkCurrentIntroBad();
ShiftIntroduction();
UpdateIntroSet();
}
UpdateIntroSet();
return true;
}
@ -882,6 +883,7 @@ namespace llarp
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;
@ -897,7 +899,8 @@ namespace llarp
{
if(p == nullptr && GetIntroFor(tag, remoteIntro))
{
p = GetPathByRouter(remoteIntro.router);
if(!remoteIntro.ExpiresSoon(now))
p = GetPathByRouter(remoteIntro.router);
if(p)
{
f.T = tag;
@ -927,7 +930,7 @@ namespace llarp
llarp::LogError("failed to encrypt and sign");
return false;
}
llarp::LogInfo(Name(), " send ", data.sz, " via ", remoteIntro);
llarp::LogDebug(Name(), " send ", data.sz, " via ", remoteIntro);
return p->SendRoutingMessage(&transfer, Router());
}
}
@ -971,7 +974,7 @@ namespace llarp
}
m_PendingTraffic[remote].emplace(data, t);
return true;
}
} // namespace service
void
Endpoint::OutboundContext::MarkCurrentIntroBad()
@ -989,6 +992,8 @@ namespace llarp
for(const auto& intro : currentIntroSet.I)
{
m_Endpoint->EnsureRouterIsKnown(intro.router);
if(intro.ExpiresSoon(now))
continue;
if(m_BadIntros.count(intro) == 0 && remoteIntro != intro)
{
shifted = intro.router != remoteIntro.router;
@ -1161,7 +1166,7 @@ namespace llarp
if(updatingIntroSet)
return;
auto addr = currentIntroSet.A.Addr();
auto path = m_Endpoint->PickRandomEstablishedPath();
auto path = m_Endpoint->GetEstablishedPathClosestTo(addr.data());
if(path)
{
HiddenServiceAddressLookup* job = new HiddenServiceAddressLookup(
@ -1206,6 +1211,8 @@ namespace llarp
const RouterContact& prev,
RouterContact& cur, size_t hop)
{
if(remoteIntro.router.IsZero())
return false;
if(hop == numHops - 1)
{
if(llarp_nodedb_get_rc(db, remoteIntro.router, cur))
@ -1235,6 +1242,7 @@ namespace llarp
return ++(itr->second.seqno);
}
/// send on an established convo tag
void
Endpoint::SendContext::EncryptAndSendTo(llarp_buffer_t payload,
ProtocolType t)
@ -1253,6 +1261,14 @@ namespace llarp
f.T = *tags.begin();
f.S = m_Endpoint->GetSeqNoForConvo(f.T);
auto now = llarp_time_now_ms();
if(remoteIntro.ExpiresSoon(now))
{
// shift intro
MarkCurrentIntroBad();
ShiftIntroduction();
}
auto path = m_PathSet->GetNewestPathByRouter(remoteIntro.router);
if(!path)
{

View File

@ -172,7 +172,10 @@ namespace llarp
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
// encode message
if(!msg.BEncode(&buf))
{
llarp::LogError("message too big to encode");
return false;
}
// rewind
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
@ -182,16 +185,24 @@ namespace llarp
D = buf;
// zero out signature
Z.Zero();
// reset size
buf.sz = sizeof(tmp);
// reset buffer
buf = llarp::StackBuffer< decltype(tmp) >(tmp);
// encode frame
if(!BEncode(&buf))
{
llarp::LogError("frame too big to encode");
return false;
}
// rewind
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
// sign
return localIdent.Sign(crypto, Z, buf);
if(!localIdent.Sign(crypto, Z, buf))
{
llarp::LogError("failed to sign? wtf?!");
return false;
}
return true;
}
struct AsyncFrameDecrypt

View File

@ -79,14 +79,14 @@ namespace llarp
TransitHop::HandleDownstream(llarp_buffer_t buf, const TunnelNonce& Y,
llarp_router* r)
{
RelayDownstreamMessage* msg = new RelayDownstreamMessage;
msg->pathid = info.rxID;
msg->Y = Y ^ nonceXOR;
RelayDownstreamMessage msg;
msg.pathid = info.rxID;
msg.Y = Y ^ nonceXOR;
r->crypto.xchacha20(buf, pathKey, Y);
msg->X = buf;
llarp::LogDebug("relay ", msg->X.size(), " bytes downstream from ",
msg.X = buf;
llarp::LogDebug("relay ", msg.X.size(), " bytes downstream from ",
info.upstream, " to ", info.downstream);
return r->SendToOrQueue(info.downstream, msg);
return r->SendToOrQueue(info.downstream, &msg);
}
bool
@ -100,14 +100,14 @@ namespace llarp
}
else
{
RelayUpstreamMessage* msg = new RelayUpstreamMessage;
msg->pathid = info.txID;
msg->Y = Y ^ nonceXOR;
RelayUpstreamMessage msg;
msg.pathid = info.txID;
msg.Y = Y ^ nonceXOR;
msg->X = buf;
llarp::LogDebug("relay ", msg->X.size(), " bytes upstream from ",
msg.X = buf;
llarp::LogDebug("relay ", msg.X.size(), " bytes upstream from ",
info.downstream, " to ", info.upstream);
return r->SendToOrQueue(info.upstream, msg);
return r->SendToOrQueue(info.upstream, &msg);
}
}

View File

@ -13,6 +13,9 @@
#include <llarp/net.h>
#include <windows.h>
#include <iphlpapi.h>
#if WINNT_CROSS_COMPILE && !NTSTATUS
typedef LONG NTSTATUS;
#endif
#include "win32_intrnl.h"
const char *

View File

@ -22,6 +22,11 @@ option(gtest_build_samples "Build gtest's sample programs." OFF)
option(gtest_disable_pthreads "Disable uses of pthreads in gtest." OFF)
# use native windows nt threading even in gcc or clang
if (WIN32)
option(gtest_disable_pthreads ON)
endif(WIN32)
option(
gtest_hide_internal_symbols
"Build gtest with internal symbols hidden in shared libraries."

View File

@ -31,16 +31,17 @@ TEST_F(HiddenServiceTest, TestGenerateIntroSet)
llarp::service::Address addr;
ASSERT_TRUE(ident.pub.CalculateAddress(addr.data()));
llarp::service::IntroSet I;
auto now = llarp_time_now_ms();
while(I.I.size() < 10)
{
llarp::service::Introduction intro;
intro.expiresAt = 1000;
intro.expiresAt = now + (DEFAULT_PATH_LIFETIME / 2);
intro.router.Randomize();
intro.pathID.Randomize();
I.I.push_back(intro);
}
ASSERT_TRUE(ident.SignIntroSet(I, Crypto()));
ASSERT_TRUE(I.VerifySignature(Crypto()));
ASSERT_TRUE(I.Verify(Crypto()));
};
TEST_F(HiddenServiceTest, TestAddressToFromString)

View File

@ -186,6 +186,7 @@ tuntap_sys_set_ipv4_tap(struct device *dev, t_tun_in_addr *s4, uint32_t bits) {
struct ifaliasreq ifrq;
struct sockaddr_in mask;
struct sockaddr_in addr;
struct ifreq ifr;
(void)memset(&ifrq, 0, sizeof(ifrq));
(void)strlcpy(ifrq.ifra_name, dev->if_name, sizeof(ifrq.ifra_name));
@ -284,10 +285,13 @@ tuntap_sys_set_descr(struct device *dev, const char *descr, size_t len) {
}
int
tuntap_sys_set_ifname(struct device *dev, const char *ifname, size_t len) {
struct ifreq ifr;
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->ifname, IF_NAMESIZE);
newname = strdup(ifname);
if(newname == NULL)
{
@ -295,10 +299,13 @@ 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) {
if (ioctl(dev->ctrl_sock, SIOCSIFNAME, &ifr) == -1)
{
perror(NULL);
free(newname);
tuntap_log(TUNTAP_LOG_ERR, "Can't set interface name");
return -1;
}
return 0;
}
}