BIP155 (addrv2)
Tor v3 + i2p
This commit is contained in:
@@ -7,11 +7,13 @@
|
||||
#include "chainparamsbase.h"
|
||||
#include "compat.h"
|
||||
#include "util.h"
|
||||
#include "util/strencodings.h"
|
||||
#include "netbase.h"
|
||||
#include "rpc/protocol.h" // For HTTP status codes
|
||||
#include "sync.h"
|
||||
#include "ui_interface.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "util/strencodings.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -22,6 +24,7 @@
|
||||
#include <event2/http.h>
|
||||
#include <event2/thread.h>
|
||||
#include <event2/buffer.h>
|
||||
#include <event2/bufferevent.h>
|
||||
#include <event2/util.h>
|
||||
#include <event2/keyvalq_struct.h>
|
||||
|
||||
@@ -157,6 +160,7 @@ public:
|
||||
boost::unique_lock<boost::mutex> lock(cs);
|
||||
return queue.size();
|
||||
}
|
||||
|
||||
size_t MaxDepth()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(cs);
|
||||
@@ -167,6 +171,7 @@ public:
|
||||
boost::unique_lock<boost::mutex> lock(cs);
|
||||
return numThreads;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct HTTPPathHandler
|
||||
@@ -196,7 +201,6 @@ std::vector<HTTPPathHandler> pathHandlers;
|
||||
//! Bound listening sockets
|
||||
std::vector<evhttp_bound_socket *> boundSockets;
|
||||
|
||||
|
||||
int getWorkQueueDepth()
|
||||
{
|
||||
return workQueue->Depth();
|
||||
@@ -227,12 +231,17 @@ static bool ClientAllowed(const CNetAddr& netaddr)
|
||||
static bool InitHTTPAllowList()
|
||||
{
|
||||
rpc_allow_subnets.clear();
|
||||
rpc_allow_subnets.push_back(CSubNet("127.0.0.0/8")); // always allow IPv4 local subnet
|
||||
rpc_allow_subnets.push_back(CSubNet("::1")); // always allow IPv6 localhost
|
||||
CNetAddr localv4;
|
||||
CNetAddr localv6;
|
||||
LookupHost("127.0.0.1", localv4, false);
|
||||
LookupHost("::1", localv6, false);
|
||||
rpc_allow_subnets.push_back(CSubNet(localv4, 8)); // always allow IPv4 local subnet
|
||||
rpc_allow_subnets.push_back(CSubNet(localv6)); // always allow IPv6 localhost
|
||||
if (mapMultiArgs.count("-rpcallowip")) {
|
||||
const std::vector<std::string>& vAllow = mapMultiArgs["-rpcallowip"];
|
||||
BOOST_FOREACH (std::string strAllow, vAllow) {
|
||||
CSubNet subnet(strAllow);
|
||||
CSubNet subnet;
|
||||
LookupSubNet(strAllow.c_str(), subnet);
|
||||
if (!subnet.IsValid()) {
|
||||
uiInterface.ThreadSafeMessageBox(
|
||||
strprintf("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow),
|
||||
@@ -273,6 +282,16 @@ static std::string RequestMethodString(HTTPRequest::RequestMethod m)
|
||||
/** HTTP request callback */
|
||||
static void http_request_cb(struct evhttp_request* req, void* arg)
|
||||
{
|
||||
// Disable reading to work around a libevent bug, fixed in 2.2.0.
|
||||
if (event_get_version_number() >= 0x02010600 && event_get_version_number() < 0x02020001) {
|
||||
evhttp_connection* conn = evhttp_request_get_connection(req);
|
||||
if (conn) {
|
||||
bufferevent* bev = evhttp_connection_get_bufferevent(conn);
|
||||
if (bev) {
|
||||
bufferevent_disable(bev, EV_READ);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::unique_ptr<HTTPRequest> hreq(new HTTPRequest(req));
|
||||
|
||||
// Early address-based allow check
|
||||
@@ -315,11 +334,10 @@ static void http_request_cb(struct evhttp_request* req, void* arg)
|
||||
if (i != iend) {
|
||||
std::unique_ptr<HTTPWorkItem> item(new HTTPWorkItem(hreq.release(), path, i->handler));
|
||||
assert(workQueue);
|
||||
if (workQueue->Enqueue(item.get())) {
|
||||
if (workQueue->Enqueue(item.get()))
|
||||
item.release(); /* if true, queue took ownership */
|
||||
} else {
|
||||
item->req->WriteReply(HTTP_INTERNAL, strprintf("Work queue depth %d exceeded", workQueue->Depth() ));
|
||||
}
|
||||
else
|
||||
item->req->WriteReply(HTTP_INTERNAL, "Work queue depth exceeded");
|
||||
} else {
|
||||
hreq->WriteReply(HTTP_NOTFOUND);
|
||||
}
|
||||
@@ -541,7 +559,7 @@ struct event_base* EventBase()
|
||||
static void httpevent_callback_fn(evutil_socket_t, short, void* data)
|
||||
{
|
||||
// Static handler: simply call inner handler
|
||||
HTTPEvent *self = ((HTTPEvent*)data);
|
||||
HTTPEvent *self = static_cast<HTTPEvent*>(data);
|
||||
self->handler();
|
||||
if (self->deleteWhenTriggered)
|
||||
delete self;
|
||||
@@ -628,8 +646,21 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply)
|
||||
struct evbuffer* evb = evhttp_request_get_output_buffer(req);
|
||||
assert(evb);
|
||||
evbuffer_add(evb, strReply.data(), strReply.size());
|
||||
HTTPEvent* ev = new HTTPEvent(eventBase, true,
|
||||
boost::bind(evhttp_send_reply, req, nStatus, (const char*)NULL, (struct evbuffer *)NULL));
|
||||
auto req_copy = req;
|
||||
HTTPEvent* ev = new HTTPEvent(eventBase, true, [req_copy, nStatus]{
|
||||
evhttp_send_reply(req_copy, nStatus, (const char*)NULL, (struct evbuffer *)NULL);
|
||||
// Re-enable reading from the socket. This is the second part of the libevent
|
||||
// workaround above.
|
||||
if (event_get_version_number() >= 0x02010600 && event_get_version_number() < 0x02020001) {
|
||||
evhttp_connection* conn = evhttp_request_get_connection(req_copy);
|
||||
if (conn) {
|
||||
bufferevent* bev = evhttp_connection_get_bufferevent(conn);
|
||||
if (bev) {
|
||||
bufferevent_enable(bev, EV_READ | EV_WRITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
ev->trigger(0);
|
||||
replySent = true;
|
||||
req = 0; // transferred back to main thread
|
||||
@@ -644,7 +675,7 @@ CService HTTPRequest::GetPeer()
|
||||
const char* address = "";
|
||||
uint16_t port = 0;
|
||||
evhttp_connection_get_peer(con, (char**)&address, &port);
|
||||
peer = CService(address, port);
|
||||
peer = LookupNumeric(address, port);
|
||||
}
|
||||
return peer;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user