Gossip discovery refinement

Rename from RsDisc to more descriptive RsGossipDiscovery
Keep full retrocompatibility suggesting usage of RsGossipDiscovery
Add capability to send and receive full RetroShare invitation
Emit event when receiving a full invitation
Start using new debug utilities
Use enum class instead of defines and constant where appropriate
This commit is contained in:
Gioacchino Mazzurco 2019-05-02 16:23:46 +02:00
parent 4e1280839a
commit b1285a5de7
No known key found for this signature in database
GPG key ID: A1FBCA3872E87051
10 changed files with 473 additions and 391 deletions

View file

@ -0,0 +1,162 @@
/*******************************************************************************
* Gossip discovery service items *
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2007-2008 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include "gossipdiscovery/gossipdiscoveryitems.h"
#include "serialiser/rsbaseserial.h"
#include "serialiser/rstypeserializer.h"
#include "serialiser/rsserializable.h"
#include <iostream>
RsItem *RsDiscSerialiser::create_item(
uint16_t service, uint8_t item_subtype ) const
{
if(service != RS_SERVICE_TYPE_DISC) return nullptr;
switch(static_cast<RsGossipDiscoveryItemType>(item_subtype))
{
case RsGossipDiscoveryItemType::PGP_LIST: return new RsDiscPgpListItem();
case RsGossipDiscoveryItemType::PGP_CERT: return new RsDiscPgpCertItem();
case RsGossipDiscoveryItemType::CONTACT: return new RsDiscContactItem();
case RsGossipDiscoveryItemType::IDENTITY_LIST:
return new RsDiscIdentityListItem();
case RsGossipDiscoveryItemType::INVITE:
return new RsGossipDiscoveryInviteItem();
case RsGossipDiscoveryItemType::INVITE_REQUEST:
return new RsGossipDiscoveryInviteRequestItem();
}
return nullptr;
}
/*************************************************************************/
void RsDiscPgpListItem::clear()
{
mode = RsGossipDiscoveryPgpListMode::NONE;
pgpIdSet.TlvClear();
}
void RsDiscPgpListItem::serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RS_SERIAL_PROCESS(mode);
RS_SERIAL_PROCESS(pgpIdSet);
}
void RsDiscPgpCertItem::clear()
{
pgpId.clear();
pgpCert.clear();
}
void RsDiscPgpCertItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process(j,ctx,pgpId,"pgpId") ;
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_PGPCERT,pgpCert,"pgpCert") ;
}
void RsDiscContactItem::clear()
{
pgpId.clear();
sslId.clear();
location.clear();
version.clear();
netMode = 0;
vs_disc = 0;
vs_dht = 0;
lastContact = 0;
isHidden = false;
hiddenAddr.clear();
hiddenPort = 0;
localAddrV4.TlvClear();
extAddrV4.TlvClear();
localAddrV6.TlvClear();
extAddrV6.TlvClear();
dyndns.clear();
localAddrList.TlvClear();
extAddrList.TlvClear();
}
void RsDiscContactItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process (j,ctx,pgpId,"pgpId");
RsTypeSerializer::serial_process (j,ctx,sslId,"sslId");
RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_LOCATION,location,"location");
RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_VERSION,version,"version");
RsTypeSerializer::serial_process<uint32_t>(j,ctx,netMode,"netMode");
RsTypeSerializer::serial_process<uint16_t>(j,ctx,vs_disc,"vs_disc");
RsTypeSerializer::serial_process<uint16_t>(j,ctx,vs_dht,"vs_dht");
RsTypeSerializer::serial_process<uint32_t>(j,ctx,lastContact,"lastContact");
// This is a hack. Normally we should have to different item types, in order to avoid this nonesense.
if(j == RsGenericSerializer::DESERIALIZE)
isHidden = ( GetTlvType( &(((uint8_t *) ctx.mData)[ctx.mOffset]) )==TLV_TYPE_STR_DOMADDR);
if(isHidden)
{
RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_DOMADDR,hiddenAddr,"hiddenAddr");
RsTypeSerializer::serial_process<uint16_t>(j,ctx,hiddenPort,"hiddenPort");
}
else
{
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,localAddrV4,"localAddrV4");
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx, extAddrV4,"extAddrV4");
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,localAddrV6,"localAddrV6");
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx, extAddrV6,"extAddrV6");
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,currentConnectAddress,"currentConnectAddress");
RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_DYNDNS,dyndns,"dyndns");
RsTypeSerializer::serial_process (j,ctx,localAddrList,"localAddrList");
RsTypeSerializer::serial_process (j,ctx, extAddrList,"extAddrList");
}
}
void RsDiscIdentityListItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RS_SERIAL_PROCESS(ownIdentityList);
}
RsGossipDiscoveryInviteItem::RsGossipDiscoveryInviteItem() :
RsDiscItem(RsGossipDiscoveryItemType::INVITE)
{ setPriorityLevel(QOS_PRIORITY_RS_DISC_ASK_INFO); }
RsGossipDiscoveryInviteRequestItem::RsGossipDiscoveryInviteRequestItem() :
RsDiscItem(RsGossipDiscoveryItemType::INVITE_REQUEST)
{ setPriorityLevel(QOS_PRIORITY_RS_DISC_REPLY); }
RsDiscItem::RsDiscItem(RsGossipDiscoveryItemType subtype) :
RsItem( RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DISC,
static_cast<uint8_t>(subtype) ) {}
RsDiscItem::~RsDiscItem() {}

