mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Merging r4674 through r4699 from https://retroshare.svn.sourceforge.net/svnroot/retroshare/branches/v0.5-dhtmods into trunk.
Full Changes can be extracted from logs associated with the following checkins: r4674 r4678 r4679 r4680 r4681 r4684 r4686 r4687 r4697 r4698 r4699 Summary of changes: DHT Improvements: Added knowledge of Friends / FoFs and Relays to DHT. Added bdFriendList class to store this information. Added Checks against known Peer:IP information to detect bad peers. Bad Peer Checking is in Test Mode Only for the moment, New Interfaces to exchange above information with libretroshare Cleaned up various compiler warnings. libretroshare Improvements: Added p3BanList Service and DataTypes to exchange Bad Peer information. Added Plumbing to get info from network to DHT and back. Supply Friend List from p3LinkMgr Supply Friend of Friend List from p3Disc. Added p3Dsdv Service and DataTypes for NetworkWide Routing (Testing Mode). Various BugFixes. Patch Manual Forward mode to preserve user selected Port. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4700 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
commit
0d118c7033
@ -64,7 +64,7 @@ bdAccount::bdAccount()
|
||||
|
||||
void bdAccount::incCounter(uint32_t idx, bool out)
|
||||
{
|
||||
if (idx > mNoStats-1)
|
||||
if ((signed) idx > mNoStats-1)
|
||||
{
|
||||
std::cerr << "bdAccount::incCounter() Invalid Index";
|
||||
std::cerr << std::endl;
|
||||
|
@ -670,7 +670,7 @@ void bdConnectManager::iterateConnectionRequests()
|
||||
it->second.mState = BITDHT_CONNREQUEST_DONE;
|
||||
it->second.mStateTS = now;
|
||||
}
|
||||
else if (it->second.mRecycled > it->second.mGoodProxies.size() * MAX_NUM_RETRIES)
|
||||
else if ((unsigned) it->second.mRecycled > it->second.mGoodProxies.size() * MAX_NUM_RETRIES)
|
||||
{
|
||||
#ifdef DEBUG_NODE_CONNECTION
|
||||
std::cerr << "bdConnectManager::iterateConnectionAttempt() to many retries => DONE";
|
||||
|
216
libbitdht/src/bitdht/bdfriendlist.cc
Normal file
216
libbitdht/src/bitdht/bdfriendlist.cc
Normal file
@ -0,0 +1,216 @@
|
||||
|
||||
/*
|
||||
* bitdht/bdfriendlist.cc
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2011 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bitdht/bdfriendlist.h"
|
||||
#include "bitdht/bdstddht.h"
|
||||
#include "bitdht/bdpeer.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/*****
|
||||
* #define DEBUG_FRIENDLIST 1
|
||||
****/
|
||||
|
||||
bdFriendEntry::bdFriendEntry()
|
||||
{
|
||||
mFlags = 0;
|
||||
mLastSeen = 0;
|
||||
}
|
||||
|
||||
bool bdFriendEntry::addrKnown(struct sockaddr_in *addr)
|
||||
{
|
||||
if (mFlags & BD_FRIEND_ENTRY_ADDR_OK)
|
||||
{
|
||||
if (mFlags & BD_FRIEND_ENTRY_ONLINE)
|
||||
{
|
||||
*addr = mPeerId.addr;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (time(NULL) - mLastSeen < BD_FRIEND_ENTRY_TIMEOUT)
|
||||
{
|
||||
*addr = mPeerId.addr;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t bdFriendEntry::getPeerFlags()
|
||||
{
|
||||
return mFlags & BD_FRIEND_ENTRY_MASK_KNOWN;
|
||||
}
|
||||
|
||||
|
||||
bdFriendList::bdFriendList(const bdNodeId *ownId)
|
||||
{
|
||||
bdId tmpId;
|
||||
tmpId.id = *ownId;
|
||||
updatePeer(&tmpId, BD_FRIEND_ENTRY_SELF);
|
||||
}
|
||||
|
||||
/******
|
||||
* Simple logic: timestamp is set with address.
|
||||
* if ONLINE, then address will be dropped as soon as OFFLINE.
|
||||
* if ADDR_OK, then address will be dropped after XX seconds.
|
||||
*
|
||||
* ONLINE - will be used with friends.
|
||||
* ADDR_OK - will potentially be used for friends of friends (but not for now).
|
||||
*****/
|
||||
|
||||
/* catch-all interface function */
|
||||
bool bdFriendList::updatePeer(const bdId *id, uint32_t flags)
|
||||
{
|
||||
std::cerr << "bdFriendList::updatePeer() Peer(";
|
||||
bdStdPrintId(std::cerr, id);
|
||||
std::cerr << ") Flags: " << flags;
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::map<bdNodeId, bdFriendEntry>::iterator it;
|
||||
it = mPeers.find(id->id);
|
||||
if (it == mPeers.end())
|
||||
{
|
||||
bdFriendEntry entry;
|
||||
entry.mPeerId.id = id->id;
|
||||
entry.mFlags = 0;
|
||||
entry.mLastSeen = 0;
|
||||
|
||||
mPeers[id->id] = entry;
|
||||
it = mPeers.find(id->id);
|
||||
}
|
||||
|
||||
/* update all */
|
||||
it->second.mFlags = flags;
|
||||
if (it->second.mFlags & (BD_FRIEND_ENTRY_ADDR_OK | BD_FRIEND_ENTRY_ONLINE))
|
||||
{
|
||||
it->second.mFlags |= BD_FRIEND_ENTRY_ADDR_OK;
|
||||
|
||||
it->second.mPeerId.addr = id->addr;
|
||||
it->second.mLastSeen = time(NULL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bdFriendList::removePeer(const bdNodeId *id)
|
||||
{
|
||||
/* see if it exists... */
|
||||
std::map<bdNodeId, bdFriendEntry>::iterator it;
|
||||
it = mPeers.find(*id);
|
||||
if (it == mPeers.end())
|
||||
{
|
||||
std::cerr << "bdFriendList::removeFriend() Peer(";
|
||||
bdStdPrintNodeId(std::cerr, id);
|
||||
std::cerr << ") is unknown!";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
mPeers.erase(*id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bdFriendList::findPeerEntry(const bdNodeId *id, bdFriendEntry &entry)
|
||||
{
|
||||
/* see if it exists... */
|
||||
std::map<bdNodeId, bdFriendEntry>::iterator it;
|
||||
it = mPeers.find(*id);
|
||||
if (it == mPeers.end())
|
||||
{
|
||||
#ifdef DEBUG_FRIENDLIST
|
||||
std::cerr << "bdFriendList::getPeerEntry() Peer(";
|
||||
bdStdPrintNodeId(std::cerr, id);
|
||||
std::cerr << ") is unknown!";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
entry = it->second;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool bdFriendList::print(std::ostream &out)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
out << "bdFriendList::print()";
|
||||
out << std::endl;
|
||||
|
||||
std::map<bdNodeId, bdFriendEntry>::iterator it;
|
||||
for(it = mPeers.begin(); it != mPeers.end(); it++)
|
||||
{
|
||||
bdStdPrintId(out, &(it->second.mPeerId));
|
||||
out << " Flags: " << it->second.mFlags;
|
||||
out << " Seen: " << now - it->second.mLastSeen;
|
||||
out << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bdPeerQueue::bdPeerQueue()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool bdPeerQueue::queuePeer(const bdId *id, uint32_t flags)
|
||||
{
|
||||
bdFriendEntry entry;
|
||||
entry.mPeerId = *id;
|
||||
entry.mFlags = flags;
|
||||
entry.mLastSeen = time(NULL);
|
||||
|
||||
mPeerQueue.push_back(entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bdPeerQueue::popPeer(bdId *id, uint32_t &flags)
|
||||
{
|
||||
if (mPeerQueue.size() > 0)
|
||||
{
|
||||
bdFriendEntry entry = mPeerQueue.front();
|
||||
mPeerQueue.pop_front();
|
||||
*id = entry.mPeerId;
|
||||
flags = entry.mFlags;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
103
libbitdht/src/bitdht/bdfriendlist.h
Normal file
103
libbitdht/src/bitdht/bdfriendlist.h
Normal file
@ -0,0 +1,103 @@
|
||||
#ifndef BITDHT_FRIEND_LIST_H
|
||||
#define BITDHT_FRIEND_LIST_H
|
||||
|
||||
/*
|
||||
* bitdht/bdfriendlist.h
|
||||
*
|
||||
* BitDHT: An Flexible DHT library.
|
||||
*
|
||||
* Copyright 2011 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 3 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "bitdht@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This class maintains a list of current friends and friends-of-friends.
|
||||
* It should also be updated when a peer's address has been identified.
|
||||
*
|
||||
* It is used for selecting preferential peers for DHT Connections.
|
||||
* and for detecting bad peers that are duplicating real RS peers.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "bitdht/bdiface.h"
|
||||
#include <set>
|
||||
|
||||
#define BD_FRIEND_ENTRY_TIMEOUT 10
|
||||
|
||||
|
||||
//#define BD_FRIEND_ENTRY_ONLINE 0x0001
|
||||
//#define BD_FRIEND_ENTRY_ADDR_OK 0x0002
|
||||
|
||||
//#define BD_FRIEND_ENTRY_WHITELIST BITDHT_PEER_STATUS_DHT_WHITELIST
|
||||
//#define BD_FRIEND_ENTRY_FOF BITDHT_PEER_STATUS_DHT_FOF
|
||||
//#define BD_FRIEND_ENTRY_FRIEND BITDHT_PEER_STATUS_DHT_FRIEND
|
||||
//#define BD_FRIEND_ENTRY_RELAY_SERVER BITDHT_PEER_STATUS_DHT_RELAY_SERVER
|
||||
|
||||
//#define BD_FRIEND_ENTRY_SELF BITDHT_PEER_STATUS_DHT_SELF
|
||||
|
||||
//#define BD_FRIEND_ENTRY_MASK_KNOWN BITDHT_PEER_STATUS_MASK_KNOWN
|
||||
|
||||
class bdFriendEntry
|
||||
{
|
||||
public:
|
||||
bdFriendEntry();
|
||||
|
||||
bool addrKnown(struct sockaddr_in *addr);
|
||||
uint32_t getPeerFlags();
|
||||
|
||||
bdId mPeerId;
|
||||
uint32_t mFlags;
|
||||
time_t mLastSeen;
|
||||
};
|
||||
|
||||
class bdFriendList
|
||||
{
|
||||
|
||||
public:
|
||||
bdFriendList(const bdNodeId *ownid);
|
||||
|
||||
bool updatePeer(const bdId *id, uint32_t flags);
|
||||
bool removePeer(const bdNodeId *id);
|
||||
|
||||
bool findPeerEntry(const bdNodeId *id, bdFriendEntry &entry);
|
||||
|
||||
bool print(std::ostream &out);
|
||||
private:
|
||||
|
||||
std::map<bdNodeId, bdFriendEntry> mPeers;
|
||||
};
|
||||
|
||||
class bdPeerQueue
|
||||
{
|
||||
|
||||
public:
|
||||
bdPeerQueue();
|
||||
|
||||
bool queuePeer(const bdId *id, uint32_t flags);
|
||||
bool popPeer(bdId *id, uint32_t &flags);
|
||||
|
||||
private:
|
||||
|
||||
std::list<bdFriendEntry> mPeerQueue;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -109,7 +109,7 @@ virtual void bdPrintNodeId(std::ostream &out, const bdNodeId *a) = 0;
|
||||
|
||||
/* NODE OPTIONS */
|
||||
#define BITDHT_OPTIONS_MAINTAIN_UNSTABLE_PORT 0x00000001
|
||||
|
||||
#define BITDHT_OPTIONS_ENABLE_RELAYS 0x00000002
|
||||
|
||||
|
||||
/* peer flags
|
||||
@ -143,13 +143,15 @@ virtual void bdPrintNodeId(std::ostream &out, const bdNodeId *a) = 0;
|
||||
#define BITDHT_PEER_STATUS_DHT_WHITELIST 0x00010000
|
||||
#define BITDHT_PEER_STATUS_DHT_FOF 0x00020000
|
||||
#define BITDHT_PEER_STATUS_DHT_FRIEND 0x00040000
|
||||
#define BITDHT_PEER_STATUS_DHT_RELAY_SERVER 0x00080000 // (Flag must be enabled)
|
||||
#define BITDHT_PEER_STATUS_DHT_SELF 0x00100000
|
||||
|
||||
|
||||
// EXTRA FLAGS are our internal thoughts about the peer.
|
||||
#define BITDHT_PEER_EXFLAG_MASK_BASIC 0x000000ff
|
||||
#define BITDHT_PEER_EXFLAG_UNSTABLE 0x00000001 // Port changes.
|
||||
#define BITDHT_PEER_EXFLAG_ATTACHED 0x00000002 // We will ping in heavily. (if unstable)
|
||||
|
||||
#define BITDHT_PEER_EXFLAG_BADPEER 0x00000004 // For testing, we flag rather than discard.
|
||||
|
||||
|
||||
|
||||
@ -198,6 +200,20 @@ virtual void bdPrintNodeId(std::ostream &out, const bdNodeId *a) = 0;
|
||||
#define BITDHT_CONNECT_ERROR_USER 0x0000000d
|
||||
|
||||
|
||||
/*************/
|
||||
// FRIEND_ENTRY_FLAGS... used by updateKnownPeers().
|
||||
|
||||
#define BD_FRIEND_ENTRY_ONLINE 0x0001
|
||||
#define BD_FRIEND_ENTRY_ADDR_OK 0x0002
|
||||
|
||||
#define BD_FRIEND_ENTRY_WHITELIST BITDHT_PEER_STATUS_DHT_WHITELIST
|
||||
#define BD_FRIEND_ENTRY_FOF BITDHT_PEER_STATUS_DHT_FOF
|
||||
#define BD_FRIEND_ENTRY_FRIEND BITDHT_PEER_STATUS_DHT_FRIEND
|
||||
#define BD_FRIEND_ENTRY_RELAY_SERVER BITDHT_PEER_STATUS_DHT_RELAY_SERVER
|
||||
|
||||
#define BD_FRIEND_ENTRY_SELF BITDHT_PEER_STATUS_DHT_SELF
|
||||
|
||||
#define BD_FRIEND_ENTRY_MASK_KNOWN BITDHT_PEER_STATUS_MASK_KNOWN
|
||||
|
||||
|
||||
|
||||
@ -288,6 +304,8 @@ class bdQuerySummary
|
||||
#define BD_PROXY_CONNECTION_MID_POINT 2
|
||||
#define BD_PROXY_CONNECTION_END_POINT 3
|
||||
|
||||
#define BITDHT_INFO_CB_TYPE_BADPEER 1
|
||||
|
||||
class BitDhtCallback
|
||||
{
|
||||
public:
|
||||
@ -304,6 +322,9 @@ virtual int dhtValueCallback(const bdNodeId *id, std::string key, uint32_t statu
|
||||
virtual int dhtConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId *destId,
|
||||
uint32_t mode, uint32_t point, uint32_t param, uint32_t cbtype, uint32_t errcode) = 0; /* { return 0; } */
|
||||
|
||||
// Generic Info callback - initially will be used to provide bad peers.
|
||||
virtual int dhtInfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::string info) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -311,6 +332,12 @@ class BitDhtInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/* bad peer notification */
|
||||
virtual void addBadPeer(const struct sockaddr_in &addr, uint32_t source, uint32_t reason, uint32_t age) = 0;
|
||||
|
||||
/* Friend Tracking */
|
||||
virtual void updateKnownPeer(const bdId *id, uint32_t type, uint32_t flags) = 0;
|
||||
|
||||
/***** Request Lookup (DHT Peer & Keyword) *****/
|
||||
virtual void addFindNode(bdNodeId *id, uint32_t mode) = 0;
|
||||
virtual void removeFindNode(bdNodeId *id) = 0;
|
||||
|
@ -157,8 +157,17 @@ bool bdNodeManager::setAttachMode(bool on)
|
||||
return on;
|
||||
}
|
||||
|
||||
/* Friend Tracking */
|
||||
void bdNodeManager::addBadPeer(const struct sockaddr_in &addr, uint32_t source, uint32_t reason, uint32_t age)
|
||||
{
|
||||
std::cerr << "bdNodeManager::addBadPeer() not implemented yet!";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void bdNodeManager::updateKnownPeer(const bdId *id, uint32_t /* type */, uint32_t flags)
|
||||
{
|
||||
mFriendList.updatePeer(id, flags);
|
||||
}
|
||||
|
||||
void bdNodeManager::addFindNode(bdNodeId *id, uint32_t qflags)
|
||||
{
|
||||
@ -621,6 +630,7 @@ int bdNodeManager::status()
|
||||
#endif
|
||||
|
||||
checkStatus();
|
||||
checkBadPeerStatus();
|
||||
|
||||
/* update the network numbers */
|
||||
mNetworkSize = mNodeSpace.calcNetworkSize();
|
||||
@ -924,6 +934,18 @@ bdNodeManager::checkPingStatus()
|
||||
}
|
||||
#endif
|
||||
|
||||
int bdNodeManager::checkBadPeerStatus()
|
||||
{
|
||||
bdId id;
|
||||
uint32_t flags;
|
||||
std::string nullstr;
|
||||
|
||||
while(mBadPeerQueue.popPeer(&id, flags))
|
||||
{
|
||||
doInfoCallback(&id, BITDHT_INFO_CB_TYPE_BADPEER, flags, nullstr);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bdNodeManager::SearchOutOfDate()
|
||||
{
|
||||
@ -1138,6 +1160,23 @@ void bdNodeManager::doValueCallback(const bdNodeId *id, std::string key, uint32_
|
||||
}
|
||||
|
||||
|
||||
void bdNodeManager::doInfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::string info)
|
||||
{
|
||||
std::cerr << "bdNodeManager::doInfoCallback()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
#ifdef DEBUG_MGR
|
||||
#endif
|
||||
/* search list */
|
||||
std::list<BitDhtCallback *>::iterator it;
|
||||
for(it = mCallbacks.begin(); it != mCallbacks.end(); it++)
|
||||
{
|
||||
(*it)->dhtInfoCallback(id, type, flags, info);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#define BITDHT_IDENTITY_STRING_V1 "d1:"
|
||||
#define BITDHT_IDENTITY_SIZE_V1 3
|
||||
#define BITDHT_PACKET_MIN_SIZE 4
|
||||
|
@ -102,6 +102,12 @@ class bdNodeManager: public bdNode, public BitDhtInterface
|
||||
void iteration();
|
||||
|
||||
/***** Functions to Call down to bdNodeManager ****/
|
||||
|
||||
|
||||
/* Friend Tracking */
|
||||
virtual void addBadPeer(const struct sockaddr_in &addr, uint32_t source, uint32_t reason, uint32_t age);
|
||||
virtual void updateKnownPeer(const bdId *id, uint32_t type, uint32_t flags);
|
||||
|
||||
/* Request DHT Peer Lookup */
|
||||
/* Request Keyword Lookup */
|
||||
virtual void addFindNode(bdNodeId *id, uint32_t mode);
|
||||
@ -149,10 +155,12 @@ int isBitDhtPacket(char *data, int size, struct sockaddr_in &from);
|
||||
void doNodeCallback(const bdId *id, uint32_t peerflags);
|
||||
void doPeerCallback(const bdId *id, uint32_t status);
|
||||
void doValueCallback(const bdNodeId *id, std::string key, uint32_t status);
|
||||
void doInfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::string info);
|
||||
|
||||
int status();
|
||||
int checkStatus();
|
||||
int checkPingStatus();
|
||||
int checkBadPeerStatus();
|
||||
int SearchOutOfDate();
|
||||
void startQueries();
|
||||
|
||||
|
@ -66,7 +66,7 @@
|
||||
|
||||
|
||||
bdNode::bdNode(bdNodeId *ownId, std::string dhtVersion, std::string bootfile, bdDhtFunctions *fns)
|
||||
:mNodeSpace(ownId, fns), mQueryMgr(NULL), mConnMgr(NULL), mFilterPeers(NULL), mOwnId(*ownId), mDhtVersion(dhtVersion), mStore(bootfile, fns), mFns(fns)
|
||||
:mNodeSpace(ownId, fns), mQueryMgr(NULL), mConnMgr(NULL), mFilterPeers(NULL), mOwnId(*ownId), mDhtVersion(dhtVersion), mStore(bootfile, fns), mFns(fns), mFriendList(ownId)
|
||||
{
|
||||
|
||||
init(); /* (uses this pointers) stuff it - do it here! */
|
||||
@ -88,7 +88,7 @@ void bdNode::init()
|
||||
#define ATTACH_NUMBER 5
|
||||
void bdNode::setNodeOptions(uint32_t optFlags)
|
||||
{
|
||||
mNodeOptionFlags = optFlags;
|
||||
mNodeOptionFlags = optFlags;
|
||||
if (optFlags & BITDHT_OPTIONS_MAINTAIN_UNSTABLE_PORT)
|
||||
{
|
||||
mNodeSpace.setAttachedFlag(BITDHT_PEER_STATUS_DHT_ENGINE | BITDHT_PEER_STATUS_DHT_ENGINE_VERSION, ATTACH_NUMBER);
|
||||
@ -392,9 +392,63 @@ void bdNode::send_connect_msg(bdId *id, int msgtype, bdId *srcAddr, bdId *destAd
|
||||
|
||||
|
||||
|
||||
#define TEST_BAD_PEER 1
|
||||
|
||||
void bdNode::checkPotentialPeer(bdId *id, bdId *src)
|
||||
{
|
||||
/* Check BadPeer Filters for Potential Peers too */
|
||||
|
||||
/* first check the filters */
|
||||
if (!mFilterPeers->addrOkay(&(id->addr)))
|
||||
{
|
||||
std::cerr << "bdNode::checkPotentialPeer(";
|
||||
mFns->bdPrintId(std::cerr, id);
|
||||
std::cerr << ") BAD ADDRESS!!!! SHOULD DISCARD POTENTIAL PEER";
|
||||
std::cerr << std::endl;
|
||||
|
||||
#ifdef TEST_BAD_PEER
|
||||
std::cerr << "IN TEST MODE... so letting it through.";
|
||||
std::cerr << std::endl;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* is it masquarading? */
|
||||
bdFriendEntry entry;
|
||||
if (mFriendList.findPeerEntry(&(id->id), entry))
|
||||
{
|
||||
struct sockaddr_in knownAddr;
|
||||
if (entry.addrKnown(&knownAddr))
|
||||
{
|
||||
if (knownAddr.sin_addr.s_addr != id->addr.sin_addr.s_addr)
|
||||
{
|
||||
std::cerr << "bdNode::checkPotentialPeer(";
|
||||
mFns->bdPrintId(std::cerr, id);
|
||||
std::cerr << ") MASQARADING AS KNOWN PEER - FLAGGING AS BAD";
|
||||
std::cerr << std::endl;
|
||||
|
||||
#ifdef TEST_BAD_PEER
|
||||
std::cerr << "IN TEST MODE... Notifying, but letting it through.";
|
||||
std::cerr << std::endl;
|
||||
|
||||
mBadPeerQueue.queuePeer(id, 0);
|
||||
#else
|
||||
|
||||
mFilterPeers->addBadPeer(id, 0);
|
||||
// Stores in queue for later callback and desemination around the network.
|
||||
mBadPeerQueue.queuePeer(id, 0);
|
||||
|
||||
std::list<struct sockaddr_in> filteredIPs;
|
||||
mFilterPeers->filteredIPs(filteredIPs);
|
||||
mStore.filterIpList(filteredIPs);
|
||||
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isWorthyPeer = mQueryMgr->checkPotentialPeer(id, src);
|
||||
|
||||
if (isWorthyPeer)
|
||||
@ -445,9 +499,66 @@ void bdNode::addPeer(const bdId *id, uint32_t peerflags)
|
||||
return;
|
||||
}
|
||||
|
||||
// NB: TODO CLEANUP THIS CODE - ONCE LOGIC IS TESTED!
|
||||
|
||||
/* next we check if it is a friend, whitelist etc, and adjust flags */
|
||||
bdFriendEntry entry;
|
||||
|
||||
#ifdef TEST_BAD_PEER
|
||||
bool peerBad = false;
|
||||
#endif
|
||||
if (mFriendList.findPeerEntry(&(id->id), entry))
|
||||
{
|
||||
/* found! */
|
||||
peerflags |= entry.getPeerFlags(); // translates internal into general ones.
|
||||
|
||||
struct sockaddr_in knownAddr;
|
||||
if (entry.addrKnown(&knownAddr))
|
||||
{
|
||||
if (knownAddr.sin_addr.s_addr != id->addr.sin_addr.s_addr)
|
||||
{
|
||||
std::cerr << "bdNode::addPeer(";
|
||||
mFns->bdPrintId(std::cerr, id);
|
||||
std::cerr << ", " << std::hex << peerflags << std::dec;
|
||||
std::cerr << ") MASQARADING AS KNOWN PEER - FLAGGING AS BAD";
|
||||
std::cerr << std::endl;
|
||||
|
||||
#ifdef TEST_BAD_PEER
|
||||
peerBad = true;
|
||||
#else
|
||||
mFilterPeers->addBadPeer(id, peerflags);
|
||||
// Stores in queue for later callback and desemination around the network.
|
||||
mBadPeerList->queuePeer(id, peerflags);
|
||||
|
||||
std::list<struct sockaddr_in> filteredIPs;
|
||||
mFilterPeers->filteredIPs(filteredIPs);
|
||||
mStore.filterIpList(filteredIPs);
|
||||
|
||||
// DO WE EXPLICITLY NEED TO DO THIS, OR WILL THEY JUST BE DROPPED?
|
||||
//mNodeSpace.remove_badpeer(id);
|
||||
//mQueryMgr->remove_badpeer(id);
|
||||
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mQueryMgr->addPeer(id, peerflags);
|
||||
mNodeSpace.add_peer(id, peerflags);
|
||||
|
||||
#ifdef TEST_BAD_PEER
|
||||
// NOTE: We will push bad peers to Query in the testing case.
|
||||
// This allows us to test the multiple solutions... as well.
|
||||
// In normal behaviour - they will just get stripped and never added.
|
||||
if (peerBad)
|
||||
{
|
||||
mNodeSpace.flagpeer(id, 0, BITDHT_PEER_EXFLAG_BADPEER);
|
||||
//mQueryMgr->flag_badpeer(id);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bdPeer peer;
|
||||
peer.mPeerId = *id;
|
||||
peer.mPeerFlags = peerflags;
|
||||
@ -1529,7 +1640,7 @@ void bdNode::msgin_pong(bdId *id, bdToken *transId, bdToken *versionId)
|
||||
{
|
||||
sameDhtVersion = false;
|
||||
std::cerr << "bdNode::msgin_pong() STRANGE Peer Version: ";
|
||||
for(int i = 0; i < versionId->len; i++)
|
||||
for(uint32_t i = 0; i < versionId->len; i++)
|
||||
{
|
||||
std::cerr << versionId->data[i];
|
||||
}
|
||||
|
@ -37,6 +37,8 @@
|
||||
#include "bitdht/bdconnection.h"
|
||||
#include "bitdht/bdaccount.h"
|
||||
|
||||
#include "bitdht/bdfriendlist.h"
|
||||
|
||||
class bdFilter;
|
||||
|
||||
|
||||
@ -241,6 +243,9 @@ void recvPkt(char *msg, int len, struct sockaddr_in addr);
|
||||
bdDhtFunctions *mFns;
|
||||
bdHashSpace mHashSpace;
|
||||
|
||||
bdFriendList mFriendList;
|
||||
bdPeerQueue mBadPeerQueue;
|
||||
|
||||
private:
|
||||
|
||||
uint32_t mNodeOptionFlags;
|
||||
|
@ -444,7 +444,7 @@ int bdSpace::scanOutOfDatePeers(std::list<bdId> &peerIds)
|
||||
*
|
||||
*/
|
||||
bool doAttached = (mAttachedCount > 0);
|
||||
int attachedCount = 0;
|
||||
uint32_t attachedCount = 0;
|
||||
|
||||
std::map<bdMetric, bdId> closest;
|
||||
std::map<bdMetric, bdId>::iterator mit;
|
||||
@ -538,13 +538,20 @@ int bdSpace::scanOutOfDatePeers(std::list<bdId> &peerIds)
|
||||
}
|
||||
|
||||
|
||||
/* Attached should be changed to preferentially choose the ones we want
|
||||
* If we have RELAYS enabled - then we want them to attach to the RELAYS
|
||||
* Not sure about this yet!
|
||||
*
|
||||
* Have to think about it a bit more. (and redesign code to handle multiple passes)
|
||||
*/
|
||||
|
||||
int bdSpace::updateAttachedPeers()
|
||||
{
|
||||
/*
|
||||
*
|
||||
*/
|
||||
bool doAttached = (mAttachedCount > 0);
|
||||
int attachedCount = 0;
|
||||
uint32_t attachedCount = 0;
|
||||
|
||||
// Must scan through - otherwise we can never remove Attached state.
|
||||
// It is only once every 10 minutes or so!
|
||||
@ -762,7 +769,48 @@ int bdSpace::add_peer(const bdId *id, uint32_t peerflags)
|
||||
return add;
|
||||
}
|
||||
|
||||
/* flag peer */
|
||||
bool bdSpace::flagpeer(const bdId *id, uint32_t flags, uint32_t ex_flags)
|
||||
{
|
||||
#ifdef DEBUG_BD_SPACE
|
||||
fprintf(stderr, "bdSpace::flagpeer()\n");
|
||||
#endif
|
||||
|
||||
/* calculate metric */
|
||||
bdMetric met;
|
||||
mFns->bdDistance(&(mOwnId), &(id->id), &met);
|
||||
int bucket = mFns->bdBucketDistance(&met);
|
||||
|
||||
|
||||
/* select correct bucket */
|
||||
bdBucket &buck = buckets[bucket];
|
||||
|
||||
/* loop through ids, to find it */
|
||||
std::list<bdPeer>::iterator it;
|
||||
for(it = buck.entries.begin(); it != buck.entries.end(); it++)
|
||||
{
|
||||
/* similar id check */
|
||||
if (mFns->bdSimilarId(id, &(it->mPeerId)))
|
||||
{
|
||||
#ifdef DEBUG_BD_SPACE
|
||||
fprintf(stderr, "peer:");
|
||||
mFns->bdPrintId(std::cerr, id);
|
||||
fprintf(stderr, " bucket: %d", bucket);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Original Flags: %x Extra: %x\n",
|
||||
it->mPeerFlags, it->mExtraFlags);
|
||||
#endif
|
||||
it->mPeerFlags |= flags;
|
||||
it->mExtraFlags |= ex_flags;
|
||||
|
||||
#ifdef DEBUG_BD_SPACE
|
||||
fprintf(stderr, "Updated Flags: %x Extra: %x\n",
|
||||
it->mPeerFlags, it->mExtraFlags);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* print tables.
|
||||
*/
|
||||
|
@ -193,6 +193,9 @@ bool findRandomPeerWithFlag(bdId &id, uint32_t withFlag);
|
||||
/* to add later */
|
||||
int updateOwnId(bdNodeId *newOwnId);
|
||||
|
||||
/* flag peer */
|
||||
bool flagpeer(const bdId *id, uint32_t flags, uint32_t ex_flags);
|
||||
|
||||
private:
|
||||
|
||||
std::vector<bdBucket> buckets;
|
||||
|
@ -141,7 +141,7 @@ void bdStdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *m
|
||||
int bdStdLoadNodeId(bdNodeId *id, std::string input)
|
||||
{
|
||||
uint8_t *a_data = (uint8_t *) id->data;
|
||||
int reqlen = BITDHT_KEY_LEN * 2;
|
||||
uint32_t reqlen = BITDHT_KEY_LEN * 2;
|
||||
if (input.size() < reqlen)
|
||||
{
|
||||
return 0;
|
||||
|
@ -109,6 +109,7 @@ HEADERS += \
|
||||
bitdht/bdaccount.h \
|
||||
bitdht/bdquerymgr.h \
|
||||
util/bdbloom.h \
|
||||
bitdht/bdfriendlist.h \
|
||||
|
||||
SOURCES += \
|
||||
bitdht/bencode.c \
|
||||
@ -133,5 +134,6 @@ SOURCES += \
|
||||
bitdht/bdaccount.cc \
|
||||
bitdht/bdquerymgr.cc \
|
||||
util/bdbloom.cc \
|
||||
bitdht/bdfriendlist.cc \
|
||||
|
||||
|
||||
|
@ -88,6 +88,22 @@ UdpBitDht::~UdpBitDht()
|
||||
/*********** External Interface to the World ************/
|
||||
|
||||
/***** Functions to Call down to bdNodeManager ****/
|
||||
/* Friend Tracking */
|
||||
void UdpBitDht::addBadPeer(const struct sockaddr_in &addr, uint32_t source, uint32_t reason, uint32_t age)
|
||||
{
|
||||
bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/
|
||||
|
||||
mBitDhtManager->addBadPeer(addr, source, reason, age);
|
||||
}
|
||||
|
||||
|
||||
void UdpBitDht::updateKnownPeer(const bdId *id, uint32_t type, uint32_t flags)
|
||||
{
|
||||
bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/
|
||||
|
||||
mBitDhtManager->updateKnownPeer(id, type, flags);
|
||||
}
|
||||
|
||||
/* Request DHT Peer Lookup */
|
||||
/* Request Keyword Lookup */
|
||||
void UdpBitDht::addFindNode(bdNodeId *id, uint32_t mode)
|
||||
|
@ -57,6 +57,11 @@ virtual ~UdpBitDht();
|
||||
/*********** External Interface to the World (BitDhtInterface) ************/
|
||||
|
||||
/***** Functions to Call down to bdNodeManager ****/
|
||||
|
||||
/* Friend Tracking */
|
||||
virtual void addBadPeer(const struct sockaddr_in &addr, uint32_t source, uint32_t reason, uint32_t age);
|
||||
virtual void updateKnownPeer(const bdId *id, uint32_t type, uint32_t flags);
|
||||
|
||||
/* Request DHT Peer Lookup */
|
||||
/* Request Keyword Lookup */
|
||||
virtual void addFindNode(bdNodeId *id, uint32_t mode);
|
||||
|
@ -87,7 +87,7 @@ uint8_t convertCharToUint8(char ch1, char ch2)
|
||||
|
||||
int bloomFilter::setFilterBits(const std::string &hex)
|
||||
{
|
||||
int bytes = (mFilterBits / BITS_PER_BYTE);
|
||||
uint32_t bytes = (mFilterBits / BITS_PER_BYTE);
|
||||
if (mFilterBits % BITS_PER_BYTE)
|
||||
{
|
||||
bytes++;
|
||||
@ -100,7 +100,7 @@ int bloomFilter::setFilterBits(const std::string &hex)
|
||||
|
||||
// convert to binary array.
|
||||
uint8_t *tmparray = (uint8_t *) malloc(bytes);
|
||||
int i = 0;
|
||||
uint32_t i = 0;
|
||||
|
||||
for(i = 0; i < bytes; i++)
|
||||
{
|
||||
@ -186,7 +186,7 @@ uint32_t bloomFilter::filterBits()
|
||||
uint32_t bloomFilter::countBits()
|
||||
{
|
||||
int count = 0;
|
||||
int i;
|
||||
uint32_t i;
|
||||
for(i = 0; i < mFilterBits; i++)
|
||||
{
|
||||
if (mBits[i])
|
||||
@ -206,7 +206,7 @@ void bloomFilter::printFilter(std::ostream &out)
|
||||
out << std::endl;
|
||||
|
||||
out << "BITS: ";
|
||||
int i;
|
||||
uint32_t i;
|
||||
for(i = 0; i < mFilterBits; i++)
|
||||
{
|
||||
if ((i > 0) && (i % 32 == 0))
|
||||
@ -236,7 +236,7 @@ void bloomFilter::setHashFunction(int idx, uint32_t (*hashfn)(const std::string
|
||||
void bloomFilter::add(const std::string &hex)
|
||||
{
|
||||
uint32_t (*hashfn)(const std::string &);
|
||||
int i;
|
||||
uint32_t i;
|
||||
for(i = 0; i < mNoHashs; i++)
|
||||
{
|
||||
hashfn = mHashFns[i];
|
||||
@ -253,7 +253,7 @@ void bloomFilter::add(const std::string &hex)
|
||||
bool bloomFilter::test(const std::string &hex)
|
||||
{
|
||||
uint32_t (*hashfn)(const std::string &);
|
||||
int i;
|
||||
uint32_t i;
|
||||
for(i = 0; i < mNoHashs; i++)
|
||||
{
|
||||
hashfn = mHashFns[i];
|
||||
|
@ -70,6 +70,11 @@ virtual int dhtConnectCallback(const bdId *srcId, const bdId *proxyId, const bdI
|
||||
return mParent->ConnectCallback(srcId, proxyId, destId, mode, point, param, cbtype, errcode);
|
||||
}
|
||||
|
||||
virtual int dhtInfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::string info)
|
||||
{
|
||||
return mParent->InfoCallback(id, type, flags, info);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
p3BitDht *mParent;
|
||||
@ -84,6 +89,8 @@ p3BitDht::p3BitDht(std::string id, pqiConnectCb *cb, p3NetMgr *nm,
|
||||
mProxyStunner = NULL;
|
||||
mRelay = NULL;
|
||||
|
||||
mPeerSharer = NULL;
|
||||
|
||||
std::string dhtVersion = "RS51"; // should come from elsewhere!
|
||||
mOwnRsId = id;
|
||||
|
||||
@ -150,6 +157,10 @@ void p3BitDht::setupConnectBits(UdpStunner *dhtStunner, UdpStunner *proxyStun
|
||||
mRelay = relay;
|
||||
}
|
||||
|
||||
void p3BitDht::setupPeerSharer(pqiNetAssistPeerShare *sharer)
|
||||
{
|
||||
mPeerSharer = sharer;
|
||||
}
|
||||
|
||||
void p3BitDht::start()
|
||||
{
|
||||
|
@ -155,8 +155,7 @@ virtual std::string getUdpAddressString();
|
||||
|
||||
|
||||
void setupConnectBits(UdpStunner *dhtStunner, UdpStunner *proxyStunner, UdpRelayReceiver *relay);
|
||||
|
||||
|
||||
void setupPeerSharer(pqiNetAssistPeerShare *sharer);
|
||||
|
||||
|
||||
void start(); /* starts up the bitdht thread */
|
||||
@ -177,9 +176,11 @@ virtual bool getNetworkStats(uint32_t &netsize, uint32_t &localnetsize);
|
||||
virtual bool findPeer(std::string id);
|
||||
virtual bool dropPeer(std::string id);
|
||||
|
||||
virtual int addFriend(const std::string pid);
|
||||
virtual int addFriendOfFriend(const std::string pid);
|
||||
virtual int addOther(const std::string pid);
|
||||
virtual int addBadPeer(const struct sockaddr_in &addr, uint32_t reason, uint32_t flags, uint32_t age);
|
||||
virtual int addKnownPeer(const std::string &pid, const struct sockaddr_in &addr, uint32_t flags);
|
||||
//virtual int addFriend(const std::string pid);
|
||||
//virtual int addFriendOfFriend(const std::string pid);
|
||||
//virtual int addOther(const std::string pid);
|
||||
|
||||
/* feedback on success failure of Connections */
|
||||
virtual void ConnectionFeedback(std::string pid, int state);
|
||||
@ -218,6 +219,8 @@ int PeerCallback(const bdId *id, uint32_t status);
|
||||
int ValueCallback(const bdNodeId *id, std::string key, uint32_t status);
|
||||
int ConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId *destId,
|
||||
uint32_t mode, uint32_t point, uint32_t param, uint32_t cbtype, uint32_t errcode);
|
||||
int InfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::string info);
|
||||
|
||||
|
||||
int OnlinePeerCallback_locked(const bdId *id, uint32_t status, DhtPeerDetails *dpd);
|
||||
int UnreachablePeerCallback_locked(const bdId *id, uint32_t status, DhtPeerDetails *dpd);
|
||||
@ -282,6 +285,8 @@ int calculateNodeId(const std::string pid, bdNodeId *id);
|
||||
|
||||
p3NetMgr *mNetMgr;
|
||||
|
||||
pqiNetAssistPeerShare *mPeerSharer;
|
||||
|
||||
RsMutex dhtMtx;
|
||||
|
||||
std::string mOwnRsId;
|
||||
|
@ -37,6 +37,50 @@
|
||||
************************************* Dht Callback ***************************************
|
||||
******************************************************************************************/
|
||||
|
||||
/**** dht NodeCallback ****
|
||||
*
|
||||
*
|
||||
* In the old version, we used this to callback mConnCb->peerStatus()
|
||||
* We might want to drop this, and concentrate on the connection stuff.
|
||||
*
|
||||
* -> if an new dht peer, then pass to Stunners.
|
||||
* -> do we care if we know them? not really!
|
||||
*/
|
||||
|
||||
int p3BitDht::InfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::string info)
|
||||
{
|
||||
/* translate info */
|
||||
std::string rsid;
|
||||
struct sockaddr_in addr = id->addr;
|
||||
int outtype = PNASS_TYPE_BADPEER;
|
||||
int outreason = PNASS_REASON_UNKNOWN;
|
||||
int outage = 0;
|
||||
|
||||
#ifdef DEBUG_BITDHT_COMMON
|
||||
std::cerr << "p3BitDht::InfoCallback() likely BAD_PEER: ";
|
||||
bdStdPrintId(std::cerr, id);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
{
|
||||
RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/
|
||||
|
||||
DhtPeerDetails *dpd = findInternalDhtPeer_locked(&(id->id), RSDHT_PEERTYPE_ANY);
|
||||
|
||||
if (dpd)
|
||||
{
|
||||
rsid = dpd->mRsId;
|
||||
}
|
||||
}
|
||||
|
||||
if (mPeerSharer)
|
||||
{
|
||||
mPeerSharer->updatePeer(rsid, addr, outtype, outreason, outage);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**** dht NodeCallback ****
|
||||
*
|
||||
|
@ -60,67 +60,73 @@ bool p3BitDht::findPeer(std::string pid)
|
||||
std::cerr << "p3BitDht::findPeer(" << pid << ")";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
bdNodeId nid;
|
||||
|
||||
DhtPeerDetails *dpd = findInternalRsPeer_locked(pid);
|
||||
if (!dpd)
|
||||
{
|
||||
dpd = addInternalPeer_locked(pid, RSDHT_PEERTYPE_FRIEND);
|
||||
RsStackMutex stack(dhtMtx); /********* LOCKED *********/
|
||||
|
||||
DhtPeerDetails *dpd = findInternalRsPeer_locked(pid);
|
||||
if (!dpd)
|
||||
{
|
||||
/* ERROR */
|
||||
dpd = addInternalPeer_locked(pid, RSDHT_PEERTYPE_FRIEND);
|
||||
if (!dpd)
|
||||
{
|
||||
/* ERROR */
|
||||
#ifdef DEBUG_BITDHT
|
||||
std::cerr << "p3BitDht::findPeer() ERROR installing InternalPeer";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "p3BitDht::findPeer() ERROR installing InternalPeer";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/* new entry... what do we need to set? */
|
||||
dpd->mDhtState = RSDHT_PEERDHT_SEARCHING;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* new entry... what do we need to set? */
|
||||
dpd->mDhtState = RSDHT_PEERDHT_SEARCHING;
|
||||
|
||||
#ifdef DEBUG_BITDHT
|
||||
std::cerr << "p3BitDht::findPeer() Installed new DhtPeer with pid => NodeId: ";
|
||||
bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* old entry */
|
||||
#ifdef DEBUG_BITDHT
|
||||
std::cerr << "p3BitDht::findPeer() Reactivating DhtPeer with pid => NodeId: ";
|
||||
bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
if (dpd->mDhtState != RSDHT_PEERDHT_NOT_ACTIVE)
|
||||
{
|
||||
#ifdef DEBUG_BITDHT
|
||||
std::cerr << "p3BitDht::findPeer() WARNING DhtState is Already Active!";
|
||||
std::cerr << "p3BitDht::findPeer() Installed new DhtPeer with pid => NodeId: ";
|
||||
bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* flag as searching */
|
||||
dpd->mDhtState = RSDHT_PEERDHT_SEARCHING;
|
||||
/* old entry */
|
||||
#ifdef DEBUG_BITDHT
|
||||
std::cerr << "p3BitDht::findPeer() Marking Old Peer as SEARCHING";
|
||||
std::cerr << "p3BitDht::findPeer() Reactivating DhtPeer with pid => NodeId: ";
|
||||
bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
if (dpd->mDhtState != RSDHT_PEERDHT_NOT_ACTIVE)
|
||||
{
|
||||
#ifdef DEBUG_BITDHT
|
||||
std::cerr << "p3BitDht::findPeer() WARNING DhtState is Already Active!";
|
||||
bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id));
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* flag as searching */
|
||||
dpd->mDhtState = RSDHT_PEERDHT_SEARCHING;
|
||||
#ifdef DEBUG_BITDHT
|
||||
std::cerr << "p3BitDht::findPeer() Marking Old Peer as SEARCHING";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bdNodeId nid = dpd->mDhtId.id;
|
||||
|
||||
nid = dpd->mDhtId.id;
|
||||
|
||||
#ifdef DEBUG_BITDHT
|
||||
std::cerr << "p3BitDht::findPeer() calling AddFindNode() with pid => NodeId: ";
|
||||
bdStdPrintNodeId(std::cerr, &nid);
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "p3BitDht::findPeer() calling AddFindNode() with pid => NodeId: ";
|
||||
bdStdPrintNodeId(std::cerr, &nid);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* add in peer */
|
||||
mUdpBitDht->addFindNode(&nid, BITDHT_QFLAGS_DO_IDLE | BITDHT_QFLAGS_UPDATES);
|
||||
|
||||
@ -134,29 +140,36 @@ bool p3BitDht::dropPeer(std::string pid)
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
bdNodeId nid;
|
||||
|
||||
DhtPeerDetails *dpd = findInternalRsPeer_locked(pid);
|
||||
if (!dpd)
|
||||
{
|
||||
/* ERROR */
|
||||
std::cerr << "p3BitDht::dropPeer(" << pid << ") HACK TO INCLUDE FRIEND AS NON-ACTIVE PEER";
|
||||
std::cerr << std::endl;
|
||||
|
||||
addFriend(pid);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* flag as searching */
|
||||
dpd->mDhtState = RSDHT_PEERDHT_NOT_ACTIVE;
|
||||
|
||||
bdNodeId nid = dpd->mDhtId.id;
|
||||
|
||||
RsStackMutex stack(dhtMtx); /********* LOCKED *********/
|
||||
|
||||
DhtPeerDetails *dpd = findInternalRsPeer_locked(pid);
|
||||
if (!dpd)
|
||||
{
|
||||
/* ERROR */
|
||||
std::cerr << "p3BitDht::dropPeer(" << pid << ") HACK TO INCLUDE FRIEND AS NON-ACTIVE PEER";
|
||||
std::cerr << std::endl;
|
||||
|
||||
//addFriend(pid);
|
||||
dpd = addInternalPeer_locked(pid, RSDHT_PEERTYPE_FOF);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* flag as searching */
|
||||
dpd->mDhtState = RSDHT_PEERDHT_NOT_ACTIVE;
|
||||
|
||||
nid = dpd->mDhtId.id;
|
||||
|
||||
#ifdef DEBUG_BITDHT
|
||||
std::cerr << "p3BitDht::dropPeer() calling removeFindNode() with pid => NodeId: ";
|
||||
bdStdPrintNodeId(std::cerr, &nid);
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "p3BitDht::dropPeer() calling removeFindNode() with pid => NodeId: ";
|
||||
bdStdPrintNodeId(std::cerr, &nid);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* remove in peer */
|
||||
mUdpBitDht->removeFindNode(&nid);
|
||||
|
||||
@ -170,6 +183,91 @@ bool p3BitDht::dropPeer(std::string pid)
|
||||
********************************* Basic Peer Details *************************************
|
||||
******************************************************************************************/
|
||||
|
||||
int p3BitDht::addBadPeer(const struct sockaddr_in &addr, uint32_t reason, uint32_t flags, uint32_t age)
|
||||
{
|
||||
//mUdpBitDht->updateKnownPeer(&id, 0, bdflags);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int p3BitDht::addKnownPeer(const std::string &pid, const struct sockaddr_in &addr, uint32_t flags)
|
||||
{
|
||||
|
||||
int p3type = 0;
|
||||
int bdflags = 0;
|
||||
bdId id;
|
||||
bool isOwnId = false;
|
||||
|
||||
switch(flags & NETASSIST_KNOWN_PEER_TYPE_MASK)
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
case NETASSIST_KNOWN_PEER_WHITELIST:
|
||||
p3type = RSDHT_PEERTYPE_OTHER;
|
||||
bdflags = BITDHT_PEER_STATUS_DHT_WHITELIST;
|
||||
|
||||
break;
|
||||
case NETASSIST_KNOWN_PEER_FOF:
|
||||
p3type = RSDHT_PEERTYPE_FOF;
|
||||
bdflags = BITDHT_PEER_STATUS_DHT_FOF;
|
||||
|
||||
break;
|
||||
case NETASSIST_KNOWN_PEER_FRIEND:
|
||||
p3type = RSDHT_PEERTYPE_FRIEND;
|
||||
bdflags = BITDHT_PEER_STATUS_DHT_FRIEND;
|
||||
|
||||
break;
|
||||
case NETASSIST_KNOWN_PEER_RELAY:
|
||||
p3type = RSDHT_PEERTYPE_OTHER;
|
||||
bdflags = BITDHT_PEER_STATUS_DHT_RELAY_SERVER;
|
||||
|
||||
break;
|
||||
case NETASSIST_KNOWN_PEER_SELF:
|
||||
p3type = RSDHT_PEERTYPE_OTHER;
|
||||
bdflags = BITDHT_PEER_STATUS_DHT_SELF;
|
||||
isOwnId = true;
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (flags & NETASSIST_KNOWN_PEER_ONLINE)
|
||||
{
|
||||
bdflags |= BD_FRIEND_ENTRY_ONLINE;
|
||||
}
|
||||
|
||||
if (!isOwnId)
|
||||
{
|
||||
RsStackMutex stack(dhtMtx); /********* LOCKED *********/
|
||||
DhtPeerDetails *dpd = addInternalPeer_locked(pid, p3type);
|
||||
|
||||
|
||||
if (bdflags & BD_FRIEND_ENTRY_ONLINE)
|
||||
{
|
||||
/* can we update the address? */
|
||||
//dpd->mDhtId.addr = addr;
|
||||
}
|
||||
|
||||
|
||||
id.id = dpd->mDhtId.id;
|
||||
id.addr = addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
// shouldn't use own id without mutex - but it is static!
|
||||
id.id = mOwnDhtId;
|
||||
id.addr = addr;
|
||||
}
|
||||
|
||||
mUdpBitDht->updateKnownPeer(&id, 0, bdflags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
int p3BitDht::addFriend(const std::string pid)
|
||||
{
|
||||
RsStackMutex stack(dhtMtx); /********* LOCKED *********/
|
||||
@ -192,6 +290,7 @@ int p3BitDht::addOther(const std::string pid)
|
||||
|
||||
return (NULL != addInternalPeer_locked(pid, RSDHT_PEERTYPE_OTHER));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int p3BitDht::removePeer(const std::string pid)
|
||||
|
@ -152,6 +152,7 @@ PUBLIC_HEADERS = retroshare/rsblogs.h \
|
||||
retroshare/rsturtle.h \
|
||||
retroshare/rstypes.h \
|
||||
retroshare/rsdht.h \
|
||||
retroshare/rsdsdv.h \
|
||||
retroshare/rsconfig.h
|
||||
|
||||
HEADERS += plugins/pluginmanager.h \
|
||||
@ -422,6 +423,10 @@ HEADERS += serialiser/rsbaseitems.h \
|
||||
serialiser/rstlvkvwide.h \
|
||||
serialiser/rstlvtypes.h \
|
||||
serialiser/rstlvutil.h \
|
||||
serialiser/rstlvdsdv.h \
|
||||
serialiser/rsdsdvitems.h \
|
||||
serialiser/rstlvbanlist.h \
|
||||
serialiser/rsbanlistitems.h \
|
||||
serialiser/rstunnelitems.h
|
||||
|
||||
HEADERS += services/p3channels.h \
|
||||
@ -434,6 +439,8 @@ HEADERS += services/p3channels.h \
|
||||
services/p3photoservice.h \
|
||||
services/p3service.h \
|
||||
services/p3statusservice.h \
|
||||
services/p3dsdv.h \
|
||||
services/p3banlist.h \
|
||||
services/p3tunnel.h
|
||||
|
||||
HEADERS += distrib/p3distrib.h \
|
||||
@ -555,6 +562,10 @@ SOURCES += serialiser/rsbaseitems.cc \
|
||||
serialiser/rstlvkvwide.cc \
|
||||
serialiser/rstlvtypes.cc \
|
||||
serialiser/rstlvutil.cc \
|
||||
serialiser/rstlvdsdv.cc \
|
||||
serialiser/rsdsdvitems.cc \
|
||||
serialiser/rstlvbanlist.cc \
|
||||
serialiser/rsbanlistitems.cc \
|
||||
serialiser/rstunnelitems.cc
|
||||
|
||||
SOURCES += services/p3channels.cc \
|
||||
@ -565,7 +576,10 @@ SOURCES += services/p3channels.cc \
|
||||
services/p3msgservice.cc \
|
||||
services/p3photoservice.cc \
|
||||
services/p3service.cc \
|
||||
services/p3statusservice.cc
|
||||
services/p3statusservice.cc \
|
||||
services/p3dsdv.cc \
|
||||
services/p3banlist.cc
|
||||
|
||||
# removed because getPeer() doesn t exist services/p3tunnel.cc
|
||||
|
||||
SOURCES += distrib/p3distrib.cc \
|
||||
|
@ -877,7 +877,10 @@ bool p3LinkMgrIMPL::connectResult(const std::string &id, bool success, uint32_t
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* always switch it off now */
|
||||
mNetMgr->netAssistFriend(id,false) ;
|
||||
mNetMgr->netAssistFriend(id,false);
|
||||
|
||||
/* inform NetMgr that we know this peers address */
|
||||
mNetMgr->netAssistKnownPeer(id,remote_peer_address, NETASSIST_KNOWN_PEER_FRIEND | NETASSIST_KNOWN_PEER_ONLINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -896,6 +899,9 @@ bool p3LinkMgrIMPL::connectResult(const std::string &id, bool success, uint32_t
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* inform NetMgr that this peer is offline */
|
||||
mNetMgr->netAssistKnownPeer(id,remote_peer_address, NETASSIST_KNOWN_PEER_FRIEND | NETASSIST_KNOWN_PEER_OFFLINE);
|
||||
}
|
||||
|
||||
return success;
|
||||
|
@ -888,7 +888,14 @@ void p3NetMgrIMPL::netExtCheck()
|
||||
updateNetStateBox_startup();
|
||||
|
||||
/* update PeerMgr with correct info */
|
||||
mPeerMgr->UpdateOwnAddress(mLocalAddr, mExtAddr);
|
||||
if (mPeerMgr)
|
||||
{
|
||||
mPeerMgr->UpdateOwnAddress(mLocalAddr, mExtAddr);
|
||||
}
|
||||
|
||||
/* inform DHT about our external address */
|
||||
std::string fakeId;
|
||||
netAssistKnownPeer(fakeId, mExtAddr, NETASSIST_KNOWN_PEER_SELF | NETASSIST_KNOWN_PEER_ONLINE);
|
||||
|
||||
std::ostringstream out;
|
||||
out << "p3NetMgr::netExtCheck() Network Setup Complete";
|
||||
@ -1031,7 +1038,10 @@ bool p3NetMgrIMPL::checkNetAddress()
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
mPeerMgr->UpdateOwnAddress(mLocalAddr, mExtAddr);
|
||||
if (mPeerMgr)
|
||||
{
|
||||
mPeerMgr->UpdateOwnAddress(mLocalAddr, mExtAddr);
|
||||
}
|
||||
|
||||
{
|
||||
std::ostringstream out;
|
||||
@ -1397,6 +1407,39 @@ bool p3NetMgrIMPL::netAssistFriend(std::string id, bool on)
|
||||
}
|
||||
|
||||
|
||||
bool p3NetMgrIMPL::netAssistKnownPeer(std::string id, const struct sockaddr_in &addr, uint32_t flags)
|
||||
{
|
||||
std::map<uint32_t, pqiNetAssistConnect *>::iterator it;
|
||||
|
||||
#ifdef NETMGR_DEBUG
|
||||
std::cerr << "p3NetMgrIMPL::netAssistKnownPeer(" << id << ")";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
for(it = mDhts.begin(); it != mDhts.end(); it++)
|
||||
{
|
||||
(it->second)->addKnownPeer(id, addr, flags);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3NetMgrIMPL::netAssistBadPeer(const struct sockaddr_in &addr, uint32_t reason, uint32_t flags, uint32_t age)
|
||||
{
|
||||
std::map<uint32_t, pqiNetAssistConnect *>::iterator it;
|
||||
|
||||
#ifdef NETMGR_DEBUG
|
||||
std::cerr << "p3NetMgrIMPL::netAssistBadPeer(" << rs_inet_ntoa(addr.sin_addr) << ")";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
for(it = mDhts.begin(); it != mDhts.end(); it++)
|
||||
{
|
||||
(it->second)->addBadPeer(addr, reason, flags, age);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool p3NetMgrIMPL::netAssistAttach(bool on)
|
||||
{
|
||||
std::map<uint32_t, pqiNetAssistConnect *>::iterator it;
|
||||
|
@ -97,6 +97,7 @@ class UdpRelayReceiver;
|
||||
#define NETMGR_DHT_FEEDBACK_CONN_FAILED 0x0002
|
||||
#define NETMGR_DHT_FEEDBACK_CONN_CLOSED 0x0003
|
||||
|
||||
|
||||
/**********
|
||||
* p3NetMgr Interface....
|
||||
* This allows a drop-in replacement for testing.
|
||||
@ -118,6 +119,8 @@ virtual bool setVisState(uint32_t visState) = 0;
|
||||
|
||||
// Switch DHT On/Off.
|
||||
virtual bool netAssistFriend(std::string id, bool on) = 0;
|
||||
virtual bool netAssistKnownPeer(std::string id, const struct sockaddr_in &addr, uint32_t flags) = 0;
|
||||
virtual bool netAssistBadPeer(const struct sockaddr_in &addr, uint32_t reason, uint32_t flags, uint32_t age) = 0;
|
||||
virtual bool netAssistStatusUpdate(std::string id, int mode) = 0;
|
||||
|
||||
/* Get Network State */
|
||||
@ -172,6 +175,8 @@ virtual bool setVisState(uint32_t visState);
|
||||
|
||||
// Switch DHT On/Off.
|
||||
virtual bool netAssistFriend(std::string id, bool on);
|
||||
virtual bool netAssistKnownPeer(std::string id, const struct sockaddr_in &addr, uint32_t flags);
|
||||
virtual bool netAssistBadPeer(const struct sockaddr_in &addr, uint32_t reason, uint32_t flags, uint32_t age);
|
||||
virtual bool netAssistStatusUpdate(std::string id, int mode);
|
||||
|
||||
/* Get Network State */
|
||||
|
@ -716,7 +716,28 @@ bool p3PeerMgrIMPL::UpdateOwnAddress(const struct sockaddr_in &localAddr, const
|
||||
ipAddressTimed.mSeenTime = time(NULL);
|
||||
mOwnState.ipAddrs.updateExtAddrs(ipAddressTimed);
|
||||
|
||||
mOwnState.serveraddr = extAddr;
|
||||
/* Attempted Fix to MANUAL FORWARD Mode....
|
||||
* don't update the server address - if we are in this mode
|
||||
*
|
||||
* It is okay - if they get it wrong, as we put the address in the address list anyway.
|
||||
* This should keep people happy, and allow for misconfiguration!
|
||||
*/
|
||||
|
||||
if (mOwnState.netMode & RS_NET_MODE_TRY_EXT)
|
||||
{
|
||||
mOwnState.serveraddr.sin_addr.s_addr = extAddr.sin_addr.s_addr;
|
||||
std::cerr << "p3PeerMgrIMPL::UpdateOwnAddress() Disabling Update of Server Port ";
|
||||
std::cerr << " as MANUAL FORWARD Mode";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "Address is Now: ";
|
||||
std::cerr << rs_inet_ntoa(mOwnState.serveraddr.sin_addr);
|
||||
std::cerr << ":" << htons(mOwnState.serveraddr.sin_port);
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
mOwnState.serveraddr = extAddr;
|
||||
}
|
||||
}
|
||||
|
||||
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
|
||||
|
@ -79,6 +79,19 @@ virtual bool getExternalAddress(struct sockaddr_in &addr) = 0;
|
||||
};
|
||||
|
||||
|
||||
#define PNASS_TYPE_BADPEER 0x0001
|
||||
#define PNASS_REASON_UNKNOWN 0x0001
|
||||
|
||||
class pqiNetAssistPeerShare
|
||||
{
|
||||
public:
|
||||
|
||||
/* share Addresses for various reasons (bad peers, etc) */
|
||||
virtual void updatePeer(std::string id, struct sockaddr_in addr, int type, int reason, int age) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* this is for the Stunners
|
||||
*
|
||||
*
|
||||
@ -98,6 +111,16 @@ virtual int tick() = 0; /* for internal accounting */
|
||||
};
|
||||
|
||||
|
||||
#define NETASSIST_KNOWN_PEER_OFFLINE 0x0001
|
||||
#define NETASSIST_KNOWN_PEER_ONLINE 0x0002
|
||||
|
||||
#define NETASSIST_KNOWN_PEER_WHITELIST 0x0100
|
||||
#define NETASSIST_KNOWN_PEER_FRIEND 0x0200
|
||||
#define NETASSIST_KNOWN_PEER_FOF 0x0400
|
||||
#define NETASSIST_KNOWN_PEER_RELAY 0x0800
|
||||
#define NETASSIST_KNOWN_PEER_SELF 0x1000
|
||||
|
||||
#define NETASSIST_KNOWN_PEER_TYPE_MASK 0xff00
|
||||
|
||||
class pqiNetAssistConnect: public pqiNetAssist
|
||||
{
|
||||
@ -120,9 +143,12 @@ virtual bool findPeer(std::string id) = 0;
|
||||
virtual bool dropPeer(std::string id) = 0;
|
||||
|
||||
/* add non-active peers (can still toggle active/non-active via above) */
|
||||
virtual int addFriend(const std::string pid) = 0;
|
||||
virtual int addFriendOfFriend(const std::string pid) = 0;
|
||||
virtual int addOther(const std::string pid) = 0;
|
||||
virtual int addBadPeer(const struct sockaddr_in &addr, uint32_t reason, uint32_t flags, uint32_t age) = 0;
|
||||
virtual int addKnownPeer(const std::string &pid, const struct sockaddr_in &addr, uint32_t flags) = 0;
|
||||
|
||||
//virtual int addFriend(const std::string pid) = 0;
|
||||
//virtual int addFriendOfFriend(const std::string pid) = 0;
|
||||
//virtual int addOther(const std::string pid) = 0;
|
||||
|
||||
|
||||
virtual void ConnectionFeedback(std::string pid, int mode) = 0;
|
||||
|
107
libretroshare/src/retroshare/rsdsdv.h
Normal file
107
libretroshare/src/retroshare/rsdsdv.h
Normal file
@ -0,0 +1,107 @@
|
||||
#ifndef RETROSHARE_DSDV_INTERFACE_H
|
||||
#define RETROSHARE_DSDV_INTERFACE_H
|
||||
|
||||
/*
|
||||
* libretroshare/src/rsiface: rsdsdv.h
|
||||
*
|
||||
* RetroShare C++ Interface.
|
||||
*
|
||||
* Copyright 2011-2011 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
/* The Main Interface Class - for information about your Peers */
|
||||
class RsDsdv;
|
||||
extern RsDsdv *rsDsdv;
|
||||
|
||||
|
||||
#define RSDSDV_IDTYPE_PEER 0x0001
|
||||
#define RSDSDV_IDTYPE_SERVICE 0x0002
|
||||
#define RSDSDV_IDTYPE_TEST 0x0100
|
||||
|
||||
#define RSDSDV_FLAGS_SIGNIFICANT_CHANGE 0x0001
|
||||
#define RSDSDV_FLAGS_STABLE_ROUTE 0x0002
|
||||
#define RSDSDV_FLAGS_NEW_ROUTE 0x0004
|
||||
#define RSDSDV_FLAGS_OWN_SERVICE 0x0008
|
||||
|
||||
|
||||
class RsDsdvId
|
||||
{
|
||||
public:
|
||||
|
||||
uint32_t mIdType;
|
||||
std::string mAnonChunk;
|
||||
std::string mHash;
|
||||
};
|
||||
|
||||
class RsDsdvRoute
|
||||
{
|
||||
public:
|
||||
|
||||
std::string mNextHop;
|
||||
uint32_t mSequence;
|
||||
uint32_t mDistance;
|
||||
time_t mReceived;
|
||||
time_t mValidSince;
|
||||
|
||||
};
|
||||
|
||||
class RsDsdvTableEntry
|
||||
{
|
||||
public:
|
||||
|
||||
RsDsdvId mDest;
|
||||
bool mIsStable;
|
||||
RsDsdvRoute mStableRoute;
|
||||
//RsDsdvRoute mFreshestRoute;
|
||||
|
||||
std::map<std::string, RsDsdvRoute> mAllRoutes;
|
||||
|
||||
uint32_t mFlags;
|
||||
|
||||
/* if we've matched it to someone */
|
||||
std::string mMatchedHash;
|
||||
bool mMatched;
|
||||
bool mOwnSource;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const RsDsdvId &id);
|
||||
std::ostream &operator<<(std::ostream &out, const RsDsdvRoute &route);
|
||||
std::ostream &operator<<(std::ostream &out, const RsDsdvTableEntry &entry);
|
||||
|
||||
|
||||
class RsDsdv
|
||||
{
|
||||
public:
|
||||
|
||||
RsDsdv() { return; }
|
||||
virtual ~RsDsdv() { return; }
|
||||
|
||||
virtual uint32_t getLocalServices(std::list<std::string> &hashes) = 0;
|
||||
virtual uint32_t getAllServices(std::list<std::string> &hashes) = 0;
|
||||
virtual int getDsdvEntry(const std::string &hash, RsDsdvTableEntry &entry) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -83,7 +83,7 @@ class RsPlugin
|
||||
virtual MainPage *qt_page() const { return NULL ; }
|
||||
virtual QWidget *qt_config_panel() const { return NULL ; }
|
||||
virtual QIcon *qt_icon() const { return NULL ; }
|
||||
virtual QTranslator *qt_translator(QApplication */*app*/, const QString& /*languageCode*/) const { return NULL ; }
|
||||
virtual QTranslator *qt_translator(QApplication * /* app */, const QString& /* languageCode */ ) const { return NULL ; }
|
||||
|
||||
virtual std::string configurationFileName() const { return std::string() ; }
|
||||
virtual std::string getShortPluginDescription() const = 0 ;
|
||||
|
@ -1781,6 +1781,9 @@ RsTurtle *rsTurtle = NULL ;
|
||||
#include "services/p3vors.h"
|
||||
#endif
|
||||
|
||||
#include "services/p3banlist.h"
|
||||
#include "services/p3dsdv.h"
|
||||
|
||||
|
||||
RsControl *createRsControl(RsIface &iface, NotifyBase ¬ify)
|
||||
{
|
||||
@ -2059,7 +2062,7 @@ int RsServer::StartupRetroShare()
|
||||
mPluginsManager->setInterfaces(interfaces);
|
||||
|
||||
/* create Services */
|
||||
ad = new p3disc(mPeerMgr, mLinkMgr, pqih);
|
||||
ad = new p3disc(mPeerMgr, mLinkMgr, mNetMgr, pqih);
|
||||
#ifndef MINIMAL_LIBRS
|
||||
msgSrv = new p3MsgService(mLinkMgr);
|
||||
chatSrv = new p3ChatService(mLinkMgr, mHistoryMgr);
|
||||
@ -2127,6 +2130,16 @@ int RsServer::StartupRetroShare()
|
||||
rsVoip = mVoipTest;
|
||||
#endif
|
||||
|
||||
// new services to test.
|
||||
p3BanList *mBanList = new p3BanList(mLinkMgr, mNetMgr);
|
||||
pqih -> addService(mBanList);
|
||||
mBitDht->setupPeerSharer(mBanList);
|
||||
|
||||
p3Dsdv *mDsdv = new p3Dsdv(mLinkMgr);
|
||||
pqih -> addService(mDsdv);
|
||||
rsDsdv = mDsdv;
|
||||
mDsdv->addTestService();
|
||||
|
||||
#endif // MINIMAL_LIBRS
|
||||
|
||||
/**************************************************************************/
|
||||
|
@ -73,3 +73,12 @@ const uint8_t QOS_PRIORITY_RS_STATUS_ITEM = 2 ;
|
||||
//
|
||||
const uint8_t QOS_PRIORITY_RS_VOIP_PING = 9 ;
|
||||
|
||||
// BanList
|
||||
//
|
||||
const uint8_t QOS_PRIORITY_RS_BANLIST_ITEM = 2 ;
|
||||
|
||||
// Dsdv Routing
|
||||
//
|
||||
const uint8_t QOS_PRIORITY_RS_DSDV_ROUTE = 4 ;
|
||||
const uint8_t QOS_PRIORITY_RS_DSDV_DATA = 2 ;
|
||||
|
||||
|
203
libretroshare/src/serialiser/rsbanlistitems.cc
Normal file
203
libretroshare/src/serialiser/rsbanlistitems.cc
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* libretroshare/src/serialiser: rsbanlist.cc
|
||||
*
|
||||
* RetroShare Serialiser.
|
||||
*
|
||||
* Copyright 2011 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "serialiser/rsbaseserial.h"
|
||||
#include "serialiser/rsbanlistitems.h"
|
||||
#include "serialiser/rstlvbanlist.h"
|
||||
|
||||
/***
|
||||
#define RSSERIAL_DEBUG 1
|
||||
***/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
RsBanListItem::~RsBanListItem()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void RsBanListItem::clear()
|
||||
{
|
||||
peerList.TlvClear();
|
||||
}
|
||||
|
||||
std::ostream &RsBanListItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsBanListItem", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
peerList.print(out, int_Indent);
|
||||
|
||||
printRsItemEnd(out, "RsBanListItem", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
uint32_t RsBanListSerialiser::sizeList(RsBanListItem *item)
|
||||
{
|
||||
uint32_t s = 8; /* header */
|
||||
s += item->peerList.TlvSize();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* serialise the data to the buffer */
|
||||
bool RsBanListSerialiser::serialiseList(RsBanListItem *item, void *data, uint32_t *pktsize)
|
||||
{
|
||||
uint32_t tlvsize = sizeList(item);
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (*pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
*pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
|
||||
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsDsdvSerialiser::serialiseRoute() Header: " << ok << std::endl;
|
||||
std::cerr << "RsDsdvSerialiser::serialiseRoute() Size: " << tlvsize << std::endl;
|
||||
#endif
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= item->peerList.SetTlv(data, tlvsize, &offset);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsDsdvSerialiser::serialiseRoute() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
RsBanListItem *RsBanListSerialiser::deserialiseList(void *data, uint32_t *pktsize)
|
||||
{
|
||||
/* get the type and size */
|
||||
uint32_t rstype = getRsItemId(data);
|
||||
uint32_t tlvsize = getRsItemSize(data);
|
||||
|
||||
uint32_t offset = 0;
|
||||
|
||||
|
||||
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
|
||||
(RS_SERVICE_TYPE_BANLIST != getRsItemService(rstype)) ||
|
||||
(RS_PKT_SUBTYPE_BANLIST_ITEM != getRsItemSubType(rstype)))
|
||||
{
|
||||
return NULL; /* wrong type */
|
||||
}
|
||||
|
||||
if (*pktsize < tlvsize) /* check size */
|
||||
return NULL; /* not enough data */
|
||||
|
||||
/* set the packet length */
|
||||
*pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* ready to load */
|
||||
RsBanListItem *item = new RsBanListItem();
|
||||
item->clear();
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= item->peerList.GetTlv(data, tlvsize, &offset);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
/* error */
|
||||
delete item;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
delete item;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
uint32_t RsBanListSerialiser::size(RsItem *i)
|
||||
{
|
||||
RsBanListItem *dri;
|
||||
|
||||
if (NULL != (dri = dynamic_cast<RsBanListItem *>(i)))
|
||||
{
|
||||
return sizeList(dri);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool RsBanListSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
|
||||
{
|
||||
RsBanListItem *dri;
|
||||
|
||||
if (NULL != (dri = dynamic_cast<RsBanListItem *>(i)))
|
||||
{
|
||||
return serialiseList(dri, data, pktsize);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RsItem *RsBanListSerialiser::deserialise(void *data, uint32_t *pktsize)
|
||||
{
|
||||
/* get the type and size */
|
||||
uint32_t rstype = getRsItemId(data);
|
||||
|
||||
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
|
||||
(RS_SERVICE_TYPE_BANLIST != getRsItemService(rstype)))
|
||||
{
|
||||
return NULL; /* wrong type */
|
||||
}
|
||||
|
||||
switch(getRsItemSubType(rstype))
|
||||
{
|
||||
case RS_PKT_SUBTYPE_BANLIST_ITEM:
|
||||
return deserialiseList(data, pktsize);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
|
86
libretroshare/src/serialiser/rsbanlistitems.h
Normal file
86
libretroshare/src/serialiser/rsbanlistitems.h
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef RS_BANLIST_ITEMS_H
|
||||
#define RS_BANLIST_ITEMS_H
|
||||
|
||||
/*
|
||||
* libretroshare/src/serialiser: rsbanlistitems.h
|
||||
*
|
||||
* RetroShare Serialiser.
|
||||
*
|
||||
* Copyright 2011 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "serialiser/rsserviceids.h"
|
||||
#include "serialiser/rsserial.h"
|
||||
#include "serialiser/rstlvtypes.h"
|
||||
#include "serialiser/rstlvbanlist.h"
|
||||
|
||||
#define RS_PKT_SUBTYPE_BANLIST_ITEM 0x01
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
class RsBanListItem: public RsItem
|
||||
{
|
||||
public:
|
||||
RsBanListItem()
|
||||
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_BANLIST,
|
||||
RS_PKT_SUBTYPE_BANLIST_ITEM)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_BANLIST_ITEM);
|
||||
return;
|
||||
}
|
||||
|
||||
virtual ~RsBanListItem();
|
||||
virtual void clear();
|
||||
std::ostream &print(std::ostream &out, uint16_t indent = 0);
|
||||
|
||||
RsTlvBanList peerList;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class RsBanListSerialiser: public RsSerialType
|
||||
{
|
||||
public:
|
||||
RsBanListSerialiser()
|
||||
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_BANLIST)
|
||||
{ return; }
|
||||
virtual ~RsBanListSerialiser()
|
||||
{ return; }
|
||||
|
||||
virtual uint32_t size(RsItem *);
|
||||
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
|
||||
virtual RsItem * deserialise(void *data, uint32_t *size);
|
||||
|
||||
private:
|
||||
|
||||
virtual uint32_t sizeList(RsBanListItem *);
|
||||
virtual bool serialiseList (RsBanListItem *item, void *data, uint32_t *size);
|
||||
virtual RsBanListItem *deserialiseList(void *data, uint32_t *size);
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#endif /* RS_BANLIST_ITEMS_H */
|
||||
|
||||
|
352
libretroshare/src/serialiser/rsdsdvitems.cc
Normal file
352
libretroshare/src/serialiser/rsdsdvitems.cc
Normal file
@ -0,0 +1,352 @@
|
||||
/*
|
||||
* libretroshare/src/serialiser: rsgameitems.cc
|
||||
*
|
||||
* RetroShare Serialiser.
|
||||
*
|
||||
* Copyright 2007-2008 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "serialiser/rsbaseserial.h"
|
||||
#include "serialiser/rsdsdvitems.h"
|
||||
#include "serialiser/rstlvdsdv.h"
|
||||
|
||||
/***
|
||||
#define RSSERIAL_DEBUG 1
|
||||
***/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
RsDsdvRouteItem::~RsDsdvRouteItem()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void RsDsdvRouteItem::clear()
|
||||
{
|
||||
routes.TlvClear();
|
||||
}
|
||||
|
||||
std::ostream &RsDsdvRouteItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsDsdvRouteItem", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
routes.print(out, int_Indent);
|
||||
|
||||
printRsItemEnd(out, "RsDsdvRouteItem", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
uint32_t RsDsdvSerialiser::sizeRoute(RsDsdvRouteItem *item)
|
||||
{
|
||||
uint32_t s = 8; /* header */
|
||||
s += item->routes.TlvSize();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* serialise the data to the buffer */
|
||||
bool RsDsdvSerialiser::serialiseRoute(RsDsdvRouteItem *item, void *data, uint32_t *pktsize)
|
||||
{
|
||||
uint32_t tlvsize = sizeRoute(item);
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (*pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
*pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
|
||||
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsDsdvSerialiser::serialiseRoute() Header: " << ok << std::endl;
|
||||
std::cerr << "RsDsdvSerialiser::serialiseRoute() Size: " << tlvsize << std::endl;
|
||||
#endif
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= item->routes.SetTlv(data, tlvsize, &offset);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsDsdvSerialiser::serialiseRoute() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
RsDsdvRouteItem *RsDsdvSerialiser::deserialiseRoute(void *data, uint32_t *pktsize)
|
||||
{
|
||||
/* get the type and size */
|
||||
uint32_t rstype = getRsItemId(data);
|
||||
uint32_t tlvsize = getRsItemSize(data);
|
||||
|
||||
uint32_t offset = 0;
|
||||
|
||||
|
||||
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
|
||||
(RS_SERVICE_TYPE_DSDV != getRsItemService(rstype)) ||
|
||||
(RS_PKT_SUBTYPE_DSDV_ROUTE != getRsItemSubType(rstype)))
|
||||
{
|
||||
return NULL; /* wrong type */
|
||||
}
|
||||
|
||||
if (*pktsize < tlvsize) /* check size */
|
||||
return NULL; /* not enough data */
|
||||
|
||||
/* set the packet length */
|
||||
*pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* ready to load */
|
||||
RsDsdvRouteItem *item = new RsDsdvRouteItem();
|
||||
item->clear();
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= item->routes.GetTlv(data, tlvsize, &offset);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
/* error */
|
||||
delete item;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
delete item;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
RsDsdvDataItem::~RsDsdvDataItem()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void RsDsdvDataItem::clear()
|
||||
{
|
||||
src.TlvClear();
|
||||
dest.TlvClear();
|
||||
ttl = 0;
|
||||
data.TlvClear();
|
||||
}
|
||||
|
||||
std::ostream &RsDsdvDataItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsDsdvDataItem", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
src.print(out, int_Indent);
|
||||
dest.print(out, int_Indent);
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "TTL: " << ttl << std::endl;
|
||||
|
||||
data.print(out, int_Indent);
|
||||
|
||||
printRsItemEnd(out, "RsDsdvDataItem", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
uint32_t RsDsdvSerialiser::sizeData(RsDsdvDataItem *item)
|
||||
{
|
||||
uint32_t s = 8; /* header */
|
||||
s += item->src.TlvSize();
|
||||
s += item->dest.TlvSize();
|
||||
s += 4;
|
||||
s += item->data.TlvSize();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* serialise the data to the buffer */
|
||||
bool RsDsdvSerialiser::serialiseData(RsDsdvDataItem *item, void *data, uint32_t *pktsize)
|
||||
{
|
||||
uint32_t tlvsize = sizeData(item);
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (*pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
*pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
|
||||
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsDsdvSerialiser::serialiseData() Header: " << ok << std::endl;
|
||||
std::cerr << "RsDsdvSerialiser::serialiseData() Size: " << tlvsize << std::endl;
|
||||
#endif
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= item->src.SetTlv(data, tlvsize, &offset);
|
||||
ok &= item->dest.SetTlv(data, tlvsize, &offset);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, item->ttl);
|
||||
ok &= item->data.SetTlv(data, tlvsize, &offset);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsDsdvSerialiser::serialiseData() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
RsDsdvDataItem *RsDsdvSerialiser::deserialiseData(void *data, uint32_t *pktsize)
|
||||
{
|
||||
/* get the type and size */
|
||||
uint32_t rstype = getRsItemId(data);
|
||||
uint32_t tlvsize = getRsItemSize(data);
|
||||
|
||||
uint32_t offset = 0;
|
||||
|
||||
|
||||
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
|
||||
(RS_SERVICE_TYPE_DSDV != getRsItemService(rstype)) ||
|
||||
(RS_PKT_SUBTYPE_DSDV_DATA != getRsItemSubType(rstype)))
|
||||
{
|
||||
return NULL; /* wrong type */
|
||||
}
|
||||
|
||||
if (*pktsize < tlvsize) /* check size */
|
||||
return NULL; /* not enough data */
|
||||
|
||||
/* set the packet length */
|
||||
*pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* ready to load */
|
||||
RsDsdvDataItem *item = new RsDsdvDataItem();
|
||||
item->clear();
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= item->src.GetTlv(data, tlvsize, &offset);
|
||||
ok &= item->dest.GetTlv(data, tlvsize, &offset);
|
||||
ok &= getRawUInt32(data, tlvsize, &offset, &(item->ttl));
|
||||
ok &= item->data.GetTlv(data, tlvsize, &offset);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
/* error */
|
||||
delete item;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
delete item;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
uint32_t RsDsdvSerialiser::size(RsItem *i)
|
||||
{
|
||||
RsDsdvRouteItem *dri;
|
||||
RsDsdvDataItem *ddi;
|
||||
|
||||
if (NULL != (dri = dynamic_cast<RsDsdvRouteItem *>(i)))
|
||||
{
|
||||
return sizeRoute(dri);
|
||||
}
|
||||
if (NULL != (ddi = dynamic_cast<RsDsdvDataItem *>(i)))
|
||||
{
|
||||
return sizeData(ddi);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool RsDsdvSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
|
||||
{
|
||||
RsDsdvRouteItem *dri;
|
||||
RsDsdvDataItem *ddi;
|
||||
|
||||
if (NULL != (dri = dynamic_cast<RsDsdvRouteItem *>(i)))
|
||||
{
|
||||
return serialiseRoute(dri, data, pktsize);
|
||||
}
|
||||
if (NULL != (ddi = dynamic_cast<RsDsdvDataItem *>(i)))
|
||||
{
|
||||
return serialiseData(ddi, data, pktsize);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RsItem *RsDsdvSerialiser::deserialise(void *data, uint32_t *pktsize)
|
||||
{
|
||||
/* get the type and size */
|
||||
uint32_t rstype = getRsItemId(data);
|
||||
|
||||
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
|
||||
(RS_SERVICE_TYPE_DSDV != getRsItemService(rstype)))
|
||||
{
|
||||
return NULL; /* wrong type */
|
||||
}
|
||||
|
||||
switch(getRsItemSubType(rstype))
|
||||
{
|
||||
case RS_PKT_SUBTYPE_DSDV_ROUTE:
|
||||
return deserialiseRoute(data, pktsize);
|
||||
break;
|
||||
case RS_PKT_SUBTYPE_DSDV_DATA:
|
||||
return deserialiseData(data, pktsize);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
|
109
libretroshare/src/serialiser/rsdsdvitems.h
Normal file
109
libretroshare/src/serialiser/rsdsdvitems.h
Normal file
@ -0,0 +1,109 @@
|
||||
#ifndef RS_DSDV_ITEMS_H
|
||||
#define RS_DSDV_ITEMS_H
|
||||
|
||||
/*
|
||||
* libretroshare/src/serialiser: rsdsdvitems.h
|
||||
*
|
||||
* RetroShare Serialiser.
|
||||
*
|
||||
* Copyright 2011-2011 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "serialiser/rsserviceids.h"
|
||||
#include "serialiser/rsserial.h"
|
||||
#include "serialiser/rstlvbase.h"
|
||||
#include "serialiser/rstlvtypes.h"
|
||||
#include "serialiser/rstlvdsdv.h"
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#define RS_PKT_SUBTYPE_DSDV_ROUTE 0x01
|
||||
#define RS_PKT_SUBTYPE_DSDV_DATA 0x02
|
||||
|
||||
class RsDsdvRouteItem: public RsItem
|
||||
{
|
||||
public:
|
||||
RsDsdvRouteItem()
|
||||
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DSDV,
|
||||
RS_PKT_SUBTYPE_DSDV_ROUTE)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_DSDV_ROUTE);
|
||||
return;
|
||||
}
|
||||
virtual ~RsDsdvRouteItem();
|
||||
virtual void clear();
|
||||
std::ostream &print(std::ostream &out, uint16_t indent = 0);
|
||||
|
||||
RsTlvDsdvEntrySet routes;
|
||||
};
|
||||
|
||||
class RsDsdvDataItem: public RsItem
|
||||
{
|
||||
public:
|
||||
RsDsdvDataItem()
|
||||
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DSDV,
|
||||
RS_PKT_SUBTYPE_DSDV_DATA), data(TLV_TYPE_BIN_GENERIC)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_DSDV_DATA);
|
||||
return;
|
||||
}
|
||||
virtual ~RsDsdvDataItem();
|
||||
virtual void clear();
|
||||
std::ostream &print(std::ostream &out, uint16_t indent = 0);
|
||||
|
||||
RsTlvDsdvEndPoint src;
|
||||
RsTlvDsdvEndPoint dest;
|
||||
uint32_t ttl;
|
||||
RsTlvBinaryData data;
|
||||
};
|
||||
|
||||
class RsDsdvSerialiser: public RsSerialType
|
||||
{
|
||||
public:
|
||||
RsDsdvSerialiser()
|
||||
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DSDV)
|
||||
{ return; }
|
||||
virtual ~RsDsdvSerialiser()
|
||||
{ return; }
|
||||
|
||||
virtual uint32_t size(RsItem *);
|
||||
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
|
||||
virtual RsItem * deserialise(void *data, uint32_t *size);
|
||||
|
||||
private:
|
||||
|
||||
virtual uint32_t sizeRoute(RsDsdvRouteItem *);
|
||||
virtual bool serialiseRoute(RsDsdvRouteItem *item, void *data, uint32_t *size);
|
||||
virtual RsDsdvRouteItem *deserialiseRoute(void *data, uint32_t *size);
|
||||
|
||||
virtual uint32_t sizeData(RsDsdvDataItem *);
|
||||
virtual bool serialiseData(RsDsdvDataItem *item, void *data, uint32_t *size);
|
||||
virtual RsDsdvDataItem *deserialiseData(void *data, uint32_t *size);
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#endif /* RS_DSDV_ITEMS_H */
|
||||
|
||||
|
@ -92,6 +92,11 @@ const uint16_t RS_SERVICE_TYPE_PROXY = 0xf030;
|
||||
/* Photo - Cache Only */
|
||||
const uint16_t RS_SERVICE_TYPE_PHOTO = 0xf040;
|
||||
|
||||
/* DSDV Testing at the moment - Service Only */
|
||||
const uint16_t RS_SERVICE_TYPE_DSDV = 0xf050;
|
||||
|
||||
/* BanList Testing at the moment - Service Only */
|
||||
const uint16_t RS_SERVICE_TYPE_BANLIST = 0xf060;
|
||||
|
||||
/* Games/External Apps - Service Only */
|
||||
const uint16_t RS_SERVICE_TYPE_GAME_LAUNCHER = 0xf200;
|
||||
|
314
libretroshare/src/serialiser/rstlvbanlist.cc
Normal file
314
libretroshare/src/serialiser/rstlvbanlist.cc
Normal file
@ -0,0 +1,314 @@
|
||||
|
||||
/*
|
||||
* libretroshare/src/serialiser: rstlvtypes.cc
|
||||
*
|
||||
* RetroShare Serialiser.
|
||||
*
|
||||
* Copyright 2007-2008 by Robert Fernie, Chris Parker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "rstlvbanlist.h"
|
||||
|
||||
#include "rstlvbase.h"
|
||||
#include "rstlvtypes.h"
|
||||
#include "rsbaseserial.h"
|
||||
#include "util/rsprint.h"
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
/************************************* RsTlvBanListEntry ************************************/
|
||||
|
||||
RsTlvBanListEntry::RsTlvBanListEntry()
|
||||
:RsTlvItem(), level(0), reason(0), age(0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void RsTlvBanListEntry::TlvClear()
|
||||
{
|
||||
sockaddr_clear(&addr);
|
||||
level = 0;
|
||||
reason = 0;
|
||||
age = 0;
|
||||
}
|
||||
|
||||
uint32_t RsTlvBanListEntry::TlvSize()
|
||||
{
|
||||
uint32_t s = TLV_HEADER_SIZE;
|
||||
|
||||
s += GetTlvIpAddrPortV4Size();
|
||||
s += 4; // level;
|
||||
s += 4; // reason;
|
||||
s += 4; // age;
|
||||
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
bool RsTlvBanListEntry::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
|
||||
{
|
||||
/* must check sizes */
|
||||
uint32_t tlvsize = TlvSize();
|
||||
uint32_t tlvend = *offset + tlvsize;
|
||||
|
||||
if (size < tlvend)
|
||||
return false; /* not enough space */
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* start at data[offset] */
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_BAN_ENTRY, tlvsize);
|
||||
|
||||
ok &= SetTlvIpAddrPortV4(data, tlvend, offset, TLV_TYPE_IPV4_REMOTE, &addr);
|
||||
ok &= setRawUInt32(data, tlvend, offset, level);
|
||||
ok &= setRawUInt32(data, tlvend, offset, reason);
|
||||
ok &= setRawUInt32(data, tlvend, offset, age);
|
||||
return ok;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool RsTlvBanListEntry::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
|
||||
{
|
||||
if (size < *offset + TLV_HEADER_SIZE)
|
||||
return false;
|
||||
|
||||
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
|
||||
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
|
||||
uint32_t tlvend = *offset + tlvsize;
|
||||
|
||||
if (size < tlvend) /* check size */
|
||||
return false; /* not enough space */
|
||||
|
||||
if (tlvtype != TLV_TYPE_BAN_ENTRY) /* check type */
|
||||
return false;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* ready to load */
|
||||
TlvClear();
|
||||
|
||||
/* skip the header */
|
||||
(*offset) += TLV_HEADER_SIZE;
|
||||
|
||||
ok &= GetTlvIpAddrPortV4(data, tlvend, offset, TLV_TYPE_IPV4_REMOTE, &addr);
|
||||
ok &= getRawUInt32(data, tlvend, offset, &(level));
|
||||
ok &= getRawUInt32(data, tlvend, offset, &(reason));
|
||||
ok &= getRawUInt32(data, tlvend, offset, &(age));
|
||||
|
||||
/***************************************************************************
|
||||
* NB: extra components could be added (for future expansion of the type).
|
||||
* or be present (if this code is reading an extended version).
|
||||
*
|
||||
* We must chew up the extra characters to conform with TLV specifications
|
||||
***************************************************************************/
|
||||
if (*offset != tlvend)
|
||||
{
|
||||
#ifdef TLV_DEBUG
|
||||
std::cerr << "RsTlvBanListEntry::GetTlv() Warning extra bytes at end of item";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
*offset = tlvend;
|
||||
}
|
||||
|
||||
return ok;
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::ostream &RsTlvBanListEntry::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printBase(out, "RsTlvBanListEntry", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "addr:" << rs_inet_ntoa(addr.sin_addr) << ":" << htons(addr.sin_port);
|
||||
out << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "level:" << level;
|
||||
out << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "reason:" << reason;
|
||||
out << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "age:" << age;
|
||||
out << std::endl;
|
||||
|
||||
printEnd(out, "RsTlvBanListEntry", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/************************************* RsTlvBanList ************************************/
|
||||
|
||||
RsTlvBanList::RsTlvBanList()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RsTlvBanList::TlvClear()
|
||||
{
|
||||
entries.clear();
|
||||
}
|
||||
|
||||
uint32_t RsTlvBanList::TlvSize()
|
||||
{
|
||||
|
||||
uint32_t s = TLV_HEADER_SIZE; /* header */
|
||||
|
||||
std::list<RsTlvBanListEntry>::iterator it;
|
||||
|
||||
|
||||
if(!entries.empty())
|
||||
{
|
||||
|
||||
for(it = entries.begin(); it != entries.end() ; ++it)
|
||||
s += it->TlvSize();
|
||||
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
bool RsTlvBanList::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
|
||||
{
|
||||
/* must check sizes */
|
||||
uint32_t tlvsize = TlvSize();
|
||||
uint32_t tlvend = *offset + tlvsize;
|
||||
|
||||
if (size < tlvend)
|
||||
return false; /* not enough space */
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* start at data[offset] */
|
||||
ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_BAN_LIST , tlvsize);
|
||||
|
||||
if(!entries.empty())
|
||||
{
|
||||
std::list<RsTlvBanListEntry>::iterator it;
|
||||
|
||||
for(it = entries.begin(); it != entries.end() ; ++it)
|
||||
ok &= it->SetTlv(data, size, offset);
|
||||
}
|
||||
|
||||
|
||||
return ok;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool RsTlvBanList::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
|
||||
{
|
||||
if (size < *offset + TLV_HEADER_SIZE)
|
||||
return false;
|
||||
|
||||
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
|
||||
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
|
||||
uint32_t tlvend = *offset + tlvsize;
|
||||
|
||||
if (size < tlvend) /* check size */
|
||||
return false; /* not enough space */
|
||||
|
||||
if (tlvtype != TLV_TYPE_BAN_LIST) /* check type */
|
||||
return false;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* ready to load */
|
||||
TlvClear();
|
||||
|
||||
/* skip the header */
|
||||
(*offset) += TLV_HEADER_SIZE;
|
||||
|
||||
/* while there is TLV */
|
||||
while((*offset) + 2 < tlvend)
|
||||
{
|
||||
/* get the next type */
|
||||
uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
|
||||
|
||||
switch(tlvsubtype)
|
||||
{
|
||||
case TLV_TYPE_BAN_ENTRY:
|
||||
{
|
||||
RsTlvBanListEntry entry;
|
||||
ok &= entry.GetTlv(data, size, offset);
|
||||
if (ok)
|
||||
{
|
||||
entries.push_back(entry);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ok &= SkipUnknownTlv(data, tlvend, offset);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* NB: extra components could be added (for future expansion of the type).
|
||||
* or be present (if this code is reading an extended version).
|
||||
*
|
||||
* We must chew up the extra characters to conform with TLV specifications
|
||||
***************************************************************************/
|
||||
if (*offset != tlvend)
|
||||
{
|
||||
#ifdef TLV_DEBUG
|
||||
std::cerr << "RsTlvBanList::GetTlv() Warning extra bytes at end of item";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
*offset = tlvend;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
// prints out contents of RsTlvBanList
|
||||
std::ostream &RsTlvBanList::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printBase(out, "RsTlvBanList", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
std::list<RsTlvBanListEntry>::iterator it;
|
||||
for(it = entries.begin(); it != entries.end() ; ++it)
|
||||
it->print(out, int_Indent);
|
||||
|
||||
printEnd(out, "RsTlvBanList", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/************************************* RsTlvBanList ************************************/
|
||||
|
||||
|
72
libretroshare/src/serialiser/rstlvbanlist.h
Normal file
72
libretroshare/src/serialiser/rstlvbanlist.h
Normal file
@ -0,0 +1,72 @@
|
||||
#ifndef RS_TLV_BANLIST_TYPES_H
|
||||
#define RS_TLV_BANLIST_TYPES_H
|
||||
|
||||
/*
|
||||
* libretroshare/src/serialiser: rstlvbanlist.h
|
||||
*
|
||||
* RetroShare Serialiser.
|
||||
*
|
||||
* Copyright 2011 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
/*******************************************************************
|
||||
* These are the Compound TLV structures that must be (un)packed.
|
||||
******************************************************************/
|
||||
|
||||
#include <map>
|
||||
#include "serialiser/rstlvtypes.h"
|
||||
#include "util/rsnet.h"
|
||||
|
||||
#define RSDSDV_MAX_ROUTE_TABLE 1000
|
||||
|
||||
class RsTlvBanListEntry: public RsTlvItem
|
||||
{
|
||||
public:
|
||||
RsTlvBanListEntry();
|
||||
virtual ~RsTlvBanListEntry() { return; }
|
||||
virtual uint32_t TlvSize();
|
||||
virtual void TlvClear();
|
||||
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
|
||||
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
|
||||
virtual std::ostream &print(std::ostream &out, uint16_t indent);
|
||||
|
||||
struct sockaddr_in addr;
|
||||
uint32_t level;
|
||||
uint32_t reason;
|
||||
uint32_t age;
|
||||
};
|
||||
|
||||
class RsTlvBanList: public RsTlvItem
|
||||
{
|
||||
public:
|
||||
RsTlvBanList();
|
||||
virtual ~RsTlvBanList() { return; }
|
||||
virtual uint32_t TlvSize();
|
||||
virtual void TlvClear();
|
||||
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
|
||||
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
|
||||
virtual std::ostream &print(std::ostream &out, uint16_t indent);
|
||||
|
||||
std::list<RsTlvBanListEntry> entries;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -184,6 +184,8 @@ const uint16_t TLV_TYPE_BIN_FILEDATA = 0x0140; /* Used - ACTIVE! */
|
||||
|
||||
const uint16_t TLV_TYPE_BIN_SERIALISE = 0x0150; /* Used (Generic - Distrib) */
|
||||
|
||||
const uint16_t TLV_TYPE_BIN_GENERIC = 0x0160; /* Used (DSDV Data) */
|
||||
|
||||
|
||||
/**** Compound Types ****/
|
||||
const uint16_t TLV_TYPE_FILEITEM = 0x1000;
|
||||
@ -210,9 +212,12 @@ const uint16_t TLV_TYPE_IMAGE = 0x1060;
|
||||
const uint16_t TLV_TYPE_ADDRESS_INFO = 0x1070;
|
||||
const uint16_t TLV_TYPE_ADDRESS_SET = 0x1071;
|
||||
|
||||
const uint16_t TLV_TYPE_DSDV_ENDPOINT = 0x1080;
|
||||
const uint16_t TLV_TYPE_DSDV_ENTRY = 0x1081;
|
||||
const uint16_t TLV_TYPE_DSDV_ENTRY_SET= 0x1082;
|
||||
|
||||
|
||||
|
||||
const uint16_t TLV_TYPE_BAN_ENTRY = 0x1090;
|
||||
const uint16_t TLV_TYPE_BAN_LIST = 0x1091;
|
||||
|
||||
|
||||
const uint32_t RSTLV_IMAGE_TYPE_PNG = 0x0001;
|
||||
|
426
libretroshare/src/serialiser/rstlvdsdv.cc
Normal file
426
libretroshare/src/serialiser/rstlvdsdv.cc
Normal file
@ -0,0 +1,426 @@
|
||||
|
||||
/*
|
||||
* libretroshare/src/serialiser: rstlvtypes.cc
|
||||
*
|
||||
* RetroShare Serialiser.
|
||||
*
|
||||
* Copyright 2007-2008 by Robert Fernie, Chris Parker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "rstlvdsdv.h"
|
||||
|
||||
#include "rstlvbase.h"
|
||||
#include "rstlvtypes.h"
|
||||
#include "rsbaseserial.h"
|
||||
#include "util/rsprint.h"
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
/************************************* RsTlvDsdvEndPoint ************************************/
|
||||
|
||||
RsTlvDsdvEndPoint::RsTlvDsdvEndPoint()
|
||||
:RsTlvItem(), idType(0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void RsTlvDsdvEndPoint::TlvClear()
|
||||
{
|
||||
idType = 0;
|
||||
anonChunk.clear();
|
||||
serviceId.clear();
|
||||
}
|
||||
|
||||
uint32_t RsTlvDsdvEndPoint::TlvSize()
|
||||
{
|
||||
uint32_t s = TLV_HEADER_SIZE; /* header + 4 + str + str */
|
||||
|
||||
s += 4; // idType;
|
||||
s += GetTlvStringSize(anonChunk);
|
||||
s += GetTlvStringSize(serviceId);
|
||||
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
bool RsTlvDsdvEndPoint::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
|
||||
{
|
||||
/* must check sizes */
|
||||
uint32_t tlvsize = TlvSize();
|
||||
uint32_t tlvend = *offset + tlvsize;
|
||||
|
||||
if (size < tlvend)
|
||||
return false; /* not enough space */
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* start at data[offset] */
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_DSDV_ENDPOINT, tlvsize);
|
||||
|
||||
ok &= setRawUInt32(data, tlvend, offset, idType);
|
||||
ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, anonChunk);
|
||||
ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_HASH_SHA1, serviceId);
|
||||
return ok;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool RsTlvDsdvEndPoint::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
|
||||
{
|
||||
if (size < *offset + TLV_HEADER_SIZE)
|
||||
return false;
|
||||
|
||||
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
|
||||
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
|
||||
uint32_t tlvend = *offset + tlvsize;
|
||||
|
||||
if (size < tlvend) /* check size */
|
||||
return false; /* not enough space */
|
||||
|
||||
if (tlvtype != TLV_TYPE_DSDV_ENDPOINT) /* check type */
|
||||
return false;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* ready to load */
|
||||
TlvClear();
|
||||
|
||||
/* skip the header */
|
||||
(*offset) += TLV_HEADER_SIZE;
|
||||
|
||||
ok &= getRawUInt32(data, tlvend, offset, &(idType));
|
||||
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, anonChunk);
|
||||
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_HASH_SHA1, serviceId);
|
||||
|
||||
/***************************************************************************
|
||||
* NB: extra components could be added (for future expansion of the type).
|
||||
* or be present (if this code is reading an extended version).
|
||||
*
|
||||
* We must chew up the extra characters to conform with TLV specifications
|
||||
***************************************************************************/
|
||||
if (*offset != tlvend)
|
||||
{
|
||||
#ifdef TLV_DEBUG
|
||||
std::cerr << "RsTlvDsdvEndPoint::GetTlv() Warning extra bytes at end of item";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
*offset = tlvend;
|
||||
}
|
||||
|
||||
return ok;
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::ostream &RsTlvDsdvEndPoint::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printBase(out, "RsTlvDsdvEndPoint", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "idType:" << idType;
|
||||
out << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "AnonChunk:" << anonChunk;
|
||||
out << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "ServiceId:" << serviceId;
|
||||
out << std::endl;
|
||||
|
||||
printEnd(out, "RsTlvDsdvEndPoint", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/************************************* RsTlvDsdvEntry ************************************/
|
||||
|
||||
RsTlvDsdvEntry::RsTlvDsdvEntry()
|
||||
:RsTlvItem(), sequence(0), distance(0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void RsTlvDsdvEntry::TlvClear()
|
||||
{
|
||||
endPoint.TlvClear();
|
||||
sequence = 0;
|
||||
distance = 0;
|
||||
}
|
||||
|
||||
uint32_t RsTlvDsdvEntry::TlvSize()
|
||||
{
|
||||
uint32_t s = TLV_HEADER_SIZE; /* header + EndPoint.Size + 4 + 4 */
|
||||
|
||||
s += endPoint.TlvSize();
|
||||
s += 4; // sequence;
|
||||
s += 4; // distance;
|
||||
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
bool RsTlvDsdvEntry::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
|
||||
{
|
||||
/* must check sizes */
|
||||
uint32_t tlvsize = TlvSize();
|
||||
uint32_t tlvend = *offset + tlvsize;
|
||||
|
||||
if (size < tlvend)
|
||||
return false; /* not enough space */
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* start at data[offset] */
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_DSDV_ENTRY, tlvsize);
|
||||
|
||||
ok &= endPoint.SetTlv(data, size, offset);
|
||||
ok &= setRawUInt32(data, tlvend, offset, sequence);
|
||||
ok &= setRawUInt32(data, tlvend, offset, distance);
|
||||
|
||||
return ok;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool RsTlvDsdvEntry::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
|
||||
{
|
||||
if (size < *offset + TLV_HEADER_SIZE)
|
||||
return false;
|
||||
|
||||
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
|
||||
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
|
||||
uint32_t tlvend = *offset + tlvsize;
|
||||
|
||||
if (size < tlvend) /* check size */
|
||||
return false; /* not enough space */
|
||||
|
||||
if (tlvtype != TLV_TYPE_DSDV_ENTRY) /* check type */
|
||||
return false;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* ready to load */
|
||||
TlvClear();
|
||||
|
||||
/* skip the header */
|
||||
(*offset) += TLV_HEADER_SIZE;
|
||||
|
||||
ok &= endPoint.GetTlv(data, size, offset);
|
||||
ok &= getRawUInt32(data, tlvend, offset, &(sequence));
|
||||
ok &= getRawUInt32(data, tlvend, offset, &(distance));
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* NB: extra components could be added (for future expansion of the type).
|
||||
* or be present (if this code is reading an extended version).
|
||||
*
|
||||
* We must chew up the extra characters to conform with TLV specifications
|
||||
***************************************************************************/
|
||||
if (*offset != tlvend)
|
||||
{
|
||||
#ifdef TLV_DEBUG
|
||||
std::cerr << "RsTlvDsdvEntry::GetTlv() Warning extra bytes at end of item";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
*offset = tlvend;
|
||||
}
|
||||
|
||||
return ok;
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::ostream &RsTlvDsdvEntry::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printBase(out, "RsTlvDsdvEntry", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
endPoint.print(out, int_Indent);
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "Sequence:" << sequence;
|
||||
out << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "Distance:" << distance;
|
||||
out << std::endl;
|
||||
|
||||
printEnd(out, "RsTlvDsdvEntry", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/************************************* RsTlvDsdvEntrySet ************************************/
|
||||
|
||||
RsTlvDsdvEntrySet::RsTlvDsdvEntrySet()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RsTlvDsdvEntrySet::TlvClear()
|
||||
{
|
||||
entries.clear();
|
||||
}
|
||||
|
||||
uint32_t RsTlvDsdvEntrySet::TlvSize()
|
||||
{
|
||||
|
||||
uint32_t s = TLV_HEADER_SIZE; /* header */
|
||||
|
||||
std::list<RsTlvDsdvEntry>::iterator it;
|
||||
|
||||
|
||||
if(!entries.empty())
|
||||
{
|
||||
|
||||
for(it = entries.begin(); it != entries.end() ; ++it)
|
||||
s += it->TlvSize();
|
||||
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
bool RsTlvDsdvEntrySet::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
|
||||
{
|
||||
/* must check sizes */
|
||||
uint32_t tlvsize = TlvSize();
|
||||
uint32_t tlvend = *offset + tlvsize;
|
||||
|
||||
if (size < tlvend)
|
||||
return false; /* not enough space */
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* start at data[offset] */
|
||||
ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_DSDV_ENTRY_SET , tlvsize);
|
||||
|
||||
if(!entries.empty())
|
||||
{
|
||||
std::list<RsTlvDsdvEntry>::iterator it;
|
||||
|
||||
for(it = entries.begin(); it != entries.end() ; ++it)
|
||||
ok &= it->SetTlv(data, size, offset);
|
||||
}
|
||||
|
||||
|
||||
return ok;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool RsTlvDsdvEntrySet::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
|
||||
{
|
||||
if (size < *offset + TLV_HEADER_SIZE)
|
||||
return false;
|
||||
|
||||
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
|
||||
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
|
||||
uint32_t tlvend = *offset + tlvsize;
|
||||
|
||||
if (size < tlvend) /* check size */
|
||||
return false; /* not enough space */
|
||||
|
||||
if (tlvtype != TLV_TYPE_DSDV_ENTRY_SET) /* check type */
|
||||
return false;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* ready to load */
|
||||
TlvClear();
|
||||
|
||||
/* skip the header */
|
||||
(*offset) += TLV_HEADER_SIZE;
|
||||
|
||||
/* while there is TLV */
|
||||
while((*offset) + 2 < tlvend)
|
||||
{
|
||||
/* get the next type */
|
||||
uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
|
||||
|
||||
switch(tlvsubtype)
|
||||
{
|
||||
case TLV_TYPE_DSDV_ENTRY:
|
||||
{
|
||||
RsTlvDsdvEntry entry;
|
||||
ok &= entry.GetTlv(data, size, offset);
|
||||
if (ok)
|
||||
{
|
||||
entries.push_back(entry);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ok &= SkipUnknownTlv(data, tlvend, offset);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* NB: extra components could be added (for future expansion of the type).
|
||||
* or be present (if this code is reading an extended version).
|
||||
*
|
||||
* We must chew up the extra characters to conform with TLV specifications
|
||||
***************************************************************************/
|
||||
if (*offset != tlvend)
|
||||
{
|
||||
#ifdef TLV_DEBUG
|
||||
std::cerr << "RsTlvDsdvEntrySet::GetTlv() Warning extra bytes at end of item";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
*offset = tlvend;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
// prints out contents of RsTlvDsdvEntrySet
|
||||
std::ostream &RsTlvDsdvEntrySet::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printBase(out, "RsTlvDsdvEntrySet", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
std::list<RsTlvDsdvEntry>::iterator it;
|
||||
for(it = entries.begin(); it != entries.end() ; ++it)
|
||||
it->print(out, int_Indent);
|
||||
|
||||
printEnd(out, "RsTlvDsdvEntrySet", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/************************************* RsTlvIpAddressInfo ************************************/
|
||||
|
||||
|
87
libretroshare/src/serialiser/rstlvdsdv.h
Normal file
87
libretroshare/src/serialiser/rstlvdsdv.h
Normal file
@ -0,0 +1,87 @@
|
||||
#ifndef RS_TLV_DSDV_TYPES_H
|
||||
#define RS_TLV_DSDV_TYPES_H
|
||||
|
||||
/*
|
||||
* libretroshare/src/serialiser: rstlvdsdv.h
|
||||
*
|
||||
* RetroShare Serialiser.
|
||||
*
|
||||
* Copyright 2011 by Robert Fernie
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
/*******************************************************************
|
||||
* These are the Compound TLV structures that must be (un)packed.
|
||||
******************************************************************/
|
||||
|
||||
#include <map>
|
||||
#include "serialiser/rstlvtypes.h"
|
||||
#include "util/rsnet.h"
|
||||
|
||||
#define RSDSDV_MAX_ROUTE_TABLE 1000
|
||||
|
||||
class RsTlvDsdvEndPoint: public RsTlvItem
|
||||
{
|
||||
public:
|
||||
RsTlvDsdvEndPoint();
|
||||
virtual ~RsTlvDsdvEndPoint() { return; }
|
||||
virtual uint32_t TlvSize();
|
||||
virtual void TlvClear();
|
||||
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
|
||||
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
|
||||
virtual std::ostream &print(std::ostream &out, uint16_t indent);
|
||||
|
||||
uint32_t idType;
|
||||
std::string anonChunk;
|
||||
std::string serviceId;
|
||||
};
|
||||
|
||||
class RsTlvDsdvEntry: public RsTlvItem
|
||||
{
|
||||
public:
|
||||
RsTlvDsdvEntry();
|
||||
virtual ~RsTlvDsdvEntry() { return; }
|
||||
virtual uint32_t TlvSize();
|
||||
virtual void TlvClear();
|
||||
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
|
||||
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
|
||||
virtual std::ostream &print(std::ostream &out, uint16_t indent);
|
||||
|
||||
RsTlvDsdvEndPoint endPoint;
|
||||
uint32_t sequence;
|
||||
uint32_t distance;
|
||||
};
|
||||
|
||||
class RsTlvDsdvEntrySet: public RsTlvItem
|
||||
{
|
||||
public:
|
||||
RsTlvDsdvEntrySet();
|
||||
virtual ~RsTlvDsdvEntrySet() { return; }
|
||||
virtual uint32_t TlvSize();
|
||||
virtual void TlvClear();
|
||||
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
|
||||
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
|
||||
virtual std::ostream &print(std::ostream &out, uint16_t indent);
|
||||
|
||||
std::list<RsTlvDsdvEntry> entries;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
463
libretroshare/src/services/p3banlist.cc
Normal file
463
libretroshare/src/services/p3banlist.cc
Normal file
@ -0,0 +1,463 @@
|
||||
/*
|
||||
* libretroshare/src/services p3banlist.cc
|
||||
*
|
||||
* Ban List Service for RetroShare.
|
||||
*
|
||||
* Copyright 2011-2011 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pqi/p3linkmgr.h"
|
||||
#include "pqi/p3netmgr.h"
|
||||
|
||||
#include "util/rsnet.h"
|
||||
|
||||
#include "services/p3banlist.h"
|
||||
#include "serialiser/rsbanlistitems.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
/****
|
||||
* #define DEBUG_BANLIST 1
|
||||
****/
|
||||
|
||||
#define DEBUG_BANLIST 1
|
||||
|
||||
|
||||
/* DEFINE INTERFACE POINTER! */
|
||||
//RsBanList *rsBanList = NULL;
|
||||
|
||||
#define RSBANLIST_ENTRY_MAX_AGE (60 * 60 * 1) // 1 HOURS
|
||||
#define RSBANLIST_SEND_PERIOD 600 // 10 Minutes.
|
||||
|
||||
#define RSBANLIST_SOURCE_SELF 0
|
||||
#define RSBANLIST_SOURCE_FRIEND 1
|
||||
#define RSBANLIST_SOURCE_FOF 2
|
||||
|
||||
|
||||
/************ IMPLEMENTATION NOTES *********************************
|
||||
*
|
||||
* Get Bad Peers passed to us (from DHT mainly).
|
||||
* we distribute and track the network list of bad peers.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
p3BanList::p3BanList(p3LinkMgr *lm, p3NetMgr *nm)
|
||||
:p3Service(RS_SERVICE_TYPE_BANLIST), mBanMtx("p3BanList"), mLinkMgr(lm), mNetMgr(nm)
|
||||
{
|
||||
addSerialType(new RsBanListSerialiser());
|
||||
|
||||
mSentListTime = 0;
|
||||
}
|
||||
|
||||
|
||||
int p3BanList::tick()
|
||||
{
|
||||
processIncoming();
|
||||
sendPackets();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int p3BanList::status()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/***** Implementation ******/
|
||||
|
||||
bool p3BanList::processIncoming()
|
||||
{
|
||||
/* for each packet - pass to specific handler */
|
||||
RsItem *item = NULL;
|
||||
bool updated = false;
|
||||
while(NULL != (item = recvItem()))
|
||||
{
|
||||
#ifdef DEBUG_BANLIST
|
||||
std::cerr << "p3BanList::processingIncoming() Received Item:";
|
||||
std::cerr << std::endl;
|
||||
item->print(std::cerr);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
switch(item->PacketSubType())
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case RS_PKT_SUBTYPE_BANLIST_ITEM:
|
||||
{
|
||||
updated = (updated || recvBanItem((RsBanListItem *) item));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
delete item;
|
||||
}
|
||||
|
||||
if (updated)
|
||||
{
|
||||
{
|
||||
RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
mBanSet.clear();
|
||||
condenseBanSources_locked();
|
||||
}
|
||||
|
||||
/* pass list to NetAssist */
|
||||
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
bool p3BanList::recvBanItem(RsBanListItem *item)
|
||||
{
|
||||
bool updated = false;
|
||||
|
||||
std::list<RsTlvBanListEntry>::const_iterator it;
|
||||
for(it = item->peerList.entries.begin(); it != item->peerList.entries.end(); it++)
|
||||
{
|
||||
updated = (updated || addBanEntry(item->PeerId(),
|
||||
it->addr, it->level, it->reason, it->age));
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
/* overloaded from pqiNetAssistSharePeer */
|
||||
void p3BanList::updatePeer(std::string id, struct sockaddr_in addr, int type, int reason, int age)
|
||||
{
|
||||
std::string ownId = mLinkMgr->getOwnId();
|
||||
|
||||
int int_reason = 0;
|
||||
addBanEntry(ownId, addr, RSBANLIST_SOURCE_SELF, int_reason, age);
|
||||
|
||||
/* process */
|
||||
{
|
||||
RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
mBanSet.clear();
|
||||
condenseBanSources_locked();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool p3BanList::addBanEntry(const std::string &peerId, const struct sockaddr_in &addr, uint32_t level, uint32_t reason, uint32_t age)
|
||||
{
|
||||
RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
time_t now = time(NULL);
|
||||
bool updated = false;
|
||||
|
||||
#ifdef DEBUG_BANLIST
|
||||
std::cerr << "p3BanList::addBanEntry() Addr: " << rs_inet_ntoa(addr.sin_addr) << " Level: " << level;
|
||||
std::cerr << " Reason: " << reason << " Age: " << age;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::map<std::string, BanList>::iterator it;
|
||||
it = mBanSources.find(peerId);
|
||||
if (it == mBanSources.end())
|
||||
{
|
||||
BanList bl;
|
||||
bl.mPeerId = peerId;
|
||||
bl.mLastUpdate = now;
|
||||
mBanSources[peerId] = bl;
|
||||
|
||||
it = mBanSources.find(peerId);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
std::map<uint32_t, BanListPeer>::iterator mit;
|
||||
mit = it->second.mBanPeers.find(addr.sin_addr.s_addr);
|
||||
if (mit == it->second.mBanPeers.end())
|
||||
{
|
||||
/* add in */
|
||||
BanListPeer blp;
|
||||
blp.addr = addr;
|
||||
blp.reason = reason;
|
||||
blp.level = level;
|
||||
blp.mTs = now - age;
|
||||
|
||||
it->second.mBanPeers[addr.sin_addr.s_addr] = blp;
|
||||
it->second.mLastUpdate = now;
|
||||
updated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* see if it needs an update */
|
||||
if ((mit->second.reason != reason) ||
|
||||
(mit->second.level != level) ||
|
||||
(mit->second.mTs < now - age))
|
||||
{
|
||||
/* update */
|
||||
mit->second.addr = addr;
|
||||
mit->second.reason = reason;
|
||||
mit->second.level = level;
|
||||
mit->second.mTs = now - age;
|
||||
|
||||
it->second.mLastUpdate = now;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
int p3BanList::condenseBanSources_locked()
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
std::string ownId = mLinkMgr->getOwnId();
|
||||
|
||||
#ifdef DEBUG_BANLIST
|
||||
std::cerr << "p3BanList::condenseBanSources_locked()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::map<std::string, BanList>::const_iterator it;
|
||||
for(it = mBanSources.begin(); it != mBanSources.end(); it++)
|
||||
{
|
||||
if (now - it->second.mLastUpdate > RSBANLIST_ENTRY_MAX_AGE)
|
||||
{
|
||||
#ifdef DEBUG_BANLIST
|
||||
std::cerr << "p3BanList::condenseBanSources_locked()";
|
||||
std::cerr << " Ignoring Out-Of-Date peer: " << it->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_BANLIST
|
||||
std::cerr << "p3BanList::condenseBanSources_locked()";
|
||||
std::cerr << " Condensing Info from peer: " << it->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::map<uint32_t, BanListPeer>::const_iterator lit;
|
||||
for(lit = it->second.mBanPeers.begin();
|
||||
lit != it->second.mBanPeers.end(); lit++)
|
||||
{
|
||||
/* check timestamp */
|
||||
if (now - lit->second.mTs > RSBANLIST_ENTRY_MAX_AGE)
|
||||
{
|
||||
#ifdef DEBUG_BANLIST
|
||||
std::cerr << "p3BanList::condenseBanSources_locked()";
|
||||
std::cerr << " Ignoring Out-Of-Date Entry for: ";
|
||||
std::cerr << rs_inet_ntoa(lit->second.addr.sin_addr);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
int lvl = lit->second.level;
|
||||
if (it->first != ownId)
|
||||
{
|
||||
/* as from someone else, increment level */
|
||||
lvl++;
|
||||
}
|
||||
|
||||
/* check if it exists in the Set already */
|
||||
std::map<uint32_t, BanListPeer>::iterator sit;
|
||||
sit = mBanSet.find(lit->second.addr.sin_addr.s_addr);
|
||||
if ((sit == mBanSet.end()) || (lvl < sit->second.level))
|
||||
{
|
||||
BanListPeer bp = lit->second;
|
||||
bp.level = lvl;
|
||||
bp.addr.sin_port = 0;
|
||||
mBanSet[lit->second.addr.sin_addr.s_addr] = bp;
|
||||
#ifdef DEBUG_BANLIST
|
||||
std::cerr << "p3BanList::condenseBanSources_locked()";
|
||||
std::cerr << " Added New Entry for: ";
|
||||
std::cerr << rs_inet_ntoa(lit->second.addr.sin_addr);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_BANLIST
|
||||
std::cerr << "p3BanList::condenseBanSources_locked()";
|
||||
std::cerr << " Merging Info for: ";
|
||||
std::cerr << rs_inet_ntoa(lit->second.addr.sin_addr);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* update if necessary */
|
||||
if (lvl == sit->second.level)
|
||||
{
|
||||
sit->second.reason |= lit->second.reason;
|
||||
if (sit->second.mTs < lit->second.mTs)
|
||||
{
|
||||
sit->second.mTs = lit->second.mTs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_BANLIST
|
||||
std::cerr << "p3BanList::condenseBanSources_locked() Printing New Set:";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
printBanSet_locked(std::cerr);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int p3BanList::sendPackets()
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
time_t pt;
|
||||
{
|
||||
RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/
|
||||
pt = mSentListTime;
|
||||
}
|
||||
|
||||
if (now - pt > RSBANLIST_SEND_PERIOD)
|
||||
{
|
||||
sendBanLists();
|
||||
|
||||
RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
std::cerr << "p3BanList::sendPackets() Regular Broadcast";
|
||||
std::cerr << std::endl;
|
||||
|
||||
printBanSources_locked(std::cerr);
|
||||
printBanSet_locked(std::cerr);
|
||||
|
||||
mSentListTime = now;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
void p3BanList::sendBanLists()
|
||||
{
|
||||
|
||||
/* we ping our peers */
|
||||
/* who is online? */
|
||||
std::list<std::string> idList;
|
||||
|
||||
mLinkMgr->getOnlineList(idList);
|
||||
|
||||
#ifdef DEBUG_BANLIST
|
||||
std::cerr << "p3BanList::sendBanList()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* prepare packets */
|
||||
std::list<std::string>::iterator it;
|
||||
for(it = idList.begin(); it != idList.end(); it++)
|
||||
{
|
||||
#ifdef DEBUG_BANLIST
|
||||
std::cerr << "p3VoRS::sendBanList() To: " << *it;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
sendBanSet(*it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int p3BanList::sendBanSet(std::string peerid)
|
||||
{
|
||||
/* */
|
||||
RsBanListItem *item = new RsBanListItem();
|
||||
item->PeerId(peerid);
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
{
|
||||
RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/
|
||||
std::map<uint32_t, BanListPeer>::iterator it;
|
||||
for(it = mBanSet.begin(); it != mBanSet.end(); it++)
|
||||
{
|
||||
if (it->second.level > RSBANLIST_SOURCE_FRIEND)
|
||||
{
|
||||
continue; // only share OWN and FRIENDS.
|
||||
}
|
||||
|
||||
RsTlvBanListEntry bi;
|
||||
bi.addr = it->second.addr;
|
||||
bi.reason = it->second.reason;
|
||||
bi.level = it->second.level;
|
||||
bi.age = now - it->second.mTs;
|
||||
|
||||
item->peerList.entries.push_back(bi);
|
||||
}
|
||||
}
|
||||
|
||||
sendItem(item);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int p3BanList::printBanSet_locked(std::ostream &out)
|
||||
{
|
||||
out << "p3BanList::printBanSet_locked()";
|
||||
out << std::endl;
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
std::map<uint32_t, BanListPeer>::iterator it;
|
||||
for(it = mBanSet.begin(); it != mBanSet.end(); it++)
|
||||
{
|
||||
out << "Ban: " << rs_inet_ntoa(it->second.addr.sin_addr);
|
||||
out << " Reason: " << it->second.reason;
|
||||
out << " Level: " << it->second.level;
|
||||
if (it->second.level > RSBANLIST_SOURCE_FRIEND)
|
||||
{
|
||||
out << " (unused)";
|
||||
}
|
||||
|
||||
out << " Age: " << now - it->second.mTs;
|
||||
out << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int p3BanList::printBanSources_locked(std::ostream &out)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
std::map<std::string, BanList>::const_iterator it;
|
||||
for(it = mBanSources.begin(); it != mBanSources.end(); it++)
|
||||
{
|
||||
out << "BanList from: " << it->first;
|
||||
out << " LastUpdate: " << now - it->second.mLastUpdate;
|
||||
out << std::endl;
|
||||
|
||||
std::map<uint32_t, BanListPeer>::const_iterator lit;
|
||||
for(lit = it->second.mBanPeers.begin();
|
||||
lit != it->second.mBanPeers.end(); lit++)
|
||||
{
|
||||
out << "\t";
|
||||
out << "Ban: " << rs_inet_ntoa(lit->second.addr.sin_addr);
|
||||
out << " Reason: " << lit->second.reason;
|
||||
out << " Level: " << lit->second.level;
|
||||
out << " Age: " << now - lit->second.mTs;
|
||||
out << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
134
libretroshare/src/services/p3banlist.h
Normal file
134
libretroshare/src/services/p3banlist.h
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* libretroshare/src/services/p3banlist.h
|
||||
*
|
||||
* Exchange list of Peers for Banning / Whitelisting.
|
||||
*
|
||||
* Copyright 2011 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SERVICE_RSBANLIST_HEADER
|
||||
#define SERVICE_RSBANLIST_HEADER
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include "serialiser/rsbanlistitems.h"
|
||||
#include "services/p3service.h"
|
||||
//#include "retroshare/rsbanlist.h"
|
||||
|
||||
class p3LinkMgr;
|
||||
class p3NetMgr;
|
||||
|
||||
class BanListPeer
|
||||
{
|
||||
public:
|
||||
|
||||
struct sockaddr_in addr;
|
||||
uint32_t reason; // Dup Self, Dup Friend
|
||||
int level; // LOCAL, FRIEND, FoF.
|
||||
time_t mTs;
|
||||
};
|
||||
|
||||
class BanList
|
||||
{
|
||||
public:
|
||||
|
||||
std::string mPeerId; /* from */
|
||||
time_t mLastUpdate;
|
||||
std::map<uint32_t, BanListPeer> mBanPeers;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//!The RS BanList service.
|
||||
/**
|
||||
*
|
||||
* Exchange list of Banned IP addresses with peers.
|
||||
*/
|
||||
|
||||
class p3BanList: /* public RsBanList, */ public p3Service, public pqiNetAssistPeerShare /* , public p3Config, public pqiMonitor */
|
||||
{
|
||||
public:
|
||||
p3BanList(p3LinkMgr *lm, p3NetMgr *nm);
|
||||
|
||||
/***** overloaded from RsBanList *****/
|
||||
|
||||
/***** overloaded from pqiNetAssistPeerShare *****/
|
||||
|
||||
virtual void updatePeer(std::string id, struct sockaddr_in addr, int type, int reason, int age);
|
||||
|
||||
|
||||
/***** overloaded from p3Service *****/
|
||||
/*!
|
||||
* This retrieves all chat msg items and also (important!)
|
||||
* processes chat-status items that are in service item queue. chat msg item requests are also processed and not returned
|
||||
* (important! also) notifications sent to notify base on receipt avatar, immediate status and custom status
|
||||
* : notifyCustomState, notifyChatStatus, notifyPeerHasNewAvatar
|
||||
* @see NotifyBase
|
||||
|
||||
*/
|
||||
virtual int tick();
|
||||
virtual int status();
|
||||
|
||||
int sendPackets();
|
||||
bool processIncoming();
|
||||
|
||||
bool recvBanItem(RsBanListItem *item);
|
||||
bool addBanEntry(const std::string &peerId, const struct sockaddr_in &addr,
|
||||
uint32_t level, uint32_t reason, uint32_t age);
|
||||
void sendBanLists();
|
||||
int sendBanSet(std::string peerid);
|
||||
|
||||
|
||||
/*!
|
||||
* Interface stuff.
|
||||
*/
|
||||
|
||||
/*************** pqiMonitor callback ***********************/
|
||||
//virtual void statusChange(const std::list<pqipeer> &plist);
|
||||
|
||||
|
||||
/************* from p3Config *******************/
|
||||
//virtual RsSerialiser *setupSerialiser() ;
|
||||
//virtual bool saveList(bool& cleanup, std::list<RsItem*>&) ;
|
||||
//virtual void saveDone();
|
||||
//virtual bool loadList(std::list<RsItem*>& load) ;
|
||||
|
||||
|
||||
private:
|
||||
RsMutex mBanMtx;
|
||||
|
||||
int condenseBanSources_locked();
|
||||
int printBanSources_locked(std::ostream &out);
|
||||
int printBanSet_locked(std::ostream &out);
|
||||
|
||||
time_t mSentListTime;
|
||||
std::map<std::string, BanList> mBanSources;
|
||||
std::map<uint32_t, BanListPeer> mBanSet;
|
||||
|
||||
p3LinkMgr *mLinkMgr;
|
||||
p3NetMgr *mNetMgr;
|
||||
|
||||
};
|
||||
|
||||
#endif // SERVICE_RSBANLIST_HEADER
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "pqi/p3peermgr.h"
|
||||
#include "pqi/p3linkmgr.h"
|
||||
#include "pqi/p3netmgr.h"
|
||||
|
||||
#include "pqi/authssl.h"
|
||||
#include "pqi/authgpg.h"
|
||||
@ -78,10 +79,10 @@ const uint32_t P3DISC_FLAGS_ASK_VERSION = 0x0080;
|
||||
******************************************************************************************
|
||||
*****************************************************************************************/
|
||||
|
||||
p3disc::p3disc(p3PeerMgr *pm, p3LinkMgr *lm, pqipersongrp *pqih)
|
||||
p3disc::p3disc(p3PeerMgr *pm, p3LinkMgr *lm, p3NetMgr *nm, pqipersongrp *pqih)
|
||||
:p3Service(RS_SERVICE_TYPE_DISC),
|
||||
p3Config(CONFIG_TYPE_P3DISC),
|
||||
mPeerMgr(pm), mLinkMgr(lm),
|
||||
mPeerMgr(pm), mLinkMgr(lm), mNetMgr(nm),
|
||||
mPqiPersonGrp(pqih), mDiscMtx("p3disc")
|
||||
{
|
||||
RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/
|
||||
@ -711,6 +712,17 @@ void p3disc::recvPeerDetails(RsDiscReply *item, const std::string &certGpgId)
|
||||
/* skip if not one of our peers */
|
||||
if (!mPeerMgr->isFriend(pit->pid))
|
||||
{
|
||||
/* THESE ARE OUR FRIEND OF FRIENDS ... pass this information along to NetMgr & DHT...
|
||||
* as we can track FOF and use them as potential Proxies / Relays
|
||||
*/
|
||||
|
||||
/* add into NetMgr and non-search, so we can detect connect attempts */
|
||||
mNetMgr->netAssistFriend(pit->pid,false);
|
||||
|
||||
/* inform NetMgr that we know this peer */
|
||||
mNetMgr->netAssistKnownPeer(pit->pid, pit->currentremoteaddr,
|
||||
NETASSIST_KNOWN_PEER_FOF | NETASSIST_KNOWN_PEER_OFFLINE);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,7 @@ class autoneighbour: public autoserver
|
||||
|
||||
class p3PeerMgr;
|
||||
class p3LinkMgr;
|
||||
class p3NetMgr;
|
||||
|
||||
|
||||
class p3disc: public p3Service, public pqiMonitor, public p3Config, public AuthGPGService
|
||||
@ -81,7 +82,7 @@ class p3disc: public p3Service, public pqiMonitor, public p3Config, public AuthG
|
||||
public:
|
||||
|
||||
|
||||
p3disc(p3PeerMgr *pm, p3LinkMgr *lm, pqipersongrp *persGrp);
|
||||
p3disc(p3PeerMgr *pm, p3LinkMgr *lm, p3NetMgr *nm, pqipersongrp *persGrp);
|
||||
|
||||
/************* from pqiMonitor *******************/
|
||||
virtual void statusChange(const std::list<pqipeer> &plist);
|
||||
@ -145,6 +146,7 @@ int idServers();
|
||||
|
||||
p3PeerMgr *mPeerMgr;
|
||||
p3LinkMgr *mLinkMgr;
|
||||
p3NetMgr *mNetMgr;
|
||||
|
||||
pqipersongrp *mPqiPersonGrp;
|
||||
|
||||
|
899
libretroshare/src/services/p3dsdv.cc
Normal file
899
libretroshare/src/services/p3dsdv.cc
Normal file
@ -0,0 +1,899 @@
|
||||
/*
|
||||
* libretroshare/src/services/p3dsdv.h
|
||||
*
|
||||
* Network-Wide Routing Service.
|
||||
*
|
||||
* Copyright 2011 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
//#include "serialiser/rsdsdvitems.h"
|
||||
#include "services/p3dsdv.h"
|
||||
#include "pqi/p3linkmgr.h"
|
||||
#include "util/rsrandom.h"
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
/****
|
||||
* #define DEBUG_DSDV 1
|
||||
****/
|
||||
#define DEBUG_DSDV 1
|
||||
|
||||
/* DEFINE INTERFACE POINTER! */
|
||||
RsDsdv *rsDsdv = NULL;
|
||||
|
||||
/*****
|
||||
* Routing Services are provided for any service or peer that wants to access / receive info
|
||||
* over the internal network.
|
||||
*
|
||||
* This is going to be based loosely on Ben's Algorithm...
|
||||
* Each Service / Peer is identified by a HASH.
|
||||
* This HASH is disguised by a temporary ANON-CHUNK.
|
||||
* DSDVID = Sha1(ANONCHUNK + HASH).
|
||||
*
|
||||
* Each peer can advertise as many Services as they want.
|
||||
* The Anon-chunk should be rotated regularly to hide it well.
|
||||
* period to be defined.
|
||||
*
|
||||
*
|
||||
* Once this Routing table has been established, Routes can be created - in a similar manner to turtle paths.
|
||||
* (Send Path request (Path Id + Origin + Destination))... path is established.
|
||||
*
|
||||
* Then we can do Onion Routing etc, on top of this.
|
||||
*
|
||||
****/
|
||||
|
||||
p3Dsdv::p3Dsdv(p3LinkMgr *lm)
|
||||
:p3Service(RS_SERVICE_TYPE_DSDV), /* p3Config(CONFIG_TYPE_DSDV), */ mDsdvMtx("p3Dsdv"), mLinkMgr(lm)
|
||||
{
|
||||
addSerialType(new RsDsdvSerialiser());
|
||||
|
||||
mSentTablesTime = 0;
|
||||
mSentIncrementTime = 0;
|
||||
}
|
||||
|
||||
int p3Dsdv::tick()
|
||||
{
|
||||
processIncoming();
|
||||
sendTables();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int p3Dsdv::status()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define DSDV_BROADCAST_PERIOD (60*10) // 10 Minutes.
|
||||
#define DSDV_MIN_INCREMENT_PERIOD 5
|
||||
#define DSDV_DISCARD_PERIOD (DSDV_BROADCAST_PERIOD * 2)
|
||||
|
||||
int p3Dsdv::sendTables()
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
time_t tt, it;
|
||||
bool updateRequired = false;
|
||||
{
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
tt = mSentTablesTime;
|
||||
it = mSentIncrementTime;
|
||||
updateRequired = mSignificantChanges;
|
||||
}
|
||||
|
||||
if (now - tt > DSDV_BROADCAST_PERIOD)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::sendTables() Broadcast Time";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
selectStableRoutes();
|
||||
clearOldRoutes();
|
||||
|
||||
generateRoutingTables(false);
|
||||
|
||||
printDsdvTable(std::cerr);
|
||||
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
mSentTablesTime = now;
|
||||
mSentIncrementTime = now;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
/* otherwise send incremental changes */
|
||||
if ((updateRequired) && (now - it > DSDV_MIN_INCREMENT_PERIOD))
|
||||
{
|
||||
selectStableRoutes();
|
||||
|
||||
generateRoutingTables(true);
|
||||
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
mSentIncrementTime = now;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define RSDSDV_SEQ_INCREMENT 2
|
||||
|
||||
void p3Dsdv::advanceLocalSequenceNumbers()
|
||||
{
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
std::map<std::string, RsDsdvTableEntry>::iterator it;
|
||||
for(it = mTable.begin(); it != mTable.end(); it++)
|
||||
{
|
||||
RsDsdvTableEntry &v = (it->second);
|
||||
if (v.mOwnSource)
|
||||
{
|
||||
v.mStableRoute.mSequence += RSDSDV_SEQ_INCREMENT;
|
||||
v.mStableRoute.mReceived = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void p3Dsdv::clearSignificantChangesFlags()
|
||||
{
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
std::map<std::string, RsDsdvTableEntry>::iterator it;
|
||||
for(it = mTable.begin(); it != mTable.end(); it++)
|
||||
{
|
||||
RsDsdvTableEntry &v = (it->second);
|
||||
if (v.mFlags & RSDSDV_FLAGS_SIGNIFICANT_CHANGE)
|
||||
{
|
||||
v.mFlags &= ~RSDSDV_FLAGS_SIGNIFICANT_CHANGE;
|
||||
}
|
||||
}
|
||||
mSignificantChanges = false;
|
||||
}
|
||||
|
||||
|
||||
int p3Dsdv::generateRoutingTables(bool incremental)
|
||||
{
|
||||
/* we ping our peers */
|
||||
/* who is online? */
|
||||
std::list<std::string> idList;
|
||||
mLinkMgr->getOnlineList(idList);
|
||||
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::generateRoutingTables(" << incremental << ")";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
if (!incremental)
|
||||
{
|
||||
/* now clear significant flag */
|
||||
advanceLocalSequenceNumbers();
|
||||
}
|
||||
|
||||
/* prepare packets */
|
||||
std::list<std::string>::iterator it;
|
||||
for(it = idList.begin(); it != idList.end(); it++)
|
||||
{
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::generateRoutingTables() For: " << *it;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
generateRoutingTable(*it, incremental);
|
||||
}
|
||||
|
||||
|
||||
/* now clear significant flag */
|
||||
clearSignificantChangesFlags();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int p3Dsdv::generateRoutingTable(const std::string &peerId, bool incremental)
|
||||
{
|
||||
RsDsdvRouteItem *dsdv = new RsDsdvRouteItem();
|
||||
dsdv->PeerId(peerId);
|
||||
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
std::map<std::string, RsDsdvTableEntry>::iterator it;
|
||||
for(it = mTable.begin(); it != mTable.end(); it++)
|
||||
{
|
||||
RsDsdvTableEntry &v = (it->second);
|
||||
|
||||
/* discard/ignore criterion */
|
||||
if (!v.mIsStable)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (v.mStableRoute.mDistance >= RSDSDV_MAX_DISTANCE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (incremental)
|
||||
{
|
||||
if (v.mFlags & RSDSDV_FLAGS_SIGNIFICANT_CHANGE)
|
||||
{
|
||||
// Done elsewhere.
|
||||
//v.mFlags &= ~SIGNIFICANT_CHANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ignore non-significant changes */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
RsTlvDsdvEntry entry;
|
||||
|
||||
entry.endPoint.idType = v.mDest.mIdType;
|
||||
entry.endPoint.anonChunk = v.mDest.mAnonChunk;
|
||||
entry.endPoint.serviceId = v.mDest.mHash;
|
||||
entry.sequence = v.mStableRoute.mSequence;
|
||||
entry.distance = v.mStableRoute.mDistance;
|
||||
|
||||
dsdv->routes.entries.push_back(entry);
|
||||
|
||||
if (dsdv->routes.entries.size() > RSDSDV_MAX_ROUTE_TABLE)
|
||||
{
|
||||
sendItem(dsdv);
|
||||
dsdv = new RsDsdvRouteItem();
|
||||
dsdv->PeerId(peerId);
|
||||
}
|
||||
}
|
||||
sendItem(dsdv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
|
||||
int p3Dsdv::processIncoming()
|
||||
{
|
||||
/* for each packet - pass to specific handler */
|
||||
RsItem *item = NULL;
|
||||
while(NULL != (item = recvItem()))
|
||||
{
|
||||
switch(item->PacketSubType())
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case RS_PKT_SUBTYPE_DSDV_ROUTE:
|
||||
{
|
||||
handleDSDV((RsDsdvRouteItem *) item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
delete item;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
int p3Dsdv::handleDSDV(RsDsdvRouteItem *dsdv)
|
||||
{
|
||||
/* iterate over the entries */
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::handleDSDV() Received Pkt from: " << dsdv->PeerId();
|
||||
std::cerr << std::endl;
|
||||
//dsdv->print(std::cerr);
|
||||
//std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::list<RsTlvDsdvEntry>::iterator it;
|
||||
for(it = dsdv->routes.entries.begin(); it != dsdv->routes.entries.end(); it++)
|
||||
{
|
||||
/* check for existing */
|
||||
RsTlvDsdvEntry &entry = *it;
|
||||
uint32_t realDistance = entry.distance + 1; // metric.
|
||||
|
||||
|
||||
/* find the entry */
|
||||
std::map<std::string, RsDsdvTableEntry>::iterator tit;
|
||||
tit = mTable.find(entry.endPoint.serviceId);
|
||||
if (tit == mTable.end())
|
||||
{
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::handleDSDV() Adding Entry for New ServiceId: ";
|
||||
std::cerr << entry.endPoint.serviceId;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* new entry! */
|
||||
RsDsdvTableEntry v;
|
||||
v.mDest.mIdType = entry.endPoint.idType;
|
||||
v.mDest.mAnonChunk = entry.endPoint.anonChunk;
|
||||
v.mDest.mHash = entry.endPoint.serviceId;
|
||||
|
||||
/* add as a possible route */
|
||||
RsDsdvRoute newRoute;
|
||||
|
||||
newRoute.mNextHop = dsdv->PeerId();
|
||||
newRoute.mReceived = now;
|
||||
newRoute.mSequence = entry.sequence;
|
||||
newRoute.mDistance = realDistance;
|
||||
newRoute.mValidSince = now;
|
||||
|
||||
v.mAllRoutes[dsdv->PeerId()] = newRoute;
|
||||
v.mIsStable = false;
|
||||
|
||||
v.mFlags = RSDSDV_FLAGS_NEW_ROUTE;
|
||||
v.mOwnSource = false;
|
||||
v.mMatched = false;
|
||||
|
||||
// store in table.
|
||||
mTable[v.mDest.mHash] = v;
|
||||
}
|
||||
else
|
||||
{
|
||||
RsDsdvTableEntry &v = tit->second;
|
||||
if (v.mOwnSource)
|
||||
{
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::handleDSDV() Ignoring OwnSource Entry:";
|
||||
std::cerr << entry.endPoint.serviceId;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
continue; // Ignore if we are source.
|
||||
}
|
||||
|
||||
/* look for this in mAllRoutes */
|
||||
std::map<std::string, RsDsdvRoute>::iterator rit;
|
||||
rit = v.mAllRoutes.find(dsdv->PeerId());
|
||||
if (rit == v.mAllRoutes.end())
|
||||
{
|
||||
/* add a new entry in */
|
||||
RsDsdvRoute newRoute;
|
||||
|
||||
newRoute.mNextHop = dsdv->PeerId();
|
||||
newRoute.mReceived = now;
|
||||
newRoute.mSequence = entry.sequence;
|
||||
newRoute.mDistance = realDistance;
|
||||
newRoute.mValidSince = now;
|
||||
|
||||
v.mAllRoutes[dsdv->PeerId()] = newRoute;
|
||||
|
||||
/* if we've just added it in - can't be stable one */
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::handleDSDV() Adding NewRoute Entry:";
|
||||
std::cerr << entry.endPoint.serviceId;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rit->second.mSequence >= entry.sequence)
|
||||
{
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::handleDSDV() Ignoring OLDSEQ Entry:";
|
||||
std::cerr << entry.endPoint.serviceId;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* ignore same/old sequence number??? */
|
||||
continue;
|
||||
}
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::handleDSDV() Updating Entry:";
|
||||
std::cerr << entry.endPoint.serviceId;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* update seq,dist,etc */
|
||||
if (rit->second.mSequence + 2 < entry.sequence)
|
||||
{
|
||||
/* skipped a sequence number - reset timer */
|
||||
rit->second.mValidSince = now;
|
||||
}
|
||||
|
||||
//rit->second.mNextHop; // unchanged.
|
||||
rit->second.mReceived = now;
|
||||
rit->second.mSequence = entry.sequence;
|
||||
rit->second.mDistance = realDistance;
|
||||
|
||||
/* if consistent route... maintain */
|
||||
if ((v.mIsStable) &&
|
||||
(rit->second.mNextHop == v.mStableRoute.mNextHop))
|
||||
{
|
||||
v.mStableRoute = rit->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* otherwise we need to wait - see if we get new update */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int p3Dsdv::selectStableRoutes()
|
||||
{
|
||||
/* iterate over the entries */
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::selectStableRoutes()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* find the entry */
|
||||
std::map<std::string, RsDsdvTableEntry>::iterator tit;
|
||||
for(tit = mTable.begin(); tit != mTable.end(); tit++)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::selectStableRoutes() For Entry: ";
|
||||
std::cerr << tit->second;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
if (tit->second.mOwnSource)
|
||||
{
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::selectStableRoutes() OwnSource... Ignoring";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
continue; // Ignore if we are source.
|
||||
}
|
||||
|
||||
std::map<std::string, RsDsdvRoute>::iterator rit;
|
||||
uint32_t newest = 0;
|
||||
std::string newestId;
|
||||
uint32_t closest = RSDSDV_MAX_DISTANCE + 1;
|
||||
std::string closestId;
|
||||
time_t closestAge = 0;
|
||||
|
||||
/* find newest sequence number */
|
||||
for(rit = tit->second.mAllRoutes.begin();
|
||||
rit != tit->second.mAllRoutes.end(); rit++)
|
||||
{
|
||||
if ((now - rit->second.mReceived <= DSDV_DISCARD_PERIOD) &&
|
||||
(rit->second.mSequence >= newest))
|
||||
{
|
||||
newest = rit->second.mSequence;
|
||||
newestId = rit->first;
|
||||
|
||||
/* also becomes default for closest (later) */
|
||||
closest = rit->second.mDistance;
|
||||
closestId = rit->first;
|
||||
closestAge = now - rit->second.mValidSince;
|
||||
}
|
||||
}
|
||||
|
||||
if (closest >= RSDSDV_MAX_DISTANCE + 1)
|
||||
{
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "\tNo Suitable Route";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
tit->second.mIsStable = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t currseq = newest - (newest % 2); // remove 'kill'=ODD Seq.
|
||||
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "\t Newest Seq: " << newest << " from: " << newestId;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* find closest distance - with valid seq & max valid time */
|
||||
for(rit = tit->second.mAllRoutes.begin();
|
||||
rit != tit->second.mAllRoutes.end(); rit++)
|
||||
{
|
||||
/* Maximum difference in Sequence number is 2*DISTANCE
|
||||
* Otherwise it must be old.
|
||||
*/
|
||||
if (rit->second.mSequence + rit->second.mDistance * 2 < currseq)
|
||||
{
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "\t\tIgnoring OLD SEQ Entry: " << rit->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
continue; // ignore.
|
||||
}
|
||||
|
||||
/* if we haven't received an update in ages - old */
|
||||
if (now - rit->second.mReceived > DSDV_DISCARD_PERIOD)
|
||||
{
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "\t\tIgnoring OLD TIME Entry: " << rit->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
continue; // ignore.
|
||||
}
|
||||
|
||||
if (rit->second.mDistance < closest)
|
||||
{
|
||||
closest = rit->second.mDistance;
|
||||
closestId = rit->first;
|
||||
closestAge = now - rit->second.mValidSince;
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "\t\tUpdating to Closer Entry: " << rit->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
else if ((rit->second.mDistance == closest) &&
|
||||
(closestAge < now - rit->second.mValidSince))
|
||||
{
|
||||
/* have a more stable (older) one */
|
||||
closest = rit->second.mDistance;
|
||||
closestId = rit->first;
|
||||
closestAge = now - rit->second.mValidSince;
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "\t\tUpdating to Stabler Entry: " << rit->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "\t\tIgnoring Distant Entry: " << rit->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
tit->second.mIsStable = true;
|
||||
rit = tit->second.mAllRoutes.find(closestId);
|
||||
tit->second.mStableRoute = rit->second;
|
||||
tit->second.mFlags &= ~RSDSDV_FLAGS_NEW_ROUTE;
|
||||
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "\tStable Route: " << tit->second.mStableRoute;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int p3Dsdv::clearOldRoutes()
|
||||
{
|
||||
/* iterate over the entries */
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::clearOldRoutes()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* find the entry */
|
||||
std::map<std::string, RsDsdvTableEntry>::iterator it, it2;
|
||||
for(it = mTable.begin(); it != mTable.end(); it++)
|
||||
{
|
||||
if (it->second.mOwnSource)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (it->second.mIsStable)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (it->second.mFlags & RSDSDV_FLAGS_NEW_ROUTE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* backstep iterator for loop, and delete original */
|
||||
it2 = it;
|
||||
it--;
|
||||
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::clearOldRoutes() Deleting OLD ServiceId: " << it2->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
mTable.erase(it2);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*************** pqiMonitor callback ***********************/
|
||||
void p3Dsdv::statusChange(const std::list<pqipeer> &plist)
|
||||
{
|
||||
std::list<pqipeer>::const_iterator it;
|
||||
for(it = plist.begin(); it != plist.end(); it++)
|
||||
{
|
||||
/* only care about disconnected / not friends cases */
|
||||
if ( 1 )
|
||||
{
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int p3Dsdv::addTestService()
|
||||
{
|
||||
RsDsdvId testId;
|
||||
|
||||
int rndhash1[SHA_DIGEST_LENGTH / 4];
|
||||
int rndhash2[SHA_DIGEST_LENGTH / 4];
|
||||
std::ostringstream rh, sh;
|
||||
std::string realHash;
|
||||
std::string seedHash;
|
||||
|
||||
int i;
|
||||
for(i = 0; i < SHA_DIGEST_LENGTH / 4; i++)
|
||||
{
|
||||
rndhash1[i] = RSRandom::random_u32();
|
||||
rndhash2[i] = RSRandom::random_u32();
|
||||
}
|
||||
|
||||
for(int i = 0; i < SHA_DIGEST_LENGTH; i++)
|
||||
{
|
||||
rh << std::setw(2) << std::setfill('0') << std::hex << (uint32_t) ((uint8_t *) rndhash1)[i];
|
||||
sh << std::setw(2) << std::setfill('0') << std::hex << (uint32_t) ((uint8_t *) rndhash2)[i];
|
||||
}
|
||||
|
||||
realHash = rh.str();
|
||||
seedHash = sh.str();
|
||||
|
||||
uint8_t sha_hash[SHA_DIGEST_LENGTH];
|
||||
memset(sha_hash,0,SHA_DIGEST_LENGTH*sizeof(uint8_t)) ;
|
||||
SHA_CTX *sha_ctx = new SHA_CTX;
|
||||
SHA1_Init(sha_ctx);
|
||||
|
||||
SHA1_Update(sha_ctx, realHash.c_str(), realHash.length());
|
||||
SHA1_Update(sha_ctx, seedHash.c_str(), seedHash.length());
|
||||
SHA1_Final(sha_hash, sha_ctx);
|
||||
delete sha_ctx;
|
||||
|
||||
std::ostringstream keystr;
|
||||
for(int i = 0; i < SHA_DIGEST_LENGTH; i++)
|
||||
{
|
||||
keystr << std::setw(2) << std::setfill('0') << std::hex << (uint32_t) (sha_hash)[i];
|
||||
}
|
||||
|
||||
|
||||
testId.mIdType = RSDSDV_IDTYPE_TEST;
|
||||
testId.mAnonChunk = seedHash;
|
||||
testId.mHash = keystr.str();
|
||||
|
||||
addDsdvId(&testId, realHash);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int p3Dsdv::addDsdvId(RsDsdvId *id, std::string realHash)
|
||||
{
|
||||
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::addDsdvId() ID: " << *id << " RealHash: " << realHash;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
/* check for duplicate */
|
||||
std::map<std::string, RsDsdvTableEntry>::iterator it;
|
||||
it = mTable.find(id->mHash);
|
||||
if (it != mTable.end())
|
||||
{
|
||||
/* error */
|
||||
std::cerr << "p3Dsdv::addDsdvId() ERROR Duplicate ID";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* new entry! */
|
||||
RsDsdvTableEntry v;
|
||||
v.mDest = *id;
|
||||
|
||||
v.mStableRoute.mNextHop = mLinkMgr->getOwnId();
|
||||
v.mStableRoute.mReceived = now;
|
||||
v.mStableRoute.mValidSince = now;
|
||||
v.mStableRoute.mSequence = 0;
|
||||
v.mStableRoute.mDistance = 0;
|
||||
v.mIsStable = true;
|
||||
|
||||
v.mFlags = RSDSDV_FLAGS_OWN_SERVICE;
|
||||
v.mOwnSource = true;
|
||||
v.mMatched = true;
|
||||
v.mMatchedHash = realHash;
|
||||
|
||||
// store in table.
|
||||
mTable[v.mDest.mHash] = v;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int p3Dsdv::dropDsdvId(RsDsdvId *id)
|
||||
{
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
#ifdef DEBUG_DSDV
|
||||
std::cerr << "p3Dsdv::dropDsdvId() ID: " << *id;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* This should send out an infinity packet... and flag for deletion */
|
||||
|
||||
std::map<std::string, RsDsdvTableEntry>::iterator it;
|
||||
it = mTable.find(id->mHash);
|
||||
if (it == mTable.end())
|
||||
{
|
||||
/* error */
|
||||
std::cerr << "p3Dsdv::addDsdvId() ERROR Unknown ID";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
mTable.erase(it);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int p3Dsdv::printDsdvTable(std::ostream &out)
|
||||
{
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
/* iterate over the entries */
|
||||
std::map<std::string, RsDsdvTableEntry>::iterator it;
|
||||
for(it = mTable.begin(); it != mTable.end(); it++)
|
||||
{
|
||||
RsDsdvTableEntry &v = it->second;
|
||||
out << v;
|
||||
out << std::endl;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*****************************************/
|
||||
|
||||
uint32_t p3Dsdv::getLocalServices(std::list<std::string> &hashes)
|
||||
{
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
/* iterate over the entries */
|
||||
std::map<std::string, RsDsdvTableEntry>::iterator it;
|
||||
for(it = mTable.begin(); it != mTable.end(); it++)
|
||||
{
|
||||
if (it->second.mOwnSource)
|
||||
{
|
||||
hashes.push_back(it->first);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint32_t p3Dsdv::getAllServices(std::list<std::string> &hashes)
|
||||
{
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
/* iterate over the entries */
|
||||
std::map<std::string, RsDsdvTableEntry>::iterator it;
|
||||
for(it = mTable.begin(); it != mTable.end(); it++)
|
||||
{
|
||||
hashes.push_back(it->first);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int p3Dsdv::getDsdvEntry(const std::string &hash, RsDsdvTableEntry &entry)
|
||||
{
|
||||
RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
/* iterate over the entries */
|
||||
std::map<std::string, RsDsdvTableEntry>::iterator it;
|
||||
it = mTable.find(hash);
|
||||
if (it == mTable.end())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
entry = it->second;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const RsDsdvId &id)
|
||||
{
|
||||
out << "[Type: " << id.mIdType << " AMZ: " << id.mAnonChunk << " THASH: " << id.mHash;
|
||||
out << "]";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const RsDsdvRoute &route)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
out << "< Seq: " << route.mSequence << " Dist: " << route.mDistance;
|
||||
out << " NextHop: " << route.mNextHop;
|
||||
out << " recvd: " << now-route.mReceived;
|
||||
out << " validSince: " << now-route.mValidSince;
|
||||
out << " >";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const RsDsdvTableEntry &entry)
|
||||
{
|
||||
out << "DSDV Route for: " << entry.mDest << std::endl;
|
||||
if (entry.mIsStable)
|
||||
{
|
||||
out << "\tStable: " << entry.mStableRoute << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "\tNo Stable Route" << std::endl;
|
||||
}
|
||||
|
||||
out << "\tOwnSource: " << entry.mOwnSource;
|
||||
out << " Flags: " << entry.mFlags;
|
||||
if (entry.mMatched)
|
||||
{
|
||||
out << " Matched: " << entry.mMatchedHash;
|
||||
}
|
||||
else
|
||||
{
|
||||
out << " Non Matched";
|
||||
}
|
||||
out << std::endl;
|
||||
if (entry.mAllRoutes.size() > 0)
|
||||
{
|
||||
out << "\tAll Routes:" << std::endl;
|
||||
}
|
||||
|
||||
std::map<std::string, RsDsdvRoute>::const_iterator it;
|
||||
for(it = entry.mAllRoutes.begin(); it != entry.mAllRoutes.end(); it++)
|
||||
{
|
||||
out << "\t\t" << it->second << std::endl;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
122
libretroshare/src/services/p3dsdv.h
Normal file
122
libretroshare/src/services/p3dsdv.h
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* libretroshare/src/services/p3dsdv.h
|
||||
*
|
||||
* Network-Wide Routing Service.
|
||||
*
|
||||
* Copyright 2011 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SERVICE_RSDSDV_HEADER
|
||||
#define SERVICE_RSDSDV_HEADER
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "serialiser/rsdsdvitems.h"
|
||||
#include "services/p3service.h"
|
||||
#include "pqi/p3cfgmgr.h"
|
||||
#include "pqi/pqimonitor.h"
|
||||
|
||||
#include "retroshare/rsdsdv.h"
|
||||
|
||||
class p3LinkMgr;
|
||||
|
||||
|
||||
#define RSDSDV_MAX_DISTANCE 3
|
||||
#define RSDSDV_MAX_SEND_TABLE 100
|
||||
|
||||
//!The RS DSDV service.
|
||||
/**
|
||||
*
|
||||
* Finds RS wide paths to Services and Peers.
|
||||
*/
|
||||
|
||||
class p3Dsdv: public RsDsdv, public p3Service /* , public p3Config */, public pqiMonitor
|
||||
{
|
||||
public:
|
||||
p3Dsdv(p3LinkMgr *cm);
|
||||
|
||||
/*** internal librs interface ****/
|
||||
|
||||
int addDsdvId(RsDsdvId *id, std::string realHash);
|
||||
int dropDsdvId(RsDsdvId *id);
|
||||
int printDsdvTable(std::ostream &out);
|
||||
|
||||
int addTestService();
|
||||
|
||||
private:
|
||||
|
||||
int sendTables();
|
||||
void advanceLocalSequenceNumbers();
|
||||
void clearSignificantChangesFlags();
|
||||
|
||||
|
||||
int generateRoutingTables(bool incremental);
|
||||
int generateRoutingTable(const std::string &peerId, bool incremental);
|
||||
|
||||
int processIncoming();
|
||||
|
||||
int handleDSDV(RsDsdvRouteItem *dsdv);
|
||||
|
||||
int selectStableRoutes();
|
||||
int clearOldRoutes();
|
||||
|
||||
public:
|
||||
|
||||
/***** overloaded from rsDsdv *****/
|
||||
|
||||
virtual uint32_t getLocalServices(std::list<std::string> &hashes);
|
||||
virtual uint32_t getAllServices(std::list<std::string> &hashes);
|
||||
virtual int getDsdvEntry(const std::string &hash, RsDsdvTableEntry &entry);
|
||||
|
||||
/***** overloaded from p3Service *****/
|
||||
/*!
|
||||
* Process stuff.
|
||||
*/
|
||||
|
||||
virtual int tick();
|
||||
virtual int status();
|
||||
|
||||
/*************** pqiMonitor callback ***********************/
|
||||
virtual void statusChange(const std::list<pqipeer> &plist);
|
||||
|
||||
/************* from p3Config *******************/
|
||||
//virtual RsSerialiser *setupSerialiser() ;
|
||||
//virtual bool saveList(bool& cleanup, std::list<RsItem*>&) ;
|
||||
//virtual void saveDone();
|
||||
//virtual bool loadList(std::list<RsItem*>& load) ;
|
||||
|
||||
private:
|
||||
RsMutex mDsdvMtx;
|
||||
|
||||
std::map<std::string, RsDsdvTableEntry> mTable;
|
||||
|
||||
time_t mSentTablesTime;
|
||||
time_t mSentIncrementTime;
|
||||
|
||||
bool mSignificantChanges;
|
||||
|
||||
p3LinkMgr *mLinkMgr;
|
||||
|
||||
};
|
||||
|
||||
#endif // SERVICE_RSDSDV_HEADER
|
||||
|
Loading…
Reference in New Issue
Block a user