more netns code

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

@ -29,3 +29,4 @@ SpacesInParentheses: 'false'
SpacesInSquareBrackets: 'false'
Standard: Cpp11
UseTab: Never
SortIncludes: false

@ -226,6 +226,11 @@ if(ANDROID)
set(ANDROID_PLATFORM_SRC llarp/android/ifaddrs.c)
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(ISOLATE_PROC_SRC llarp/linux/netns.cpp)
endif()
set(LIB_PLATFORM_SRC
# for outpug
llarp/logger.cpp
@ -243,6 +248,8 @@ set(LIB_PLATFORM_SRC
llarp/threadpool.cpp
# for android shim
${ANDROID_PLATFORM_SRC}
# process isolation implementation
${ISOLATE_PROC_SRC}
# tun
${LIBTUNTAP_SRC}
# win32 inline procs
@ -437,6 +444,9 @@ else()
endif(NOT HAVE_CXX17_FILESYSTEM)
add_library(llarpplatform-static STATIC ${LIB_PLATFORM_SRC})
target_link_libraries(llarpplatform-static ${THREAD_LIB})
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
target_link_libraries(llarpplatform-static -lcap)
endif()
if(NOT HAVE_CXX17_FILESYSTEM)
target_link_libraries(${STATIC_LIB} ${LIBS} backport-static llarpplatform-static)
else()

@ -64,8 +64,8 @@ namespace llarp
// discard entry
return true;
#else
// writefile
return false;
// writefile
return false;
#endif
});
/// reset errno

@ -153,8 +153,8 @@ struct llarp_win32_loop : public llarp_ev_loop
++idx;
} while(::GetQueuedCompletionStatus(iocpfd, &iolen, &ev_id, &qdata, ms));
// tick_listeners inlined since win32 does not
// implement ev_tun
// tick_listeners inlined since win32 does not
// implement ev_tun
for(auto& l : udp_listeners)
{
if(l->tick)

@ -1,6 +1,6 @@
#ifndef LLARP_FS_HPP
#define LLARP_FS_HPP
#include <functional>
#if defined(WIN32) || defined(_WIN32)
#define PATH_SEP "\\"
#else
@ -24,4 +24,37 @@ namespace fs = std::filesystem;
namespace fs = cpp17::filesystem;
#endif
namespace llarp
{
namespace util
{
typedef std::function< bool(const fs::path &) > PathVisitor;
typedef std::function< void(const fs::path &, PathVisitor) > PathIter;
#if defined(CPP17) && defined(USE_CXX17_FILESYSTEM)
static PathIter IterDir = [](const fs::path &path, PathVisitor visit) {
fs::directory_iterator i(path);
auto itr = fs::begin(i);
while(itr != fs::end(i))
{
fs::path p = path / *itr;
if(!visit(p))
return;
++itr;
}
};
#else
static PathIter IterDir = [](const fs::path &path, PathVisitor visit) {
fs::directory_iterator i(path);
auto itr = i.begin();
while(itr != itr.end())
{
fs::path p = path / *itr;
if(!visit(p))
return;
++itr;
}
};
#endif
} // namespace util
} // namespace llarp
#endif // end LLARP_FS_HPP

@ -17,7 +17,6 @@ namespace llarp
#undef MIN
#endif
memcpy(buf, pkt.base, sz);
llarp::DumpBufferHex(pkt);
return true;
}

@ -184,20 +184,11 @@ struct llarp_nodedb
loadSubdir(const fs::path &dir)
{
ssize_t sz = 0;
fs::directory_iterator i(dir);
#if defined(CPP17) && defined(USE_CXX17_FILESYSTEM)
auto itr = fs::begin(i);
while(itr != fs::end(i))
#else
auto itr = i.begin();
while(itr != itr.end())
#endif
{
if(fs::is_regular_file(itr->path()) && loadfile(*itr))
llarp::util::IterDir(dir, [&](const fs::path &f) -> bool {
if(fs::is_regular_file(f) && loadfile(f))
sz++;
++itr;
}
return true;
});
return sz;
}

@ -51,7 +51,7 @@ namespace llarp
{
llarp::LogInfo("isolating network to namespace ", m_NetNS);
m_IsolatedWorker = llarp_init_isolated_net_threadpool(
m_Name.c_str(), &SetupIsolatedNetwork, &RunIsolatedMainLoop, this);
m_NetNS.c_str(), &SetupIsolatedNetwork, &RunIsolatedMainLoop, this);
m_IsolatedLogic = llarp_init_single_process_logic(m_IsolatedWorker);
return true;
}

