mirror of https://github.com/oxen-io/lokinet
Merge pull request #1307 from tewinget/libunbound-upstream-dns
Implement upstream DNS using libunboundpull/1315/head
commit
7afa852d96
@ -0,0 +1,69 @@
|
||||
diff --git a/src/thread.cpp b/src/thread.cpp
|
||||
index b14d70757..3675899be 100644
|
||||
--- a/src/thread.cpp
|
||||
+++ b/src/thread.cpp
|
||||
@@ -32,6 +32,10 @@
|
||||
#include "thread.hpp"
|
||||
#include "err.hpp"
|
||||
|
||||
+#ifdef ZMQ_HAVE_WINDOWS
|
||||
+#include <winnt.h>
|
||||
+#endif
|
||||
+
|
||||
bool zmq::thread_t::get_started () const
|
||||
{
|
||||
return _started;
|
||||
@@ -113,10 +117,22 @@ struct thread_info_t
|
||||
#pragma pack(pop)
|
||||
}
|
||||
|
||||
+typedef struct _MY_EXCEPTION_REGISTRATION_RECORD
|
||||
+{
|
||||
+ struct _MY_EXCEPTION_REGISTRATION_RECORD *Next;
|
||||
+ void *Handler;
|
||||
+} MY_EXCEPTION_REGISTRATION_RECORD;
|
||||
+
|
||||
+static EXCEPTION_DISPOSITION NTAPI continue_execution (EXCEPTION_RECORD *rec,
|
||||
+ void *frame, CONTEXT *ctx, void *disp)
|
||||
+{
|
||||
+ return ExceptionContinueExecution;
|
||||
+}
|
||||
+
|
||||
void zmq::thread_t::
|
||||
applyThreadName () // to be called in secondary thread context
|
||||
{
|
||||
- if (!_name[0])
|
||||
+ if (!_name[0] || !IsDebuggerPresent())
|
||||
return;
|
||||
|
||||
thread_info_t thread_info;
|
||||
@@ -125,17 +141,19 @@ void zmq::thread_t::
|
||||
thread_info._thread_id = -1;
|
||||
thread_info._flags = 0;
|
||||
|
||||
-#pragma warning(push)
|
||||
-#pragma warning(disable : 6320 6322)
|
||||
- __try {
|
||||
- DWORD MS_VC_EXCEPTION = 0x406D1388;
|
||||
+ NT_TIB *tib = ((NT_TIB*)NtCurrentTeb());
|
||||
+
|
||||
+ MY_EXCEPTION_REGISTRATION_RECORD rec;
|
||||
+ rec.Next = (MY_EXCEPTION_REGISTRATION_RECORD *)tib->ExceptionList;
|
||||
+ rec.Handler = continue_execution;
|
||||
+
|
||||
+ // push our handler, raise, and finally pop our handler
|
||||
+ tib->ExceptionList = (_EXCEPTION_REGISTRATION_RECORD *)&rec;
|
||||
+ DWORD MS_VC_EXCEPTION = 0x406D1388;
|
||||
RaiseException (MS_VC_EXCEPTION, 0,
|
||||
- sizeof (thread_info) / sizeof (ULONG_PTR),
|
||||
- (ULONG_PTR *) &thread_info);
|
||||
- }
|
||||
- __except (EXCEPTION_CONTINUE_EXECUTION) {
|
||||
- }
|
||||
-#pragma warning(pop)
|
||||
+ sizeof (thread_info) / sizeof (ULONG_PTR),
|
||||
+ (ULONG_PTR *) &thread_info);
|
||||
+ tib->ExceptionList = (_EXCEPTION_REGISTRATION_RECORD *)(((MY_EXCEPTION_REGISTRATION_RECORD *)tib->ExceptionList)->Next);
|
||||
}
|
||||
|
||||
#elif defined ZMQ_HAVE_VXWORKS
|
@ -0,0 +1,43 @@
|
||||
diff --git a/RELICENSE/tomzbench.md b/RELICENSE/tomzbench.md
|
||||
new file mode 100644
|
||||
index 000000000..1cbcc4fdb
|
||||
--- /dev/null
|
||||
+++ b/RELICENSE/tomzbench.md
|
||||
@@ -0,0 +1,14 @@
|
||||
+# Permission to Relicense under MPLv2
|
||||
+
|
||||
+This is a statement by Thomas Chiantia
|
||||
+that grants permission to relicense its copyrights in the libzmq C++
|
||||
+library (ZeroMQ) under the Mozilla Public License v2 (MPLv2).
|
||||
+
|
||||
+A portion of the commits made by the Github handle "tomzbench", with
|
||||
+commit author "Thomas<Thomas@Altronix.com>", are copyright of
|
||||
+Thomas Chiantia.
|
||||
+This document hereby grants the libzmq project team to relicense libzmq,
|
||||
+including all past, present and future contributions of the author listed above.
|
||||
+
|
||||
+Thomas Chiantia
|
||||
+2019/08/10
|
||||
diff --git a/src/thread.cpp b/src/thread.cpp
|
||||
index 2cad2adaa..6f07e9cee 100644
|
||||
--- a/src/thread.cpp
|
||||
+++ b/src/thread.cpp
|
||||
@@ -117,11 +117,14 @@ struct thread_info_t
|
||||
#pragma pack(pop)
|
||||
}
|
||||
|
||||
-typedef struct _MY_EXCEPTION_REGISTRATION_RECORD
|
||||
+struct MY_EXCEPTION_REGISTRATION_RECORD
|
||||
{
|
||||
- struct _MY_EXCEPTION_REGISTRATION_RECORD *Next;
|
||||
- void *Handler;
|
||||
-} MY_EXCEPTION_REGISTRATION_RECORD;
|
||||
+ typedef EXCEPTION_DISPOSITION (NTAPI *HandlerFunctionType) (
|
||||
+ EXCEPTION_RECORD *, void *, CONTEXT *, void *);
|
||||
+
|
||||
+ MY_EXCEPTION_REGISTRATION_RECORD *Next;
|
||||
+ HandlerFunctionType Handler;
|
||||
+};
|
||||
|
||||
static EXCEPTION_DISPOSITION NTAPI continue_execution (EXCEPTION_RECORD *rec,
|
||||
void *frame,
|
@ -0,0 +1,150 @@
|
||||
#include <dns/unbound_resolver.hpp>
|
||||
|
||||
#include <dns/server.hpp>
|
||||
#include <util/buffer.hpp>
|
||||
|
||||
namespace llarp::dns
|
||||
{
|
||||
struct PendingUnboundLookup
|
||||
{
|
||||
std::weak_ptr<UnboundResolver> resolver;
|
||||
Message msg;
|
||||
SockAddr source;
|
||||
};
|
||||
|
||||
void
|
||||
UnboundResolver::Reset()
|
||||
{
|
||||
started = false;
|
||||
if (unboundContext)
|
||||
{
|
||||
DeregisterPollFD();
|
||||
ub_ctx_delete(unboundContext);
|
||||
}
|
||||
unboundContext = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
UnboundResolver::DeregisterPollFD()
|
||||
{
|
||||
eventLoop->deregister_poll_fd_readable(ub_fd(unboundContext));
|
||||
}
|
||||
|
||||
void
|
||||
UnboundResolver::RegisterPollFD()
|
||||
{
|
||||
eventLoop->register_poll_fd_readable(
|
||||
ub_fd(unboundContext), [=]() { ub_process(unboundContext); });
|
||||
}
|
||||
|
||||
UnboundResolver::UnboundResolver(
|
||||
llarp_ev_loop_ptr eventLoop, ReplyFunction replyFunc, FailFunction failFunc)
|
||||
: unboundContext(nullptr)
|
||||
, started(false)
|
||||
, eventLoop(eventLoop)
|
||||
, replyFunc(replyFunc)
|
||||
, failFunc(failFunc)
|
||||
{
|
||||
}
|
||||
|
||||
// static callback
|
||||
void
|
||||
UnboundResolver::Callback(void* data, int err, ub_result* result)
|
||||
{
|
||||
std::unique_ptr<PendingUnboundLookup> lookup{static_cast<PendingUnboundLookup*>(data)};
|
||||
|
||||
auto this_ptr = lookup->resolver.lock();
|
||||
if (not this_ptr)
|
||||
return; // resolver is gone, so we don't reply.
|
||||
|
||||
if (err != 0)
|
||||
{
|
||||
Message& msg = lookup->msg;
|
||||
msg.AddServFail();
|
||||
this_ptr->failFunc(lookup->source, msg);
|
||||
ub_resolve_free(result);
|
||||
return;
|
||||
}
|
||||
|
||||
llarp_buffer_t buf;
|
||||
buf.base = buf.cur = static_cast<byte_t*>(result->answer_packet);
|
||||
buf.sz = result->answer_len;
|
||||
|
||||
MessageHeader hdr;
|
||||
hdr.Decode(&buf);
|
||||
hdr.id = lookup->msg.hdr_id;
|
||||
|
||||
buf.cur = buf.base;
|
||||
hdr.Encode(&buf);
|
||||
|
||||
std::vector<byte_t> buf_copy(buf.sz);
|
||||
std::copy_n(buf.base, buf.sz, buf_copy.begin());
|
||||
|
||||
this_ptr->replyFunc(lookup->source, std::move(buf_copy));
|
||||
|
||||
ub_resolve_free(result);
|
||||
}
|
||||
|
||||
bool
|
||||
UnboundResolver::Init()
|
||||
{
|
||||
if (started)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
unboundContext = ub_ctx_create();
|
||||
|
||||
if (not unboundContext)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RegisterPollFD();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
UnboundResolver::AddUpstreamResolver(const std::string& upstreamResolverIP)
|
||||
{
|
||||
if (ub_ctx_set_fwd(unboundContext, upstreamResolverIP.c_str()) != 0)
|
||||
{
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
UnboundResolver::Lookup(const SockAddr& source, Message msg)
|
||||
{
|
||||
if (not unboundContext)
|
||||
{
|
||||
msg.AddServFail();
|
||||
failFunc(source, std::move(msg));
|
||||
return;
|
||||
}
|
||||
|
||||
started = true;
|
||||
|
||||
const auto& q = msg.questions[0];
|
||||
auto* lookup = new PendingUnboundLookup{weak_from_this(), msg, source};
|
||||
int err = ub_resolve_async(
|
||||
unboundContext,
|
||||
q.Name().c_str(),
|
||||
q.qtype,
|
||||
q.qclass,
|
||||
(void*)lookup,
|
||||
&UnboundResolver::Callback,
|
||||
nullptr);
|
||||
|
||||
if (err != 0)
|
||||
{
|
||||
msg.AddServFail();
|
||||
failFunc(source, std::move(msg));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace llarp::dns
|
@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <unbound.h>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
|
||||
#include <ev/ev.hpp>
|
||||
#include <util/thread/logic.hpp>
|
||||
|
||||
#include <dns/message.hpp>
|
||||
|
||||
namespace llarp::dns
|
||||
{
|
||||
using ReplyFunction = std::function<void(SockAddr source, std::vector<byte_t> buf)>;
|
||||
using FailFunction = std::function<void(SockAddr source, Message msg)>;
|
||||
|
||||
class UnboundResolver : public std::enable_shared_from_this<UnboundResolver>
|
||||
{
|
||||
private:
|
||||
ub_ctx* unboundContext;
|
||||
|
||||
bool started;
|
||||
|
||||
llarp_ev_loop_ptr eventLoop;
|
||||
ReplyFunction replyFunc;
|
||||
FailFunction failFunc;
|
||||
|
||||
void
|
||||
Reset();
|
||||
|
||||
void
|
||||
DeregisterPollFD();
|
||||
void
|
||||
RegisterPollFD();
|
||||
|
||||
public:
|
||||
UnboundResolver(llarp_ev_loop_ptr eventLoop, ReplyFunction replyFunc, FailFunction failFunc);
|
||||
|
||||
static void
|
||||
Callback(void* data, int err, ub_result* result);
|
||||
|
||||
// upstream resolver IP can be IPv4 or IPv6
|
||||
bool
|
||||
Init();
|
||||
|
||||
bool
|
||||
AddUpstreamResolver(const std::string& upstreamResolverIP);
|
||||
|
||||
void
|
||||
Lookup(const SockAddr& source, Message msg);
|
||||
};
|
||||
|
||||
} // namespace llarp::dns
|
Loading…
Reference in New Issue