mirror of
https://github.com/twisterarmy/twister-core.git
synced 2025-03-10 12:31:27 +00:00
dhtproxy: tunnel DHT traffic into TCP connections
This commit is contained in:
parent
068a43211a
commit
e52f2c2527
@ -156,6 +156,7 @@ BITCOIN_TWISTER_SOURCES = \
|
|||||||
src/leveldb.cpp \
|
src/leveldb.cpp \
|
||||||
src/txdb.cpp \
|
src/txdb.cpp \
|
||||||
src/chainparams.cpp \
|
src/chainparams.cpp \
|
||||||
|
src/dhtproxy.cpp \
|
||||||
src/twister.cpp \
|
src/twister.cpp \
|
||||||
src/twister_rss.cpp \
|
src/twister_rss.cpp \
|
||||||
src/twister_utils.cpp \
|
src/twister_utils.cpp \
|
||||||
|
330
src/dhtproxy.cpp
Normal file
330
src/dhtproxy.cpp
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
// Copyright (c) 2014 Miguel Freitas
|
||||||
|
// tunnel DHT requests into tcp connection
|
||||||
|
// see: https://groups.google.com/forum/#!topic/twister-dev/uKjFGSw24yA
|
||||||
|
|
||||||
|
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
|
||||||
|
#include <boost/assign.hpp>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <algorithm> // std::random_shuffle
|
||||||
|
|
||||||
|
#include "dhtproxy.h"
|
||||||
|
|
||||||
|
#include "libtorrent/alert_manager.hpp"
|
||||||
|
#include "libtorrent/alert_types.hpp"
|
||||||
|
#include "libtorrent/peer_id.hpp"
|
||||||
|
#include "libtorrent/bencode.hpp"
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "uint256.h"
|
||||||
|
#include "script.h"
|
||||||
|
#include "init.h"
|
||||||
|
#include "twister.h"
|
||||||
|
#include "twister_utils.h"
|
||||||
|
|
||||||
|
//#define dbgprintf OutputDebugStringF
|
||||||
|
#define dbgprintf(...) // no debug printf
|
||||||
|
|
||||||
|
using namespace libtorrent;
|
||||||
|
|
||||||
|
namespace DhtProxy
|
||||||
|
{
|
||||||
|
bool fEnabled = true;
|
||||||
|
CCriticalSection cs_dhtProxy;
|
||||||
|
map<sha1_hash, std::list<alert_manager*> > m_dhtgetMap;
|
||||||
|
map<sha1_hash, std::list<CService> > m_dhtgetPeersReq;
|
||||||
|
|
||||||
|
class PeerBanStats {
|
||||||
|
public:
|
||||||
|
PeerBanStats() : active(0), count(0), limit(time_now()) {}
|
||||||
|
int active;
|
||||||
|
int count;
|
||||||
|
ptime limit;
|
||||||
|
};
|
||||||
|
map<CService, PeerBanStats> m_peerBanStats;
|
||||||
|
size_t numProxiesToUse = 4;
|
||||||
|
|
||||||
|
void dhtgetMapAdd(sha1_hash &ih, alert_manager *am)
|
||||||
|
{
|
||||||
|
LOCK(cs_dhtProxy);
|
||||||
|
m_dhtgetMap[ih].push_back(am);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dhtgetMapRemove(sha1_hash &ih, alert_manager *am)
|
||||||
|
{
|
||||||
|
LOCK(cs_dhtProxy);
|
||||||
|
std::map<sha1_hash, std::list<alert_manager*> >::iterator mi = m_dhtgetMap.find(ih);
|
||||||
|
if( mi != m_dhtgetMap.end() ) {
|
||||||
|
std::list<alert_manager *> &amList = (*mi).second;
|
||||||
|
amList.remove(am);
|
||||||
|
if( !amList.size() ) {
|
||||||
|
m_dhtgetMap.erase(ih);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dhtgetMapPost(sha1_hash &ih, const alert &a)
|
||||||
|
{
|
||||||
|
LOCK(cs_dhtProxy);
|
||||||
|
std::map<sha1_hash, std::list<alert_manager*> >::iterator mi = m_dhtgetMap.find(ih);
|
||||||
|
if( mi != m_dhtgetMap.end() ) {
|
||||||
|
std::list<alert_manager *> &amList = (*mi).second;
|
||||||
|
BOOST_FOREACH(alert_manager *am, amList) {
|
||||||
|
am->post_alert(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<CNode*> getRandomDhtProxies()
|
||||||
|
{
|
||||||
|
// (cs_vNodes) lock must be held!
|
||||||
|
vector<CNode*> vNodesProxy;
|
||||||
|
BOOST_FOREACH(CNode* pnode, vNodes) {
|
||||||
|
if (pnode->nVersion >= DHT_PROXY_VERSION && !pnode->fNoDhtProxy) {
|
||||||
|
vNodesProxy.push_back(pnode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::random_shuffle(vNodesProxy.begin(),vNodesProxy.end());
|
||||||
|
if(vNodesProxy.size() > numProxiesToUse) {
|
||||||
|
vNodesProxy.resize(numProxiesToUse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return vNodesProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<CNode*> dhtgetStartRequest(std::string const &username, std::string const &resource, bool multi)
|
||||||
|
{
|
||||||
|
CDHTGetRequest req;
|
||||||
|
req.vchUsername = std::vector<char>(username.begin(), username.end());
|
||||||
|
req.vchResource = std::vector<char>(resource.begin(), resource.end());
|
||||||
|
req.resTypeMulti = multi;
|
||||||
|
req.stopReq = false;
|
||||||
|
|
||||||
|
LOCK(cs_vNodes);
|
||||||
|
vector<CNode*> vNodesReq = getRandomDhtProxies();
|
||||||
|
BOOST_FOREACH(CNode* pnode, vNodesReq) {
|
||||||
|
dbgprintf("DhtProxy::dhtgetStartRequest: pushMessage to %s\n", pnode->addr.ToString().c_str());
|
||||||
|
pnode->PushMessage("dhtgetreq", req);
|
||||||
|
pnode->AddRef();
|
||||||
|
}
|
||||||
|
if( !vNodesReq.size() ) {
|
||||||
|
dbgprintf("DhtProxy::dhtgetStartRequest: sorry, no dht proxy found.\n");
|
||||||
|
|
||||||
|
// fake no data to wakeup listener
|
||||||
|
dht_reply_data_done_alert dd("","",false,false,false);
|
||||||
|
sha1_hash ih = dhtTargetHash(username, resource, multi ? "m" : "s");
|
||||||
|
dhtgetMapPost(ih, dd);
|
||||||
|
}
|
||||||
|
return vNodesReq;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dhtgetStopRequest(vector<CNode*> vNodesReq, std::string const &username, std::string const &resource, bool multi)
|
||||||
|
{
|
||||||
|
CDHTGetRequest req;
|
||||||
|
req.vchUsername = std::vector<char>(username.begin(), username.end());
|
||||||
|
req.vchResource = std::vector<char>(resource.begin(), resource.end());
|
||||||
|
req.resTypeMulti = multi;
|
||||||
|
req.stopReq = true;
|
||||||
|
|
||||||
|
BOOST_FOREACH(CNode* pnode, vNodesReq) {
|
||||||
|
dbgprintf("DhtProxy::dhtgetStopRequest: pushMessage to %s\n", pnode->addr.ToString().c_str());
|
||||||
|
pnode->PushMessage("dhtgetreq", req);
|
||||||
|
pnode->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dhtgetPeerReqAdd(sha1_hash &ih, const CNode *pnode)
|
||||||
|
{
|
||||||
|
LOCK(cs_dhtProxy);
|
||||||
|
m_dhtgetPeersReq[ih].push_back(pnode->addr);
|
||||||
|
m_peerBanStats[pnode->addr].active++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dhtgetPeerReqRemove(sha1_hash &ih, const CNode *pnode)
|
||||||
|
{
|
||||||
|
LOCK(cs_dhtProxy);
|
||||||
|
std::map<sha1_hash, std::list<CService> >::iterator mi = m_dhtgetPeersReq.find(ih);
|
||||||
|
if( mi != m_dhtgetPeersReq.end() ) {
|
||||||
|
std::list<CService> &addrList = (*mi).second;
|
||||||
|
addrList.remove(pnode->addr);
|
||||||
|
if( !addrList.size() ) {
|
||||||
|
m_dhtgetPeersReq.erase(ih);
|
||||||
|
}
|
||||||
|
m_peerBanStats[pnode->addr].active--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dhtgetPeerReqReply(sha1_hash &ih, const alert *a)
|
||||||
|
{
|
||||||
|
CDHTGetReply reply;
|
||||||
|
reply.vchTargetHash = std::vector<char>(ih.begin(), ih.end());
|
||||||
|
dht_reply_data_alert const* rd = alert_cast<dht_reply_data_alert>(a);
|
||||||
|
if (rd) {
|
||||||
|
bencode(std::back_inserter(reply.vchBencodedData), rd->m_lst);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOCK(cs_dhtProxy);
|
||||||
|
std::map<sha1_hash, std::list<CService> >::iterator mi = m_dhtgetPeersReq.find(ih);
|
||||||
|
if( mi != m_dhtgetPeersReq.end() ) {
|
||||||
|
std::list<CService> &addrList = (*mi).second;
|
||||||
|
BOOST_FOREACH(CService &addr, addrList) {
|
||||||
|
LOCK(cs_vNodes);
|
||||||
|
BOOST_FOREACH(CNode* pnode, vNodes) {
|
||||||
|
if ((CService)pnode->addr == addr) {
|
||||||
|
dbgprintf("DhtProxy::dhtgetPeerReqReply: pushMessage to %s\n", pnode->addr.ToString().c_str());
|
||||||
|
pnode->PushMessage("dhtgetreply", reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkForAbuse(CNode* pfrom)
|
||||||
|
{
|
||||||
|
LOCK(cs_dhtProxy);
|
||||||
|
|
||||||
|
// logic inspired/copied from dht_tracker.cpp:incoming_packet
|
||||||
|
ptime now = time_now();
|
||||||
|
PeerBanStats *match = &m_peerBanStats[pfrom->addr];
|
||||||
|
match->count++;
|
||||||
|
if( match->count >= 500 ) {
|
||||||
|
if (now < match->limit) {
|
||||||
|
if( match->count == 500 ) {
|
||||||
|
dbgprintf("DhtProxy::checkForAbuse: %s misbehaving, too much requests.\n",
|
||||||
|
pfrom->addr.ToString().c_str());
|
||||||
|
}
|
||||||
|
match->limit = now + minutes(5);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
match->count = 0;
|
||||||
|
match->limit = now + seconds(5);
|
||||||
|
}
|
||||||
|
if( match->active > 10 ) {
|
||||||
|
dbgprintf("DhtProxy::checkForAbuse: %s misbehaving, max active requests reached.\n",
|
||||||
|
pfrom->addr.ToString().c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dhtgetRequestReceived(const CDHTGetRequest& req, CNode* pfrom)
|
||||||
|
{
|
||||||
|
if( fEnabled ) {
|
||||||
|
// we are using proxy ourselves, we can't be proxy to anyone else
|
||||||
|
pfrom->PushMessage("nodhtproxy");
|
||||||
|
return true;
|
||||||
|
} else if( !req.stopReq && checkForAbuse(pfrom) ) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
std::string username(req.vchUsername.data(), req.vchUsername.size());
|
||||||
|
std::string resource(req.vchResource.data(), req.vchResource.size());
|
||||||
|
bool multi(req.resTypeMulti);
|
||||||
|
|
||||||
|
dbgprintf("DhtProxy::dhtgetRequestReceived: (%s,%s,%d,stop=%d) from %s\n",
|
||||||
|
username.c_str(), resource.c_str(), multi, req.stopReq,
|
||||||
|
pfrom->addr.ToString().c_str());
|
||||||
|
|
||||||
|
sha1_hash ih = dhtTargetHash(username, resource, multi ? "m" : "s");
|
||||||
|
if( !req.stopReq ) {
|
||||||
|
dhtgetPeerReqAdd(ih, pfrom);
|
||||||
|
dhtGetData(username, resource, multi);
|
||||||
|
} else {
|
||||||
|
dhtgetPeerReqRemove(ih, pfrom);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dhtgetReplyReceived(const CDHTGetReply& reply, CNode* pfrom)
|
||||||
|
{
|
||||||
|
std::string strTargetHash(reply.vchTargetHash.data(), reply.vchTargetHash.size());
|
||||||
|
sha1_hash ih(strTargetHash);
|
||||||
|
|
||||||
|
if( !reply.vchBencodedData.size() ) {
|
||||||
|
dbgprintf("DhtProxy::dhtgetReplyReceived: empty data from %s\n",
|
||||||
|
pfrom->addr.ToString().c_str());
|
||||||
|
|
||||||
|
// No reply - these fields are not used, we just want cast in twister.cpp:dhtget to fail
|
||||||
|
dht_reply_data_done_alert dd("","",false,false,false);
|
||||||
|
dhtgetMapPost(ih, dd);
|
||||||
|
} else {
|
||||||
|
lazy_entry v;
|
||||||
|
int pos;
|
||||||
|
libtorrent::error_code ec;
|
||||||
|
if (lazy_bdecode(reply.vchBencodedData.data(), reply.vchBencodedData.data() +
|
||||||
|
reply.vchBencodedData.size(), v, ec, &pos) == 0 && v.type() == lazy_entry::list_t ) {
|
||||||
|
entry lst;
|
||||||
|
lst = v;
|
||||||
|
dbgprintf("DhtProxy::dhtgetReplyReceived: %zd entries from %s\n",
|
||||||
|
lst.list().size(), pfrom->addr.ToString().c_str());
|
||||||
|
dht_reply_data_alert rd(lst.list());
|
||||||
|
dhtgetMapPost(ih, rd);
|
||||||
|
} else {
|
||||||
|
dbgprintf("DhtProxy::dhtgetReplyReceived: parsing error (data from %s)\n",
|
||||||
|
pfrom->addr.ToString().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dhtputRequest(std::string const &username, std::string const &resource, bool multi,
|
||||||
|
std::string const &str_p, std::string const &sig_p, std::string const &sig_user)
|
||||||
|
{
|
||||||
|
CDHTPutRequest req;
|
||||||
|
req.vchUsername = std::vector<char>(username.begin(), username.end());
|
||||||
|
req.vchResource = std::vector<char>(resource.begin(), resource.end());
|
||||||
|
req.resTypeMulti = multi;
|
||||||
|
req.vchStr_p = std::vector<char>(str_p.begin(), str_p.end());
|
||||||
|
req.vchSig_p = std::vector<char>(sig_p.begin(), sig_p.end());
|
||||||
|
req.vchSig_user = std::vector<char>(sig_user.begin(), sig_user.end());
|
||||||
|
|
||||||
|
LOCK(cs_vNodes);
|
||||||
|
vector<CNode*> vNodesReq = getRandomDhtProxies();
|
||||||
|
BOOST_FOREACH(CNode* pnode, vNodesReq) {
|
||||||
|
dbgprintf("DhtProxy::dhtputRequest: pushMessage to %s\n", pnode->addr.ToString().c_str());
|
||||||
|
pnode->PushMessage("dhtputreq", req);
|
||||||
|
}
|
||||||
|
if( !vNodesReq.size() ) {
|
||||||
|
dbgprintf("DhtProxy::dhtputRequest: sorry, no dht proxy found.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dhtputRequestReceived(const CDHTPutRequest& req, CNode* pfrom)
|
||||||
|
{
|
||||||
|
if( fEnabled ) {
|
||||||
|
// we are using proxy ourselves, we can't be proxy to anyone else
|
||||||
|
pfrom->PushMessage("nodhtproxy");
|
||||||
|
return true;
|
||||||
|
} else if( checkForAbuse(pfrom) ) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
std::string username(req.vchUsername.data(), req.vchUsername.size());
|
||||||
|
std::string resource(req.vchResource.data(), req.vchResource.size());
|
||||||
|
bool multi(req.resTypeMulti);
|
||||||
|
|
||||||
|
dbgprintf("DhtProxy::dhtputRequestReceived: (%s,%s,%d) from %s\n",
|
||||||
|
username.c_str(), resource.c_str(), multi,
|
||||||
|
pfrom->addr.ToString().c_str());
|
||||||
|
|
||||||
|
lazy_entry v;
|
||||||
|
int pos;
|
||||||
|
libtorrent::error_code ec;
|
||||||
|
if (lazy_bdecode(req.vchStr_p.data(), req.vchStr_p.data() +
|
||||||
|
req.vchStr_p.size(), v, ec, &pos) == 0 ) {
|
||||||
|
entry p;
|
||||||
|
p = v;
|
||||||
|
std::string sig_p(req.vchSig_p.data(), req.vchSig_p.size());
|
||||||
|
std::string sig_user(req.vchSig_user.data(), req.vchSig_user.size());
|
||||||
|
|
||||||
|
dhtPutDataSigned(username,resource,multi,p,sig_p,sig_user, false);
|
||||||
|
} else {
|
||||||
|
dbgprintf("DhtProxy::dhtputRequestReceived: parsing error (data from %s)\n",
|
||||||
|
pfrom->addr.ToString().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
195
src/dhtproxy.h
Normal file
195
src/dhtproxy.h
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
// Copyright (c) 2014 Miguel Freitas
|
||||||
|
|
||||||
|
#ifndef DHTPROXY_H
|
||||||
|
#define DHTPROXY_H
|
||||||
|
|
||||||
|
#include "serialize.h"
|
||||||
|
#include "net.h"
|
||||||
|
#include "uint256.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// just a small set of declarations to avoid main.c depending on libtorrent headers
|
||||||
|
namespace libtorrent {
|
||||||
|
class alert_manager;
|
||||||
|
class big_number;
|
||||||
|
typedef big_number sha1_hash;
|
||||||
|
class alert;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CDHTTarget;
|
||||||
|
class CDHTGetRequest;
|
||||||
|
class CDHTGetReply;
|
||||||
|
class CDHTPutRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DHTGet Sequence:
|
||||||
|
*
|
||||||
|
* Client Server
|
||||||
|
* 1) dhtgetMapAdd
|
||||||
|
* 2) dhtgetStartRequest
|
||||||
|
* => CDHTGetRequest =>
|
||||||
|
* 3) dhtgetRequestReceived(stopReq=False)
|
||||||
|
* 4) (dhtgetPeerReqAdd)
|
||||||
|
* 5) (ses->dht_getData)
|
||||||
|
* 6.1) dhtgetPeerReqReply (from ThreadSessionAlerts)
|
||||||
|
* 6.2) <= CDHTGetReply <=
|
||||||
|
* 6.3) dhtgetReplyReceived
|
||||||
|
* 6.4) (dhtgetMapPost)
|
||||||
|
* [ ..item 6 repeats... ]
|
||||||
|
* 7) dhtgetMapRemove
|
||||||
|
* 8) dhtgetStopRequest
|
||||||
|
* => CDHTGetRequest =>
|
||||||
|
* 9) dhtgetRequestReceived(stopReq=True)
|
||||||
|
* 10) (dhtgetPeerReqRemove)
|
||||||
|
*
|
||||||
|
**
|
||||||
|
* DHTPut Sequence:
|
||||||
|
*
|
||||||
|
* Client Server
|
||||||
|
* 1) dhtputRequest
|
||||||
|
* => CDHTPutRequest =>
|
||||||
|
* 2) dhtputRequestReceived
|
||||||
|
* 3) (ses->dht_putDataSigned)
|
||||||
|
*/
|
||||||
|
namespace DhtProxy
|
||||||
|
{
|
||||||
|
extern bool fEnabled;
|
||||||
|
|
||||||
|
// Register a listener for dhtget requests (client side)
|
||||||
|
void dhtgetMapAdd(libtorrent::sha1_hash &ih, libtorrent::alert_manager *am);
|
||||||
|
|
||||||
|
// Unregister the dhtget listener (client side)
|
||||||
|
void dhtgetMapRemove(libtorrent::sha1_hash &ih, libtorrent::alert_manager *am);
|
||||||
|
|
||||||
|
// Request a dhtget. Returns the list of node the request was sent to. (client side)
|
||||||
|
vector<CNode*> dhtgetStartRequest(std::string const &username, std::string const &resource, bool multi);
|
||||||
|
|
||||||
|
// Stop a dhtget request to the nodes listed. (client side)
|
||||||
|
void dhtgetStopRequest(vector<CNode*> vNodesReq, std::string const &username, std::string const &resource, bool multi);
|
||||||
|
|
||||||
|
// Handle a dhtget request received from TCP. send request to UDP. (server side)
|
||||||
|
// return true if accepted.
|
||||||
|
bool dhtgetRequestReceived(const CDHTGetRequest& req, CNode* pfrom);
|
||||||
|
|
||||||
|
// Handle a dhtget reply received from UDP, send it to the peers that made the request. (server side)
|
||||||
|
void dhtgetPeerReqReply(libtorrent::sha1_hash &ih, const libtorrent::alert *a);
|
||||||
|
|
||||||
|
// Handle a dhtget reply received from TCP. Will call dhtgetMapPost as needed. (client side)
|
||||||
|
// return true if accepted.
|
||||||
|
bool dhtgetReplyReceived(const CDHTGetReply& reply, CNode* pfrom);
|
||||||
|
|
||||||
|
// Request a dhtput.
|
||||||
|
void dhtputRequest(std::string const &username, std::string const &resource, bool multi,
|
||||||
|
std::string const &str_p, std::string const &sig_p, std::string const &sig_user);
|
||||||
|
|
||||||
|
// Handle a dhtput request received from TCP. send request to UDP. (server side)
|
||||||
|
// return true if accepted.
|
||||||
|
bool dhtputRequestReceived(const CDHTPutRequest& req, CNode* pfrom);
|
||||||
|
}
|
||||||
|
|
||||||
|
class CDHTTarget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<char> vchUsername;
|
||||||
|
std::vector<char> vchResource;
|
||||||
|
bool resTypeMulti;
|
||||||
|
|
||||||
|
CDHTTarget()
|
||||||
|
{
|
||||||
|
SetNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE
|
||||||
|
(
|
||||||
|
READWRITE(vchUsername);
|
||||||
|
READWRITE(vchResource);
|
||||||
|
READWRITE(resTypeMulti);
|
||||||
|
)
|
||||||
|
|
||||||
|
void SetNull()
|
||||||
|
{
|
||||||
|
vchUsername.clear();
|
||||||
|
vchResource.clear();
|
||||||
|
resTypeMulti = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CDHTGetRequest : public CDHTTarget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool stopReq;
|
||||||
|
|
||||||
|
CDHTGetRequest() : CDHTTarget()
|
||||||
|
{
|
||||||
|
SetNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE
|
||||||
|
(
|
||||||
|
CDHTTarget* pthis = (CDHTTarget*)(this);
|
||||||
|
READWRITE(*pthis);
|
||||||
|
READWRITE(stopReq);
|
||||||
|
)
|
||||||
|
|
||||||
|
void SetNull()
|
||||||
|
{
|
||||||
|
stopReq = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CDHTGetReply
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<char> vchTargetHash;
|
||||||
|
std::vector<char> vchBencodedData;
|
||||||
|
|
||||||
|
CDHTGetReply()
|
||||||
|
{
|
||||||
|
SetNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE
|
||||||
|
(
|
||||||
|
READWRITE(vchTargetHash);
|
||||||
|
READWRITE(vchBencodedData);
|
||||||
|
)
|
||||||
|
|
||||||
|
void SetNull()
|
||||||
|
{
|
||||||
|
vchTargetHash.clear();
|
||||||
|
vchBencodedData.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CDHTPutRequest : public CDHTTarget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<char> vchStr_p;
|
||||||
|
std::vector<char> vchSig_p;
|
||||||
|
std::vector<char> vchSig_user;
|
||||||
|
|
||||||
|
CDHTPutRequest() : CDHTTarget()
|
||||||
|
{
|
||||||
|
SetNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE
|
||||||
|
(
|
||||||
|
CDHTTarget* pthis = (CDHTTarget*)(this);
|
||||||
|
READWRITE(*pthis);
|
||||||
|
READWRITE(vchStr_p);
|
||||||
|
READWRITE(vchSig_p);
|
||||||
|
READWRITE(vchSig_user);
|
||||||
|
)
|
||||||
|
|
||||||
|
void SetNull()
|
||||||
|
{
|
||||||
|
vchStr_p.clear();
|
||||||
|
vchSig_p.clear();
|
||||||
|
vchSig_user.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -431,7 +431,11 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||||||
// to protect privacy, do not listen by default if a proxy server is specified
|
// to protect privacy, do not listen by default if a proxy server is specified
|
||||||
SoftSetBoolArg("-listen", false);
|
SoftSetBoolArg("-listen", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mapArgs.count("-proxy") || mapArgs.count("-tor")) {
|
||||||
|
SoftSetBoolArg("-dhtproxy", true);
|
||||||
|
}
|
||||||
|
|
||||||
if (!GetBoolArg("-listen", true)) {
|
if (!GetBoolArg("-listen", true)) {
|
||||||
// do not map ports or try to retrieve public IP when not listening (pointless)
|
// do not map ports or try to retrieve public IP when not listening (pointless)
|
||||||
SoftSetBoolArg("-upnp", false);
|
SoftSetBoolArg("-upnp", false);
|
||||||
|
41
src/main.cpp
41
src/main.cpp
@ -13,6 +13,7 @@
|
|||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
#include "checkqueue.h"
|
#include "checkqueue.h"
|
||||||
#include "chainparams.h"
|
#include "chainparams.h"
|
||||||
|
#include "dhtproxy.h"
|
||||||
|
|
||||||
#include "twister.h"
|
#include "twister.h"
|
||||||
#include "utf8core.h"
|
#include "utf8core.h"
|
||||||
@ -3185,6 +3186,46 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
pfrom->fRelayTxes = true;
|
pfrom->fRelayTxes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (strCommand == "dhtgetreq")
|
||||||
|
{
|
||||||
|
CDHTGetRequest req;
|
||||||
|
vRecv >> req;
|
||||||
|
|
||||||
|
if( DhtProxy::dhtgetRequestReceived(req, pfrom) ) {
|
||||||
|
// ok
|
||||||
|
} else {
|
||||||
|
pfrom->Misbehaving(20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (strCommand == "dhtputreq")
|
||||||
|
{
|
||||||
|
CDHTPutRequest req;
|
||||||
|
vRecv >> req;
|
||||||
|
|
||||||
|
if( DhtProxy::dhtputRequestReceived(req, pfrom) ) {
|
||||||
|
// ok
|
||||||
|
} else {
|
||||||
|
pfrom->Misbehaving(20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (strCommand == "dhtgetreply")
|
||||||
|
{
|
||||||
|
CDHTGetReply reply;
|
||||||
|
vRecv >> reply;
|
||||||
|
|
||||||
|
if( DhtProxy::dhtgetReplyReceived(reply, pfrom) ) {
|
||||||
|
// ok
|
||||||
|
} else {
|
||||||
|
pfrom->Misbehaving(20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (strCommand == "nodhtproxy")
|
||||||
|
{
|
||||||
|
pfrom->fNoDhtProxy = true;
|
||||||
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -133,6 +133,7 @@ OBJS= \
|
|||||||
obj/leveldb.o \
|
obj/leveldb.o \
|
||||||
obj/txdb.o \
|
obj/txdb.o \
|
||||||
obj/chainparams.o \
|
obj/chainparams.o \
|
||||||
|
obj/dhtproxy.o \
|
||||||
obj/twister.o \
|
obj/twister.o \
|
||||||
obj/twister_rss.o \
|
obj/twister_rss.o \
|
||||||
obj/twister_utils.o
|
obj/twister_utils.o
|
||||||
|
@ -148,6 +148,7 @@ OBJS= \
|
|||||||
obj/leveldb.o \
|
obj/leveldb.o \
|
||||||
obj/txdb.o \
|
obj/txdb.o \
|
||||||
obj/chainparams.o \
|
obj/chainparams.o \
|
||||||
|
obj/dhtproxy.o \
|
||||||
obj/twister.o \
|
obj/twister.o \
|
||||||
obj/twister_rss.o \
|
obj/twister_rss.o \
|
||||||
obj/twister_utils.o
|
obj/twister_utils.o
|
||||||
|
@ -148,7 +148,9 @@ OBJS= \
|
|||||||
obj/leveldb.o \
|
obj/leveldb.o \
|
||||||
obj/txdb.o \
|
obj/txdb.o \
|
||||||
obj/chainparams.o \
|
obj/chainparams.o \
|
||||||
|
obj/dhtproxy.o \
|
||||||
obj/twister.o \
|
obj/twister.o \
|
||||||
|
obj/twister_rss.o \
|
||||||
obj/twister_utils.o
|
obj/twister_utils.o
|
||||||
|
|
||||||
ifdef USE_SSE2
|
ifdef USE_SSE2
|
||||||
|
@ -150,6 +150,7 @@ OBJS= \
|
|||||||
obj/leveldb.o \
|
obj/leveldb.o \
|
||||||
obj/txdb.o \
|
obj/txdb.o \
|
||||||
obj/chainparams.o \
|
obj/chainparams.o \
|
||||||
|
obj/dhtproxy.o \
|
||||||
obj/twister.o \
|
obj/twister.o \
|
||||||
obj/twister_rss.o \
|
obj/twister_rss.o \
|
||||||
obj/twister_utils.o
|
obj/twister_utils.o
|
||||||
|
@ -203,6 +203,7 @@ public:
|
|||||||
// b) the peer may tell us in their version message that we should not relay tx invs
|
// b) the peer may tell us in their version message that we should not relay tx invs
|
||||||
// until they have initialized their bloom filter.
|
// until they have initialized their bloom filter.
|
||||||
bool fRelayTxes;
|
bool fRelayTxes;
|
||||||
|
bool fNoDhtProxy;
|
||||||
CSemaphoreGrant grantOutbound;
|
CSemaphoreGrant grantOutbound;
|
||||||
CCriticalSection cs_filter;
|
CCriticalSection cs_filter;
|
||||||
CBloomFilter* pfilter;
|
CBloomFilter* pfilter;
|
||||||
@ -266,6 +267,7 @@ public:
|
|||||||
fGetAddr = false;
|
fGetAddr = false;
|
||||||
nMisbehavior = 0;
|
nMisbehavior = 0;
|
||||||
fRelayTxes = false;
|
fRelayTxes = false;
|
||||||
|
fNoDhtProxy = false;
|
||||||
setInventoryKnown.max_size(SendBufferSize() / 1000);
|
setInventoryKnown.max_size(SendBufferSize() / 1000);
|
||||||
pfilter = NULL;
|
pfilter = NULL;
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "twister.h"
|
#include "twister.h"
|
||||||
|
|
||||||
#include "twister_utils.h"
|
#include "twister_utils.h"
|
||||||
|
#include "dhtproxy.h"
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
@ -91,18 +92,6 @@ private:
|
|||||||
#define USER_DATA_FILE "user_data"
|
#define USER_DATA_FILE "user_data"
|
||||||
#define GLOBAL_DATA_FILE "global_data"
|
#define GLOBAL_DATA_FILE "global_data"
|
||||||
|
|
||||||
sha1_hash dhtTargetHash(std::string const &username, std::string const &resource, std::string const &type)
|
|
||||||
{
|
|
||||||
entry target;
|
|
||||||
target["n"] = username;
|
|
||||||
target["r"] = resource;
|
|
||||||
target["t"] = type;
|
|
||||||
|
|
||||||
std::vector<char> buf;
|
|
||||||
bencode(std::back_inserter(buf), target);
|
|
||||||
return hasher(buf.data(), buf.size()).final();
|
|
||||||
}
|
|
||||||
|
|
||||||
void dhtgetMapAdd(sha1_hash &ih, alert_manager *am)
|
void dhtgetMapAdd(sha1_hash &ih, alert_manager *am)
|
||||||
{
|
{
|
||||||
LOCK(cs_dhtgetMap);
|
LOCK(cs_dhtgetMap);
|
||||||
@ -337,7 +326,12 @@ void ThreadWaitExtIP()
|
|||||||
//dhts.restrict_routing_ips = false;
|
//dhts.restrict_routing_ips = false;
|
||||||
//dhts.restrict_search_ips = false;
|
//dhts.restrict_search_ips = false;
|
||||||
ses->set_dht_settings(dhts);
|
ses->set_dht_settings(dhts);
|
||||||
ses->start_dht();
|
|
||||||
|
if( !DhtProxy::fEnabled ) {
|
||||||
|
ses->start_dht();
|
||||||
|
} else {
|
||||||
|
ses->stop_dht();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session_settings settings;
|
session_settings settings;
|
||||||
@ -495,7 +489,7 @@ void ThreadMaintainDHTNodes()
|
|||||||
vNodesSize = vNodes.size();
|
vNodesSize = vNodes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !ses->is_paused() ) {
|
if( !ses->is_paused() && !DhtProxy::fEnabled ) {
|
||||||
vector<CAddress> vAddr = addrman.GetAddr();
|
vector<CAddress> vAddr = addrman.GetAddr();
|
||||||
int totalNodesCandidates = (int)(vNodesSize + vAddr.size());
|
int totalNodesCandidates = (int)(vNodesSize + vAddr.size());
|
||||||
if( ((!dht_nodes && totalNodesCandidates) ||
|
if( ((!dht_nodes && totalNodesCandidates) ||
|
||||||
@ -630,6 +624,7 @@ void ThreadSessionAlerts()
|
|||||||
t && t->type() == entry::string_t) {
|
t && t->type() == entry::string_t) {
|
||||||
sha1_hash ih = dhtTargetHash(n->string(), r->string(), t->string());
|
sha1_hash ih = dhtTargetHash(n->string(), r->string(), t->string());
|
||||||
dhtgetMapPost(ih,*rd);
|
dhtgetMapPost(ih,*rd);
|
||||||
|
DhtProxy::dhtgetPeerReqReply(ih,rd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -675,7 +670,7 @@ void ThreadSessionAlerts()
|
|||||||
t->string().c_str());
|
t->string().c_str());
|
||||||
#endif
|
#endif
|
||||||
neighborCheck[ih] = false;
|
neighborCheck[ih] = false;
|
||||||
ses->dht_getData(n->string(), r->string(), t->string() == "m");
|
dhtGetData(n->string(), r->string(), t->string() == "m");
|
||||||
} else if( neighborCheck[ih] ) {
|
} else if( neighborCheck[ih] ) {
|
||||||
sha1_hash ihStatus = dhtTargetHash(n->string(), "status", "s");
|
sha1_hash ihStatus = dhtTargetHash(n->string(), "status", "s");
|
||||||
|
|
||||||
@ -686,7 +681,7 @@ void ThreadSessionAlerts()
|
|||||||
n->string().c_str(), "status", "s");
|
n->string().c_str(), "status", "s");
|
||||||
#endif
|
#endif
|
||||||
statusCheck[ihStatus] = GetTime();
|
statusCheck[ihStatus] = GetTime();
|
||||||
ses->dht_getData(n->string(), "status", false);
|
dhtGetData(n->string(), "status", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -710,6 +705,7 @@ void ThreadSessionAlerts()
|
|||||||
if( !dd->m_got_data ) {
|
if( !dd->m_got_data ) {
|
||||||
// no data: post alert to return from wait_for_alert in dhtget()
|
// no data: post alert to return from wait_for_alert in dhtget()
|
||||||
dhtgetMapPost(ih,*dd);
|
dhtgetMapPost(ih,*dd);
|
||||||
|
DhtProxy::dhtgetPeerReqReply(ih,dd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( neighborCheck.count(ih) ) {
|
if( neighborCheck.count(ih) ) {
|
||||||
@ -721,7 +717,7 @@ void ThreadSessionAlerts()
|
|||||||
#endif
|
#endif
|
||||||
sha1_hash ihStatus = dhtTargetHash(dd->m_username, "status", "s");
|
sha1_hash ihStatus = dhtTargetHash(dd->m_username, "status", "s");
|
||||||
statusCheck[ihStatus] = GetTime();
|
statusCheck[ihStatus] = GetTime();
|
||||||
ses->dht_getData(dd->m_username, "status", false);
|
dhtGetData(dd->m_username, "status", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( statusCheck.count(ih) ) {
|
if( statusCheck.count(ih) ) {
|
||||||
@ -765,6 +761,8 @@ void startSessionTorrent(boost::thread_group& threadGroup)
|
|||||||
m_noExpireResources["following"] = NumberedNoExpire;
|
m_noExpireResources["following"] = NumberedNoExpire;
|
||||||
m_noExpireResources["status"] = SimpleNoExpire;
|
m_noExpireResources["status"] = SimpleNoExpire;
|
||||||
m_noExpireResources["post"] = PostNoExpireRecent;
|
m_noExpireResources["post"] = PostNoExpireRecent;
|
||||||
|
|
||||||
|
DhtProxy::fEnabled = GetBoolArg("-dhtproxy", false);
|
||||||
|
|
||||||
m_threadsToJoin = 0;
|
m_threadsToJoin = 0;
|
||||||
threadGroup.create_thread(boost::bind(&ThreadWaitExtIP));
|
threadGroup.create_thread(boost::bind(&ThreadWaitExtIP));
|
||||||
@ -1334,16 +1332,24 @@ entry formatSpamPost(const string &msg, const string &username, uint64_t utcTime
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dhtGetData(std::string const &username, std::string const &resource, bool multi)
|
||||||
|
{
|
||||||
|
if( DhtProxy::fEnabled ) {
|
||||||
|
printf("dhtGetData: not allowed - using proxy (bug!)\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boost::shared_ptr<session> ses(m_ses);
|
||||||
|
if( !ses ) {
|
||||||
|
printf("dhtGetData: libtorrent session not ready\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ses->dht_getData(username,resource,multi);
|
||||||
|
}
|
||||||
|
|
||||||
void dhtPutData(std::string const &username, std::string const &resource, bool multi,
|
void dhtPutData(std::string const &username, std::string const &resource, bool multi,
|
||||||
entry const &value, std::string const &sig_user,
|
entry const &value, std::string const &sig_user,
|
||||||
boost::int64_t timeutc, int seq)
|
boost::int64_t timeutc, int seq)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<session> ses(m_ses);
|
|
||||||
if( !ses ) {
|
|
||||||
printf("dhtPutData: libtorrent session not ready\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// construct p dictionary and sign it
|
// construct p dictionary and sign it
|
||||||
entry p;
|
entry p;
|
||||||
entry& target = p["target"];
|
entry& target = p["target"];
|
||||||
@ -1365,7 +1371,27 @@ void dhtPutData(std::string const &username, std::string const &resource, bool m
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ses->dht_putDataSigned(username,resource,multi,p,sig_p,sig_user, true);
|
if( !DhtProxy::fEnabled ) {
|
||||||
|
dhtPutDataSigned(username,resource,multi,p,sig_p,sig_user, true);
|
||||||
|
} else {
|
||||||
|
DhtProxy::dhtputRequest(username,resource,multi,str_p,sig_p,sig_user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dhtPutDataSigned(std::string const &username, std::string const &resource, bool multi,
|
||||||
|
libtorrent::entry const &p, std::string const &sig_p, std::string const &sig_user, bool local)
|
||||||
|
{
|
||||||
|
if( DhtProxy::fEnabled ) {
|
||||||
|
printf("dhtputDataSigned: not allowed - using proxy (bug!)\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boost::shared_ptr<session> ses(m_ses);
|
||||||
|
if( !ses ) {
|
||||||
|
printf("dhtPutData: libtorrent session not ready\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ses->dht_putDataSigned(username,resource,multi,p,sig_p,sig_user, local);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value dhtput(const Array& params, bool fHelp)
|
Value dhtput(const Array& params, bool fHelp)
|
||||||
@ -1441,9 +1467,15 @@ Value dhtget(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
alert_manager am(10, alert::dht_notification);
|
alert_manager am(10, alert::dht_notification);
|
||||||
sha1_hash ih = dhtTargetHash(strUsername,strResource,strMulti);
|
sha1_hash ih = dhtTargetHash(strUsername,strResource,strMulti);
|
||||||
dhtgetMapAdd(ih, &am);
|
|
||||||
|
vector<CNode*> dhtProxyNodes;
|
||||||
ses->dht_getData(strUsername, strResource, multi);
|
if( !DhtProxy::fEnabled ) {
|
||||||
|
dhtgetMapAdd(ih, &am);
|
||||||
|
dhtGetData(strUsername, strResource, multi);
|
||||||
|
} else {
|
||||||
|
DhtProxy::dhtgetMapAdd(ih, &am);
|
||||||
|
dhtProxyNodes = DhtProxy::dhtgetStartRequest(strUsername, strResource, multi);
|
||||||
|
}
|
||||||
|
|
||||||
Array ret;
|
Array ret;
|
||||||
std::set<std::string> uniqueSigPs;
|
std::set<std::string> uniqueSigPs;
|
||||||
@ -1488,7 +1520,12 @@ Value dhtget(const Array& params, bool fHelp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dhtgetMapRemove(ih,&am);
|
if( !DhtProxy::fEnabled ) {
|
||||||
|
dhtgetMapRemove(ih,&am);
|
||||||
|
} else {
|
||||||
|
DhtProxy::dhtgetMapRemove(ih,&am);
|
||||||
|
DhtProxy::dhtgetStopRequest(dhtProxyNodes, strUsername, strResource, multi);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
#define BLOCK_AGE_TO_EXPIRE_DHT_ENTRY (2016) // about 2 weeks
|
#define BLOCK_AGE_TO_EXPIRE_DHT_ENTRY (2016) // about 2 weeks
|
||||||
#define BLOCK_AGE_TO_EXPIRE_DHT_POSTS (4320*2) // about 2 months
|
#define BLOCK_AGE_TO_EXPIRE_DHT_POSTS (4320*2) // about 2 months
|
||||||
|
|
||||||
|
namespace libtorrent {
|
||||||
|
class entry;
|
||||||
|
}
|
||||||
|
|
||||||
class twister
|
class twister
|
||||||
{
|
{
|
||||||
@ -41,4 +44,12 @@ int getDhtNodes(boost::int64_t *dht_global_nodes = NULL);
|
|||||||
|
|
||||||
void updateSeenHashtags(std::string &message, int64_t msgTime);
|
void updateSeenHashtags(std::string &message, int64_t msgTime);
|
||||||
|
|
||||||
|
// interface to dht api of the libtorrent current session
|
||||||
|
void dhtGetData(std::string const &username, std::string const &resource, bool multi);
|
||||||
|
void dhtPutData(std::string const &username, std::string const &resource, bool multi,
|
||||||
|
libtorrent::entry const &value, std::string const &sig_user,
|
||||||
|
boost::int64_t timeutc, int seq);
|
||||||
|
void dhtPutDataSigned(std::string const &username, std::string const &resource, bool multi,
|
||||||
|
libtorrent::entry const &p, std::string const &sig_p, std::string const &sig_user, bool local);
|
||||||
|
|
||||||
#endif // TWISTER_H
|
#endif // TWISTER_H
|
||||||
|
@ -360,3 +360,16 @@ libtorrent::entry safeGetEntryDict(libtorrent::entry const &e, std::string const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sha1_hash dhtTargetHash(std::string const &username, std::string const &resource, std::string const &type)
|
||||||
|
{
|
||||||
|
entry target;
|
||||||
|
target["n"] = username;
|
||||||
|
target["r"] = resource;
|
||||||
|
target["t"] = type;
|
||||||
|
|
||||||
|
std::vector<char> buf;
|
||||||
|
bencode(std::back_inserter(buf), target);
|
||||||
|
return hasher(buf.data(), buf.size()).final();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "json/json_spirit.h"
|
#include "json/json_spirit.h"
|
||||||
#include "libtorrent/entry.hpp"
|
#include "libtorrent/entry.hpp"
|
||||||
|
#include "libtorrent/peer_id.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -48,4 +49,6 @@ std::string safeGetEntryString(libtorrent::entry const &e, std::string const& ke
|
|||||||
int safeGetEntryInt(libtorrent::entry const &e, std::string const& key);
|
int safeGetEntryInt(libtorrent::entry const &e, std::string const& key);
|
||||||
libtorrent::entry safeGetEntryDict(libtorrent::entry const &e, std::string const& key);
|
libtorrent::entry safeGetEntryDict(libtorrent::entry const &e, std::string const& key);
|
||||||
|
|
||||||
|
libtorrent::sha1_hash dhtTargetHash(std::string const &username, std::string const &resource, std::string const &type);
|
||||||
|
|
||||||
#endif // TWISTER_UTILS_H
|
#endif // TWISTER_UTILS_H
|
||||||
|
@ -25,7 +25,7 @@ extern const std::string CLIENT_DATE;
|
|||||||
// network protocol versioning
|
// network protocol versioning
|
||||||
//
|
//
|
||||||
|
|
||||||
static const int PROTOCOL_VERSION = 70002;
|
static const int PROTOCOL_VERSION = 70003;
|
||||||
|
|
||||||
// earlier versions not supported as of Feb 2012, and are disconnected
|
// earlier versions not supported as of Feb 2012, and are disconnected
|
||||||
static const int MIN_PROTO_VERSION = 209;
|
static const int MIN_PROTO_VERSION = 209;
|
||||||
@ -44,6 +44,9 @@ static const int BIP0031_VERSION = 60000;
|
|||||||
// soft checkpoint min version
|
// soft checkpoint min version
|
||||||
static const int SOFT_CHECKPOINT_VERSION = 70002;
|
static const int SOFT_CHECKPOINT_VERSION = 70002;
|
||||||
|
|
||||||
|
// dht proxy min version
|
||||||
|
static const int DHT_PROXY_VERSION = 70003;
|
||||||
|
|
||||||
// "mempool" command, enhanced "getdata" behavior starts with this version:
|
// "mempool" command, enhanced "getdata" behavior starts with this version:
|
||||||
static const int MEMPOOL_GD_VERSION = 60002;
|
static const int MEMPOOL_GD_VERSION = 60002;
|
||||||
|
|
||||||
|
@ -200,6 +200,7 @@ HEADERS += \
|
|||||||
src/limitedmap.h \
|
src/limitedmap.h \
|
||||||
src/scrypt.h \
|
src/scrypt.h \
|
||||||
src/utf8core.h \
|
src/utf8core.h \
|
||||||
|
src/dhtproxy.h \
|
||||||
src/twister.h \
|
src/twister.h \
|
||||||
src/twister_rss.h \
|
src/twister_rss.h \
|
||||||
src/twister_utils.h
|
src/twister_utils.h
|
||||||
@ -277,6 +278,7 @@ SOURCES += \ #src/qt/bitcoin.cpp \
|
|||||||
src/leveldb.cpp \
|
src/leveldb.cpp \
|
||||||
src/txdb.cpp \
|
src/txdb.cpp \
|
||||||
src/scrypt.cpp \
|
src/scrypt.cpp \
|
||||||
|
src/dhtproxy.cpp \
|
||||||
src/twister.cpp \
|
src/twister.cpp \
|
||||||
src/twister_rss.cpp \
|
src/twister_rss.cpp \
|
||||||
src/twister_utils.cpp
|
src/twister_utils.cpp
|
||||||
|
Loading…
x
Reference in New Issue
Block a user