@ -15,7 +15,7 @@
#endif
#ifdef __linux__
#include <sys/wait.h>
#include <llarp/linux/netns.hpp>
#endif
#ifdef _MSC_VER
@ -113,30 +113,23 @@ namespace llarp
void
IsolatedPool::Spawn(size_t workers, const char *name)
{
#ifdef __linux__
IsolatedPool *self = this;
self->m_IsolatedName = name;
self->IsolatedName = name;
self->m_IsolatedWorkers = workers;
m_isolated = new std::thread([self] {
if(unshare(self->m_flags) == -1)
if(!self->IsolateCurrentProcess())
{
llarp::LogError("unshared failed: ", strerror(errno));
llarp::LogError("isolation failed: ", strerror(errno));
self->Fail();
return;
}
else
llarp::LogInfo("spawning isolated environment");
self->Pool::Spawn(self->m_IsolatedWorkers, self->IsolatedName);
if(self->Isolated())
{
llarp::LogInfo("spawning isolated environment");
self->Pool::Spawn(self->m_IsolatedWorkers, self->m_IsolatedName);
if(self->Isolated())
{
self->MainLoop();
}
self->MainLoop();
}
});
#else
llarp::LogError("isolated processes not supported on your platform");
Pool::Spawn(workers, name);
#endif
}
void
@ -151,27 +144,51 @@ namespace llarp
}
}
#ifdef __linux__
NetIsolatedPool::NetIsolatedPool(
_NetIsolatedPool::_NetIsolatedPool(
std::function< bool(void *, bool) > setupNet,
std::function< void(void *) > runMain, void *user)
: IsolatedPool(CLONE_NEWNET)
: IsolatedPool(0)
{
m_NetSetup = setupNet;
m_RunMain = runMain;
m_user = user;
}
#else
NetIsolatedPool::NetIsolatedPool(
std::function< bool(void *, bool) > setupNet,
std::function< void(void *) > runMain, void *user)
: IsolatedPool(0)
#ifdef __linux__
struct LinuxNetNSIsolatedPool : public _NetIsolatedPool
{
m_NetSetup = setupNet;
m_RunMain = runMain;
m_user = user;
}
LinuxNetNSIsolatedPool(std::function< bool(void *, bool) > setup,
std::function< void(void *) > run, void *user)
: _NetIsolatedPool(setup, run, user)
{
}
bool
IsolateNetwork()
{
return llarp::linux::NetNSSwitch(IsolatedName);
}
};
typedef LinuxNetNSIsolatedPool NetIsolatedPool;
#define NET_ISOLATION_SUPPORTED
#endif
#if defined(__FreeBSD__)
struct FreeBSDJailedThreadPool : public _NetIsolatedPool
{
bool
IsolateNetwork()
{
// TODO: implement me
return false;
}
};
typedef FreeBSDJailedThreadPool NetIsolatedPool;
#define NET_ISOLATION_SUPPORTED
#endif
} // namespace thread
} // namespace llarp
@ -186,9 +203,17 @@ struct llarp_threadpool
setup_net_func setup = nullptr,
run_main_func runmain = nullptr, void *user = nullptr)
{
#ifdef NET_ISOLATION_SUPPORTED
if(isolate)
impl = new llarp::thread::NetIsolatedPool(setup, runmain, user);
else
#else
if(isolate)
{
llarp::LogError("network isolation not supported");
return nullptr;
}
#endif
impl = new llarp::thread::Pool();
impl->Spawn(workers, name);
}

@ -66,6 +66,17 @@ namespace llarp
void
Join();
/// isolate current thread
/// return true for success
/// return false for failure
/// set errno on fail
/// override me in subclass
virtual bool
IsolateCurrentProcess()
{
return true;
}
// override me to do specific setups after isolation
// return true for success
virtual bool
@ -82,8 +93,8 @@ namespace llarp
std::thread* m_isolated = nullptr;
int m_flags;
int m_IsolatedWorkers = 0;
const char* m_IsolatedName = nullptr;
int m_IsolatedWorkers = 0;
const char* IsolatedName = nullptr;
virtual void
MainLoop()
@ -91,10 +102,20 @@ namespace llarp
}
};
struct NetIsolatedPool : public IsolatedPool
struct _NetIsolatedPool : public IsolatedPool
{
NetIsolatedPool(std::function< bool(void*, bool) > setupNet,
std::function< void(void*) > runMain, void* user);
_NetIsolatedPool(std::function< bool(void*, bool) > setupNet,
std::function< void(void*) > runMain, void* user);
/// implement me per platform
virtual bool
IsolateNetwork() = 0;
bool
IsolateCurrentProcess()
{
return IsolateNetwork();
}
bool
Isolated()

Loading…
Cancel
Save