View file

@ -0,0 +1,187 @@
/*******************************************************************************
* Gossip discovery service items *
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2004-2008 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include "serialiser/rsserial.h"
#include "serialiser/rstlvidset.h"
#include "serialiser/rstlvaddrs.h"
#include "rsitems/rsserviceids.h"
#include "rsitems/rsitem.h"
#include "rsitems/itempriorities.h"
#include "serialiser/rsserializer.h"
enum class RsGossipDiscoveryItemType : uint8_t
{
PGP_LIST = 1,
PGP_CERT = 2,
CONTACT = 5,
IDENTITY_LIST = 6,
INVITE = 7,
INVITE_REQUEST = 8
};
class RsDiscItem: public RsItem
{
protected:
RsDiscItem(RsGossipDiscoveryItemType subtype);
public:
RsDiscItem() = delete;
virtual ~RsDiscItem();
};
/// uint32_t overkill just for retro-compatibility
enum class RsGossipDiscoveryPgpListMode : uint32_t
{
NONE = 0,
FRIENDS = 1,
GETCERT = 2
};
class RsDiscPgpListItem: public RsDiscItem
{
public:
RsDiscPgpListItem() : RsDiscItem(RsGossipDiscoveryItemType::PGP_LIST)
{ setPriorityLevel(QOS_PRIORITY_RS_DISC_PGP_LIST); }
void clear() override;
void serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) override;
RsGossipDiscoveryPgpListMode mode;
RsTlvPgpIdSet pgpIdSet;
};
class RsDiscPgpCertItem: public RsDiscItem
{
public:
RsDiscPgpCertItem() : RsDiscItem(RsGossipDiscoveryItemType::PGP_CERT)
{ setPriorityLevel(QOS_PRIORITY_RS_DISC_PGP_CERT); }
void clear() override;
void serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override;
RsPgpId pgpId;
std::string pgpCert;
};
class RsDiscContactItem: public RsDiscItem
{
public:
RsDiscContactItem() : RsDiscItem(RsGossipDiscoveryItemType::CONTACT)
{ setPriorityLevel(QOS_PRIORITY_RS_DISC_CONTACT); }
void clear() override;
void serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) override;
RsPgpId pgpId;
RsPeerId sslId;
// COMMON
std::string location;
std::string version;
uint32_t netMode; /* Mandatory */
uint16_t vs_disc; /* Mandatory */
uint16_t vs_dht; /* Mandatory */
uint32_t lastContact;
bool isHidden; /* not serialised */
// HIDDEN.
std::string hiddenAddr;
uint16_t hiddenPort;
// STANDARD.
RsTlvIpAddress currentConnectAddress ; // used to check!
RsTlvIpAddress localAddrV4; /* Mandatory */
RsTlvIpAddress extAddrV4; /* Mandatory */
RsTlvIpAddress localAddrV6; /* Mandatory */
RsTlvIpAddress extAddrV6; /* Mandatory */
std::string dyndns;
RsTlvIpAddrSet localAddrList;
RsTlvIpAddrSet extAddrList;
};
class RsDiscIdentityListItem: public RsDiscItem
{
public:
RsDiscIdentityListItem() :
RsDiscItem(RsGossipDiscoveryItemType::IDENTITY_LIST)
{ setPriorityLevel(QOS_PRIORITY_RS_DISC_CONTACT); }
void clear() override { ownIdentityList.clear(); }
void serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override;
std::list<RsGxsId> ownIdentityList;
};
struct RsGossipDiscoveryInviteItem : RsDiscItem
{
RsGossipDiscoveryInviteItem();
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) override
{ RS_SERIAL_PROCESS(mInvite); }
void clear() override { mInvite.clear(); }
std::string mInvite;
};
struct RsGossipDiscoveryInviteRequestItem : RsDiscItem
{
RsGossipDiscoveryInviteRequestItem();
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) override
{ RS_SERIAL_PROCESS(mInviteId); }
void clear() override { mInviteId.clear(); }
RsPeerId mInviteId;
};
class RsDiscSerialiser: public RsServiceSerializer
{
public:
RsDiscSerialiser() :RsServiceSerializer(RS_SERVICE_TYPE_DISC) {}
virtual ~RsDiscSerialiser() {}
RsItem* create_item(uint16_t service, uint8_t item_subtype) const;
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,167 @@
/*******************************************************************************
* RetroShare gossip discovery service implementation *
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2004-2013 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include <memory>
#include "retroshare/rsgossipdiscovery.h"
#include "pqi/p3peermgr.h"
#include "pqi/p3linkmgr.h"
#include "pqi/p3netmgr.h"
#include "pqi/pqiservicemonitor.h"
#include "gossipdiscovery/gossipdiscoveryitems.h"
#include "services/p3service.h"
#include "pqi/authgpg.h"
#include "gxs/rsgixs.h"
class p3ServiceControl;
using PGPID RS_DEPRECATED_FOR(RsPgpId) = RsPgpId;
using SSLID RS_DEPRECATED_FOR(RsPeerId) = RsPeerId;
struct DiscSslInfo
{
DiscSslInfo() : mDiscStatus(0) {}
uint16_t mDiscStatus;
};
struct DiscPeerInfo
{
DiscPeerInfo() {}
std::string mVersion;
};
struct DiscPgpInfo
{
DiscPgpInfo() {}
void mergeFriendList(const std::set<PGPID> &friends);
std::set<PGPID> mFriendSet;
std::map<SSLID, DiscSslInfo> mSslIds;
};
class p3discovery2 :
public RsGossipDiscovery, public p3Service, public pqiServiceMonitor,
public AuthGPGService
{
public:
p3discovery2( p3PeerMgr* peerMgr, p3LinkMgr* linkMgr, p3NetMgr* netMgr,
p3ServiceControl* sc, RsGixs* gixs );
virtual ~p3discovery2();
virtual RsServiceInfo getServiceInfo();
/************* from pqiServiceMonitor *******************/
virtual void statusChange(const std::list<pqiServicePeer> &plist);
/************* from pqiServiceMonitor *******************/
int tick();
/* external interface */
bool getDiscFriends(const RsPeerId &id, std::list<RsPeerId> &friends);
bool getDiscPgpFriends(const RsPgpId &pgpid, std::list<RsPgpId> &gpg_friends);
bool getPeerVersion(const RsPeerId &id, std::string &version);
bool getWaitingDiscCount(size_t &sendCount, size_t &recvCount);
/// @see RsGossipDiscovery
bool sendInvite(
const RsPeerId& inviteId, const RsPeerId& toSslId,
std::string& errorMsg = RS_DEFAULT_STORAGE_PARAM(std::string)
) override;
/// @see RsGossipDiscovery
bool requestInvite(
const RsPeerId& inviteId, const RsPeerId& toSslId,
std::string& errorMsg = RS_DEFAULT_STORAGE_PARAM(std::string)
) override;
/************* from AuthGPService ****************/
virtual AuthGPGOperation *getGPGOperation();
virtual void setGPGOperation(AuthGPGOperation *operation);
private:
PGPID getPGPId(const SSLID &id);
int handleIncoming();
void updatePgpFriendList();
void addFriend(const SSLID &sslId);
void removeFriend(const SSLID &sslId);
void updatePeerAddresses(const RsDiscContactItem *item);
void updatePeerAddressList(const RsDiscContactItem *item);
void sendOwnContactInfo(const SSLID &sslid);
void recvOwnContactInfo(const SSLID &fromId, const RsDiscContactItem *item);
void sendPGPList(const SSLID &toId);
void processPGPList(const SSLID &fromId, const RsDiscPgpListItem *item);
void processContactInfo(const SSLID &fromId, const RsDiscContactItem *info);
void requestPGPCertificate(const PGPID &aboutId, const SSLID &toId);
void recvPGPCertificateRequest(
const RsPeerId& fromId, const RsDiscPgpListItem* item );
void sendPGPCertificate(const PGPID &aboutId, const SSLID &toId);
void recvPGPCertificate(const SSLID &fromId, RsDiscPgpCertItem *item);
void recvIdentityList(const RsPeerId& pid,const std::list<RsGxsId>& ids);
bool setPeerVersion(const SSLID &peerId, const std::string &version);
void recvInvite(std::unique_ptr<RsGossipDiscoveryInviteItem> inviteItem);
void rsEventsHandler(const RsEvent& event);
RsEventsHandlerId_t mRsEventsHandle;
p3PeerMgr *mPeerMgr;
p3LinkMgr *mLinkMgr;
p3NetMgr *mNetMgr;
p3ServiceControl *mServiceCtrl;
RsGixs* mGixs;
/* data */
RsMutex mDiscMtx;
void updatePeers_locked(const SSLID &aboutId);
void sendContactInfo_locked(const PGPID &aboutId, const SSLID &toId);
rstime_t mLastPgpUpdate;
std::map<PGPID, DiscPgpInfo> mFriendList;
std::map<SSLID, DiscPeerInfo> mLocationMap;
std::list<RsDiscPgpCertItem *> mPendingDiscPgpCertInList;
std::list<RsDiscPgpCertItem *> mPendingDiscPgpCertOutList;
protected:
RS_SET_CONTEXT_DEBUG_LEVEL(1)
};