mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-01 02:46:20 -05:00
merged with upstream/master
This commit is contained in:
commit
9db0524f34
@ -1851,7 +1851,7 @@ retroshare (0.5.4-0.6685~precise) precise; urgency=low
|
||||
|
||||
|
||||
* Bug fixes
|
||||
- Added missing location from cert when addign new friend
|
||||
- Added missing location from cert when adding new friend
|
||||
- Added missing IndicateConfigChanged to p3PeerMgrIMPL::setDynDNS
|
||||
- Fixed crash when closing the main window without the setting "Minimize to Tray Icon"
|
||||
- Renamed the setting "Do not Minimize to Tray Icon" to "Minimize to Tray
|
||||
@ -2925,7 +2925,7 @@ retroshare (0.5.3-0.4953~natty) natty; urgency=low
|
||||
- Fixed Download toaster (utf8 in file name, use QDesktopServices vs RsUrlHandler for collections, fixed
|
||||
crash after opening a collection) (Patch from AsamK).
|
||||
- fixed utf8 chars in certificate links (Patch from AsamK)
|
||||
- removed cache adding strategy to DL queue that was O(n^2). Now addign cache at the end of the queue
|
||||
- removed cache adding strategy to DL queue that was O(n^2). Now adding cache at the end of the queue
|
||||
- Fixed bug when the user clicks on a link without http:// in a QTextBrowser. This link was
|
||||
oppened directly in RetroShare.
|
||||
- Attempted fix for maintaining External Port in Manual Forwarded Mode.
|
||||
|
@ -91,7 +91,7 @@ StreamBase& operator << (StreamBase& left, ChatHandler::ChatInfo& info)
|
||||
left << makeKeyValueReference("remote_author_id", info.remote_author_id)
|
||||
<< makeKeyValueReference("remote_author_name", info.remote_author_name)
|
||||
<< makeKeyValueReference("is_broadcast", info.is_broadcast)
|
||||
<< makeKeyValueReference("is_gxs_id", info.is_gxs_id)
|
||||
<< makeKeyValueReference("is_distant_chat_id", info.is_distant_chat_id)
|
||||
<< makeKeyValueReference("is_lobby", info.is_lobby)
|
||||
<< makeKeyValueReference("is_peer", info.is_peer);
|
||||
return left;
|
||||
@ -183,7 +183,6 @@ void ChatHandler::tick()
|
||||
l.auto_subscribe = false;
|
||||
l.is_private = false;
|
||||
l.is_broadcast = true;
|
||||
l.gxs_id = id.toGxsId();
|
||||
lobbies.push_back(l);
|
||||
}
|
||||
|
||||
@ -225,12 +224,20 @@ void ChatHandler::tick()
|
||||
author_id = msg.broadcast_peer_id.toStdString();
|
||||
author_name = mRsPeers->getPeerName(msg.broadcast_peer_id);
|
||||
}
|
||||
else if(msg.chat_id.isGxsId())
|
||||
else if(msg.chat_id.isDistantChatId())
|
||||
{
|
||||
author_id = msg.chat_id.toGxsId().toStdString();
|
||||
RsIdentityDetails details;
|
||||
if(!gxs_id_failed && mRsIdentity->getIdDetails(msg.chat_id.toGxsId(), details))
|
||||
DistantChatPeerInfo dcpinfo ;
|
||||
|
||||
if(!rsMsgs->getDistantChatStatus(msg.chat_id.toDistantChatId(),dcpinfo))
|
||||
{
|
||||
std::cerr << "(EE) cannot get info for distant chat peer " << msg.chat_id.toDistantChatId() << std::endl;
|
||||
continue ;
|
||||
}
|
||||
|
||||
RsIdentityDetails details;
|
||||
if(!gxs_id_failed && mRsIdentity->getIdDetails(msg.incoming? dcpinfo.to_id: dcpinfo.own_id, details))
|
||||
{
|
||||
author_id = details.mId.toStdString();
|
||||
author_name = details.mNickname;
|
||||
}
|
||||
else
|
||||
@ -278,7 +285,7 @@ void ChatHandler::tick()
|
||||
{
|
||||
ChatInfo info;
|
||||
info.is_broadcast = msg.chat_id.isBroadcast();
|
||||
info.is_gxs_id = msg.chat_id.isGxsId();
|
||||
info.is_distant_chat_id = msg.chat_id.isDistantChatId();
|
||||
info.is_lobby = msg.chat_id.isLobbyId();
|
||||
info.is_peer = msg.chat_id.isPeerId();
|
||||
if(msg.chat_id.isLobbyId())
|
||||
@ -289,12 +296,15 @@ void ChatHandler::tick()
|
||||
info.remote_author_name = vit->name;
|
||||
}
|
||||
}
|
||||
else if(msg.chat_id.isGxsId())
|
||||
else if(msg.chat_id.isDistantChatId())
|
||||
{
|
||||
RsIdentityDetails details;
|
||||
if(!gxs_id_failed && mRsIdentity->getIdDetails(msg.chat_id.toGxsId(), details))
|
||||
DistantChatPeerInfo dcpinfo ;
|
||||
|
||||
if(!gxs_id_failed && rsMsgs->getDistantChatStatus(msg.chat_id.toDistantChatId(),dcpinfo)
|
||||
&& mRsIdentity->getIdDetails(msg.incoming? dcpinfo.to_id: dcpinfo.own_id, details))
|
||||
{
|
||||
info.remote_author_id = msg.chat_id.toGxsId().toStdString();
|
||||
info.remote_author_id = details.mId.toStdString();
|
||||
info.remote_author_name = details.mNickname;
|
||||
}
|
||||
else
|
||||
|
@ -84,7 +84,7 @@ public:
|
||||
class ChatInfo{
|
||||
public:
|
||||
bool is_broadcast;
|
||||
bool is_gxs_id;
|
||||
bool is_distant_chat_id;
|
||||
bool is_lobby;
|
||||
bool is_peer;
|
||||
std::string remote_author_id;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,35 +25,38 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <turtle/turtleclientservice.h>
|
||||
#include <chat/rschatitems.h>
|
||||
#include <retroshare/rsmsgs.h>
|
||||
#include <retroshare/rsgxstunnel.h>
|
||||
|
||||
class RsGixs ;
|
||||
|
||||
static const uint32_t DISTANT_CHAT_AES_KEY_SIZE = 16 ;
|
||||
|
||||
class DistantChatService: public RsTurtleClientService
|
||||
class DistantChatService: public RsGxsTunnelService::RsGxsTunnelClientService
|
||||
{
|
||||
public:
|
||||
DistantChatService(RsGixs *pids)
|
||||
: mGixs(pids), mDistantChatMtx("distant chat")
|
||||
// So, public interface only uses DistandChatPeerId, but internally, this is converted into a RsGxsTunnelService::RsGxsTunnelId
|
||||
|
||||
|
||||
DistantChatService() : mDistantChatMtx("distant chat")
|
||||
{
|
||||
mTurtle = NULL ;
|
||||
mGxsTunnels = NULL ;
|
||||
}
|
||||
|
||||
void flush() ;
|
||||
|
||||
virtual void connectToTurtleRouter(p3turtle *) ;
|
||||
// Overloaded methods from RsGxsTunnelClientService
|
||||
|
||||
virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) ;
|
||||
|
||||
// Creates the invite if the public key of the distant peer is available.
|
||||
// Om success, stores the invite in the map above, so that we can respond to tunnel requests.
|
||||
//
|
||||
bool initiateDistantChatConnexion(const RsGxsId& to_gxs_id,const RsGxsId &from_gxs_id, uint32_t &error_code) ;
|
||||
bool closeDistantChatConnexion(const RsGxsId& pid) ;
|
||||
virtual bool getDistantChatStatus(const RsGxsId &gxs_id,uint32_t &status, RsGxsId *from_gxs_id=NULL) ;
|
||||
bool initiateDistantChatConnexion(const RsGxsId& to_gxs_id, const RsGxsId &from_gxs_id, DistantChatPeerId& dcpid, uint32_t &error_code) ;
|
||||
bool closeDistantChatConnexion(const DistantChatPeerId &tunnel_id) ;
|
||||
|
||||
virtual bool getDistantChatStatus(const DistantChatPeerId &tunnel_id, DistantChatPeerInfo& cinfo) ;
|
||||
|
||||
// derived in p3ChatService
|
||||
// derived in p3ChatService, so as to pass down some info
|
||||
virtual void handleIncomingItem(RsItem *) = 0;
|
||||
virtual bool handleRecvChatMsgItem(RsChatMsgItem *ci)=0 ;
|
||||
|
||||
@ -62,78 +65,25 @@ public:
|
||||
void handleRecvChatStatusItem(RsChatStatusItem *cs) ;
|
||||
|
||||
private:
|
||||
class DistantChatPeerInfo
|
||||
struct DistantChatContact
|
||||
{
|
||||
public:
|
||||
DistantChatPeerInfo() : last_contact(0), last_keep_alive_sent(0), status(0), direction(0)
|
||||
{
|
||||
memset(aes_key, 0, DISTANT_CHAT_AES_KEY_SIZE);
|
||||
}
|
||||
|
||||
time_t last_contact ; // used to keep track of working connexion
|
||||
time_t last_keep_alive_sent ; // last time we sent a keep alive packet.
|
||||
|
||||
unsigned char aes_key[DISTANT_CHAT_AES_KEY_SIZE] ;
|
||||
|
||||
uint32_t status ; // info: do we have a tunnel ?
|
||||
RsPeerId virtual_peer_id; // given by the turtle router. Identifies the tunnel.
|
||||
RsGxsId own_gxs_id ; // gxs id we're using to talk.
|
||||
RsTurtleGenericTunnelItem::Direction direction ; // specifiec wether we are client(managing the tunnel) or server.
|
||||
RsGxsId from_id ;
|
||||
RsGxsId to_id ;
|
||||
};
|
||||
|
||||
class DistantChatDHInfo
|
||||
{
|
||||
public:
|
||||
DistantChatDHInfo() : dh(0), direction(0), status(0) {}
|
||||
|
||||
DH *dh ;
|
||||
RsGxsId gxs_id ;
|
||||
RsTurtleGenericTunnelItem::Direction direction ;
|
||||
uint32_t status ;
|
||||
TurtleFileHash hash ;
|
||||
};
|
||||
|
||||
// This maps contains the current peers to talk to with distant chat.
|
||||
//
|
||||
std::map<RsGxsId, DistantChatPeerInfo> _distant_chat_contacts ; // current peers we can talk to
|
||||
std::map<RsPeerId,DistantChatDHInfo> _distant_chat_virtual_peer_ids ; // current virtual peers. Used to figure out tunnels, etc.
|
||||
std::map<DistantChatPeerId, DistantChatContact> mDistantChatContacts ; // current peers we can talk to
|
||||
|
||||
// List of items to be sent asap. Used to store items that we cannot pass directly to
|
||||
// sendTurtleData(), because of Mutex protection.
|
||||
// Overloaded from RsGxsTunnelClientService
|
||||
|
||||
virtual void notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId& tunnel_id,uint32_t tunnel_status) ;
|
||||
virtual void receiveData(const RsGxsTunnelService::RsGxsTunnelId& id,unsigned char *data,uint32_t data_size) ;
|
||||
|
||||
std::list<RsChatItem*> pendingDistantChatItems ;
|
||||
// Utility functions.
|
||||
|
||||
void markDistantChatAsClosed(const DistantChatPeerId& dcpid) ;
|
||||
|
||||
// Overloaded from RsTurtleClientService
|
||||
|
||||
virtual bool handleTunnelRequest(const RsFileHash &hash,const RsPeerId& peer_id) ;
|
||||
virtual void receiveTurtleData(RsTurtleGenericTunnelItem *item,const RsFileHash& hash,const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction) ;
|
||||
void addVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&,RsTurtleGenericTunnelItem::Direction dir) ;
|
||||
void removeVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&) ;
|
||||
void markDistantChatAsClosed(const RsGxsId &gxs_id) ;
|
||||
void startClientDistantChatConnection(const RsGxsId &to_gxs_id,const RsGxsId& from_gxs_id) ;
|
||||
void locked_restartDHSession(const RsPeerId &virtual_peer_id, const RsGxsId &own_gxs_id) ;
|
||||
|
||||
//bool getHashFromVirtualPeerId(const TurtleVirtualPeerId& pid,RsFileHash& hash) ;
|
||||
|
||||
static TurtleFileHash hashFromGxsId(const RsGxsId& destination) ;
|
||||
static RsGxsId gxsIdFromHash(const TurtleFileHash& sum) ;
|
||||
|
||||
void handleRecvDHPublicKey(RsChatDHPublicKeyItem *item) ;
|
||||
bool locked_sendDHPublicKey(const DH *dh, const RsGxsId &own_gxs_id, const RsPeerId &virtual_peer_id) ;
|
||||
bool locked_initDHSessionKey(DH *&dh);
|
||||
DistantChatPeerId virtualPeerIdFromHash(const TurtleFileHash& hash ) ; // ... and to a hash for p3turtle
|
||||
|
||||
|
||||
// Utility functions
|
||||
|
||||
void sendTurtleData(RsChatItem *) ;
|
||||
void sendEncryptedTurtleData(const uint8_t *buff,uint32_t rssize,const RsGxsId &gxs_id) ;
|
||||
bool handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id) ;
|
||||
|
||||
static TurtleFileHash hashFromVirtualPeerId(const DistantChatPeerId& peerId) ; // converts IDs so that we can talk to RsPeerId from outside
|
||||
|
||||
p3turtle *mTurtle ;
|
||||
RsGixs *mGixs ;
|
||||
RsGxsTunnelService *mGxsTunnels ;
|
||||
|
||||
RsMutex mDistantChatMtx ;
|
||||
};
|
||||
|
@ -1288,7 +1288,7 @@ void DistributedChatService::handleRecvLobbyInvite(RsChatLobbyInviteItem *item)
|
||||
else
|
||||
std::cerr << " : Match!" << std::endl;
|
||||
|
||||
std::cerr << " Addign new friend " << item->PeerId() << " to lobby." << std::endl;
|
||||
std::cerr << " Adding new friend " << item->PeerId() << " to lobby." << std::endl;
|
||||
#endif
|
||||
|
||||
it->second.participating_friends.insert(item->PeerId()) ;
|
||||
|
@ -54,7 +54,7 @@ static const uint32_t MAX_AVATAR_JPEG_SIZE = 32767; // Maximum size
|
||||
// Images are 96x96, which makes approx. 27000 bytes uncompressed.
|
||||
|
||||
p3ChatService::p3ChatService(p3ServiceControl *sc,p3IdService *pids, p3LinkMgr *lm, p3HistoryMgr *historyMgr)
|
||||
:DistantChatService(pids),DistributedChatService(getServiceInfo().mServiceType,sc,historyMgr,pids), mChatMtx("p3ChatService"),mServiceCtrl(sc), mLinkMgr(lm) , mHistoryMgr(historyMgr)
|
||||
: DistributedChatService(getServiceInfo().mServiceType,sc,historyMgr,pids), mChatMtx("p3ChatService"),mServiceCtrl(sc), mLinkMgr(lm) , mHistoryMgr(historyMgr)
|
||||
{
|
||||
_serializer = new RsChatSerialiser() ;
|
||||
|
||||
@ -86,7 +86,7 @@ int p3ChatService::tick()
|
||||
receiveChatQueue();
|
||||
|
||||
DistributedChatService::flush() ;
|
||||
DistantChatService::flush() ;
|
||||
//DistantChatService::flush() ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -217,24 +217,25 @@ void p3ChatService::sendStatusString(const ChatId& id , const std::string& statu
|
||||
sendLobbyStatusString(id.toLobbyId(),status_string) ;
|
||||
else if(id.isBroadcast())
|
||||
sendGroupChatStatusString(status_string);
|
||||
else if(id.isPeerId() || id.isGxsId())
|
||||
{
|
||||
RsChatStatusItem *cs = new RsChatStatusItem ;
|
||||
else if(id.isPeerId() || id.isDistantChatId())
|
||||
{
|
||||
RsChatStatusItem *cs = new RsChatStatusItem ;
|
||||
|
||||
cs->status_string = status_string ;
|
||||
cs->flags = RS_CHAT_FLAG_PRIVATE ;
|
||||
RsPeerId vpid;
|
||||
if(id.isGxsId())
|
||||
vpid = RsPeerId(id.toGxsId());
|
||||
else
|
||||
vpid = id.toPeerId();
|
||||
cs->PeerId(vpid);
|
||||
cs->status_string = status_string ;
|
||||
cs->flags = RS_CHAT_FLAG_PRIVATE ;
|
||||
RsPeerId vpid;
|
||||
if(id.isDistantChatId())
|
||||
vpid = RsPeerId(id.toDistantChatId());
|
||||
else
|
||||
vpid = id.toPeerId();
|
||||
|
||||
cs->PeerId(vpid);
|
||||
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "sending chat status packet:" << std::endl ;
|
||||
cs->print(std::cerr) ;
|
||||
std::cerr << "sending chat status packet:" << std::endl ;
|
||||
cs->print(std::cerr) ;
|
||||
#endif
|
||||
sendChatItem(cs);
|
||||
sendChatItem(cs);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -284,12 +285,14 @@ void p3ChatService::checkSizeAndSendMessage(RsChatMsgItem *msg)
|
||||
|
||||
bool p3ChatService::isOnline(const RsPeerId& pid)
|
||||
{
|
||||
// check if the id is a tunnel id or a peer id.
|
||||
uint32_t status ;
|
||||
if(getDistantChatStatus(RsGxsId(pid),status))
|
||||
return status == RS_DISTANT_CHAT_STATUS_CAN_TALK ;
|
||||
// check if the id is a tunnel id or a peer id.
|
||||
|
||||
DistantChatPeerInfo dcpinfo;
|
||||
|
||||
if(getDistantChatStatus(DistantChatPeerId(pid),dcpinfo))
|
||||
return dcpinfo.status == RS_DISTANT_CHAT_STATUS_CAN_TALK ;
|
||||
else
|
||||
return mServiceCtrl->isPeerConnected(getServiceInfo().mServiceType, pid);
|
||||
return mServiceCtrl->isPeerConnected(getServiceInfo().mServiceType, pid);
|
||||
}
|
||||
|
||||
bool p3ChatService::sendChat(ChatId destination, std::string msg)
|
||||
@ -301,7 +304,7 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg)
|
||||
sendPublicChat(msg);
|
||||
return true;
|
||||
}
|
||||
else if(destination.isPeerId()==false && destination.isGxsId()==false)
|
||||
else if(destination.isPeerId()==false && destination.isDistantChatId()==false)
|
||||
{
|
||||
std::cerr << "p3ChatService::sendChat() Error: chat id type not handled. Is it empty?" << std::endl;
|
||||
return false;
|
||||
@ -313,8 +316,8 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg)
|
||||
#endif
|
||||
|
||||
RsPeerId vpid;
|
||||
if(destination.isGxsId())
|
||||
vpid = RsPeerId(destination.toGxsId()); // convert to virtual peer id
|
||||
if(destination.isDistantChatId())
|
||||
vpid = RsPeerId(destination.toDistantChatId()); // convert to virtual peer id
|
||||
else
|
||||
vpid = destination.toPeerId();
|
||||
|
||||
@ -378,7 +381,12 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg)
|
||||
#endif
|
||||
|
||||
RsServer::notify()->notifyChatMessage(message);
|
||||
mHistoryMgr->addMessage(message);
|
||||
|
||||
// cyril: history is temporarily diabled for distant chat, since we need to store the full tunnel ID, but then
|
||||
// at loading time, the ID is not known so that chat window shows 00000000 as a peer.
|
||||
|
||||
if(!message.chat_id.isDistantChatId())
|
||||
mHistoryMgr->addMessage(message);
|
||||
|
||||
checkSizeAndSendMessage(ci);
|
||||
|
||||
@ -497,11 +505,11 @@ void p3ChatService::handleIncomingItem(RsItem *item)
|
||||
return ; // don't delete! It's handled by handleRecvChatMsgItem in some specific cases only.
|
||||
}
|
||||
|
||||
if(DistantChatService::handleRecvItem(dynamic_cast<RsChatItem*>(item)))
|
||||
{
|
||||
delete item ;
|
||||
return ;
|
||||
}
|
||||
// if(DistantChatService::handleRecvItem(dynamic_cast<RsChatItem*>(item)))
|
||||
// {
|
||||
// delete item ;
|
||||
// return ;
|
||||
// }
|
||||
|
||||
if(DistributedChatService::handleRecvItem(dynamic_cast<RsChatItem*>(item)))
|
||||
{
|
||||
@ -749,7 +757,13 @@ bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *ci)
|
||||
cm.incoming = true;
|
||||
cm.online = true;
|
||||
RsServer::notify()->notifyChatMessage(cm);
|
||||
mHistoryMgr->addMessage(cm);
|
||||
|
||||
// cyril: history is temporarily diabled for distant chat, since we need to store the full tunnel ID, but then
|
||||
// at loading time, the ID is not known so that chat window shows 00000000 as a peer.
|
||||
|
||||
if(!cm.chat_id.isDistantChatId())
|
||||
mHistoryMgr->addMessage(cm);
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
@ -766,7 +780,7 @@ void p3ChatService::handleRecvChatStatusItem(RsChatStatusItem *cs)
|
||||
std::cerr << "Received status string \"" << cs->status_string << "\"" << std::endl ;
|
||||
#endif
|
||||
|
||||
uint32_t status;
|
||||
DistantChatPeerInfo dcpinfo;
|
||||
|
||||
if(cs->flags & RS_CHAT_FLAG_REQUEST_CUSTOM_STATE) // no state here just a request.
|
||||
sendCustomState(cs->PeerId()) ;
|
||||
@ -782,9 +796,9 @@ void p3ChatService::handleRecvChatStatusItem(RsChatStatusItem *cs)
|
||||
#endif
|
||||
sendCustomStateRequest(cs->PeerId()) ;
|
||||
}
|
||||
else if(DistantChatService::getDistantChatStatus(RsGxsId(cs->PeerId()), status))
|
||||
else if(DistantChatService::getDistantChatStatus(DistantChatPeerId(cs->PeerId()), dcpinfo))
|
||||
{
|
||||
RsServer::notify()->notifyChatStatus(ChatId(RsGxsId(cs->PeerId())), cs->status_string) ;
|
||||
RsServer::notify()->notifyChatStatus(ChatId(DistantChatPeerId(cs->PeerId())), cs->status_string) ;
|
||||
}
|
||||
else if(cs->flags & RS_CHAT_FLAG_PRIVATE)
|
||||
{
|
||||
@ -816,9 +830,9 @@ void p3ChatService::initChatMessage(RsChatMsgItem *c, ChatMessage &m)
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t status;
|
||||
if(DistantChatService::getDistantChatStatus(RsGxsId(c->PeerId()), status))
|
||||
m.chat_id = ChatId(RsGxsId(c->PeerId()));
|
||||
DistantChatPeerInfo dcpinfo;
|
||||
if(DistantChatService::getDistantChatStatus(DistantChatPeerId(c->PeerId()), dcpinfo))
|
||||
m.chat_id = ChatId(DistantChatPeerId(c->PeerId()));
|
||||
|
||||
if (c -> chatFlags & RS_CHAT_FLAG_PRIVATE)
|
||||
m.chatflags |= RS_CHAT_PRIVATE;
|
||||
|
@ -51,18 +51,6 @@ std::ostream& RsChatMsgItem::print(std::ostream &out, uint16_t indent)
|
||||
printRsItemEnd(out, "RsChatMsgItem", indent);
|
||||
return out;
|
||||
}
|
||||
std::ostream& RsChatDHPublicKeyItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsChatDHPublicKeyItem", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << " Signature Key ID: " << signature.keyId << std::endl ;
|
||||
out << " Public Key ID: " << gxs_key.keyId << std::endl ;
|
||||
|
||||
printRsItemEnd(out, "RsChatMsgItem", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& RsChatLobbyListItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
@ -277,7 +265,6 @@ RsItem *RsChatSerialiser::deserialise(void *data, uint32_t *pktsize)
|
||||
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST: return new RsChatLobbyListRequestItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST: return new RsChatLobbyListItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG: return new RsChatLobbyConfigItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY: return new RsChatDHPublicKeyItem(data,*pktsize) ;
|
||||
default:
|
||||
std::cerr << "Unknown packet type in chat!" << std::endl ;
|
||||
return NULL ;
|
||||
@ -437,17 +424,6 @@ uint32_t RsChatLobbyConfigItem::serial_size()
|
||||
return s;
|
||||
}
|
||||
|
||||
uint32_t RsChatDHPublicKeyItem::serial_size()
|
||||
{
|
||||
uint32_t s = 8 ; // header
|
||||
s += 4 ; // BN size
|
||||
s += BN_num_bytes(public_key) ; // public_key
|
||||
s += signature.TlvSize() ; // signature
|
||||
s += gxs_key.TlvSize() ; // gxs_key
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
RsChatAvatarItem::~RsChatAvatarItem()
|
||||
@ -459,41 +435,6 @@ RsChatAvatarItem::~RsChatAvatarItem()
|
||||
}
|
||||
}
|
||||
|
||||
bool RsChatDHPublicKeyItem::serialise(void *data,uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size() ;
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
uint32_t s = BN_num_bytes(public_key) ;
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, s);
|
||||
|
||||
BN_bn2bin(public_key,&((unsigned char *)data)[offset]) ;
|
||||
offset += s ;
|
||||
|
||||
ok &= signature.SetTlv(data, tlvsize, &offset);
|
||||
ok &= gxs_key.SetTlv(data, tlvsize, &offset);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "RsChatDHPublicKeyItem::serialiseItem() Size Error! offset=" << offset << ", tlvsize=" << tlvsize << std::endl;
|
||||
}
|
||||
return ok ;
|
||||
}
|
||||
|
||||
/* serialise the data to the buffer */
|
||||
bool RsChatMsgItem::serialise(void *data, uint32_t& pktsize)
|
||||
{
|
||||
@ -995,28 +936,6 @@ bool RsChatLobbyConfigItem::serialise(void *data, uint32_t& pktsize)
|
||||
return ok;
|
||||
}
|
||||
|
||||
RsChatDHPublicKeyItem::RsChatDHPublicKeyItem(void *data,uint32_t /*size*/)
|
||||
: RsChatItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY)
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
bool ok = true ;
|
||||
|
||||
uint32_t s=0 ;
|
||||
/* get mandatory parts first */
|
||||
ok &= getRawUInt32(data, rssize, &offset, &s);
|
||||
|
||||
public_key = BN_bin2bn(&((unsigned char *)data)[offset],s,NULL) ;
|
||||
offset += s ;
|
||||
|
||||
ok &= signature.GetTlv(data, rssize, &offset) ;
|
||||
ok &= gxs_key.GetTlv(data, rssize, &offset) ;
|
||||
|
||||
if (offset != rssize)
|
||||
std::cerr << "RsChatDHPublicKeyItem::() Size error while deserializing." << std::endl ;
|
||||
if (!ok)
|
||||
std::cerr << "RsChatDHPublicKeyItem::() Unknown error while deserializing." << std::endl ;
|
||||
}
|
||||
RsChatMsgItem::RsChatMsgItem(void *data,uint32_t /*size*/,uint8_t subtype)
|
||||
: RsChatItem(subtype)
|
||||
{
|
||||
|
@ -316,6 +316,7 @@ bool p3GRouter::registerKey(const RsGxsId& authentication_key,const GRouterServi
|
||||
grouter_debug() << " Auth GXS Id : " << authentication_key << std::endl;
|
||||
grouter_debug() << " Client id : " << std::hex << client_id << std::dec << std::endl;
|
||||
grouter_debug() << " Description : " << info.description_string << std::endl;
|
||||
grouter_debug() << " Hash : " << hash << std::endl;
|
||||
#endif
|
||||
|
||||
return true ;
|
||||
@ -510,6 +511,12 @@ void p3GRouter::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,const RsFileH
|
||||
|
||||
RsItem *itm = RsGRouterSerialiser().deserialise(item->data_bytes,&item->data_size) ;
|
||||
|
||||
if(itm == NULL)
|
||||
{
|
||||
std::cerr << "(EE) p3GRouter::receiveTurtleData(): cannot de-serialise data. Somthing wrong in the format. Item data (size="<< item->data_size << "): " << RsUtil::BinToHex((char*)item->data_bytes,item->data_size) << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
itm->PeerId(virtual_peer_id) ;
|
||||
|
||||
// At this point we can have either a transaction chunk, or a transaction ACK.
|
||||
@ -1674,10 +1681,14 @@ bool p3GRouter::locked_getClientAndServiceId(const TurtleFileHash& hash, const R
|
||||
{
|
||||
client = NULL ;
|
||||
service_id = 0;
|
||||
|
||||
RsGxsId gxs_id ;
|
||||
makeGxsIdAndClientId(hash,gxs_id,service_id) ;
|
||||
|
||||
|
||||
if(!locked_getGxsIdAndClientId(hash,gxs_id,service_id))
|
||||
{
|
||||
std::cerr << " p3GRouter::ERROR: locked_getGxsIdAndClientId(): no key registered for hash " << hash << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
if(gxs_id != destination_key)
|
||||
{
|
||||
std::cerr << " ERROR: verification (destination) GXS key " << destination_key << " does not match key from hash " << gxs_id << std::endl;
|
||||
@ -2013,15 +2024,25 @@ Sha1CheckSum p3GRouter::makeTunnelHash(const RsGxsId& destination,const GRouterS
|
||||
bytes[18] = (client >> 8) & 0xff ;
|
||||
bytes[19] = client & 0xff ;
|
||||
|
||||
return Sha1CheckSum(bytes) ;
|
||||
return RsDirUtil::sha1sum(bytes,20) ;
|
||||
}
|
||||
void p3GRouter::makeGxsIdAndClientId(const TurtleFileHash& sum,RsGxsId& gxs_id,GRouterServiceId& client_id)
|
||||
bool p3GRouter::locked_getGxsIdAndClientId(const TurtleFileHash& sum,RsGxsId& gxs_id,GRouterServiceId& client_id)
|
||||
{
|
||||
assert( gxs_id.SIZE_IN_BYTES == 16) ;
|
||||
assert(Sha1CheckSum::SIZE_IN_BYTES == 20) ;
|
||||
|
||||
gxs_id = RsGxsId(sum.toByteArray());// takes the first 16 bytes
|
||||
client_id = sum.toByteArray()[19] + (sum.toByteArray()[18] << 8) ;
|
||||
//gxs_id = RsGxsId(sum.toByteArray());// takes the first 16 bytes
|
||||
//client_id = sum.toByteArray()[19] + (sum.toByteArray()[18] << 8) ;
|
||||
|
||||
std::map<Sha1CheckSum, GRouterPublishedKeyInfo>::const_iterator it = _owned_key_ids.find(sum);
|
||||
|
||||
if(it == _owned_key_ids.end())
|
||||
return false ;
|
||||
|
||||
gxs_id = it->second.authentication_key ;
|
||||
client_id = it->second.service_id ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
bool p3GRouter::loadList(std::list<RsItem*>& items)
|
||||
{
|
||||
|
@ -269,8 +269,8 @@ private:
|
||||
bool decryptDataItem(RsGRouterGenericDataItem *item) ;
|
||||
|
||||
static Sha1CheckSum makeTunnelHash(const RsGxsId& destination,const GRouterServiceId& client);
|
||||
static void makeGxsIdAndClientId(const TurtleFileHash &sum,RsGxsId& gxs_id,GRouterServiceId& client_id);
|
||||
|
||||
bool locked_getGxsIdAndClientId(const TurtleFileHash &sum,RsGxsId& gxs_id,GRouterServiceId& client_id);
|
||||
bool locked_sendTransactionData(const RsPeerId& pid,const RsGRouterTransactionItem& item);
|
||||
|
||||
void locked_collectAvailableFriends(const GRouterKeyId &gxs_id,std::list<RsPeerId>& friend_peers, const std::set<RsPeerId>& incoming_routes,bool is_origin);
|
||||
|
1582
libretroshare/src/gxstunnel/p3gxstunnel.cc
Normal file
1582
libretroshare/src/gxstunnel/p3gxstunnel.cc
Normal file
File diff suppressed because it is too large
Load Diff
261
libretroshare/src/gxstunnel/p3gxstunnel.h
Normal file
261
libretroshare/src/gxstunnel/p3gxstunnel.h
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* libretroshare/src/chat: distantchat.h
|
||||
*
|
||||
* Services for RetroShare.
|
||||
*
|
||||
* Copyright 2015 by Cyril Soler
|
||||
*
|
||||
* 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 "csoler@users.sourceforge.net".
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Generic tunnel service
|
||||
//
|
||||
// Preconditions:
|
||||
// * the secured tunnel service takes care of:
|
||||
// - tunnel health: tunnels are kept alive using special items, re-openned when necessary, etc.
|
||||
// - transport: items are ACK-ed and re-sent if never received
|
||||
// - encryption: items are all encrypted and authenticated using PFS(DH)+HMAC(sha1)+AES(128)
|
||||
// * each tunnel is associated to a specific GXS id on both sides. Consequently, services that request tunnels from different IDs to a
|
||||
// server for the same GXS id need to be handled correctly.
|
||||
// * client services must register to the secured tunnel service if they want to use it.
|
||||
// * multiple services can use the same tunnel. Items contain a service Id that is obtained when registering to the secured tunnel service.
|
||||
//
|
||||
// GUI
|
||||
// * the GUI should show for each tunnel:
|
||||
// - starting and ending GXS ids
|
||||
// - tunnel status (DH ok, closed from distant peer, locally closed, etc)
|
||||
// - amount of data that is transferred in the tunnel
|
||||
// - number of pending items (and total size)
|
||||
// - number ACKed items both ways.
|
||||
//
|
||||
// We can use an additional tab "Authenticated tunnels" in the statistics->turtle window for that purpose.
|
||||
//
|
||||
// Interaction with services:
|
||||
//
|
||||
// Services request tunnels from a given GXS id and to a given GXS id. When ready, they get a handle (type = RsGxsTunnelId)
|
||||
//
|
||||
// Services send data in the tunnel using the virtual peer id
|
||||
//
|
||||
// Data is send to a service ID (could be any existing service ID). The endpoint of the tunnel must register each service, in order to
|
||||
// allow the data to be transmitted/sent from/to that service. Otherwise an error is issued.
|
||||
//
|
||||
// Encryption
|
||||
// * the whole tunnel traffic is encrypted using AES-128 with random IV
|
||||
// * a random key is established using DH key exchange for each connection (establishment of a new virtual peer)
|
||||
// * encrypted items are authenticated with HMAC(sha1).
|
||||
// * DH public keys are the only chunks of data that travel un-encrypted along the tunnel. They are
|
||||
// signed to avoid any MITM interactions. No time-stamp is used in DH exchange since a replay attack would not work.
|
||||
//
|
||||
// Algorithms
|
||||
//
|
||||
// * we need two layers: the turtle layer, and the GXS id layer.
|
||||
// - for each pair of GXS ids talking, a single turtle tunnel is used
|
||||
// - that tunnel can be shared by multiple services using it.
|
||||
// - services are responsoble for asking tunnels and also droppping them when unused.
|
||||
// - at the turtle layer, the tunnel will be effectively closed only when no service uses it.
|
||||
// * IDs
|
||||
// TurtleVirtualPeerId:
|
||||
// - Used by tunnel service for each turtle tunnel
|
||||
// - one virtual peer ID per GXS tunnel
|
||||
//
|
||||
// GxsTunnelId:
|
||||
// - one GxsTunnelId per couple of GXS ids. But we also need to allow multiple services to use the tunnel.
|
||||
//
|
||||
// * at the turtle layer:
|
||||
// - accept virtual peers from turtle tunnel service. The hash for that VP only depends on the server GXS id at server side, which is our
|
||||
// own ID at server side, and destination ID at client side. What happens if two different clients request to talk to the same GXS id? (same hash)
|
||||
// They should use different virtual peers, so it should be ok.
|
||||
//
|
||||
// Turtle hash: [ 0 ---------------15 16---19 ]
|
||||
// Destination Random
|
||||
//
|
||||
// We Use 16 bytes to target the exact destination of the hash. The source part is just 4 arbitrary bytes that need to be different for all source
|
||||
// IDs that come from the same peer, which is quite likely to be sufficient. The real source of the tunnel will make itself known when sending the
|
||||
// DH key.
|
||||
//
|
||||
// * at the GXS layer
|
||||
// - we should be able to have as many tunnels as they are different couples of GXS ids to interact. That means the tunnel should be determined
|
||||
// by a mix between our own GXS id and the GXS id we're talking to. That is what the TunnelVirtualPeer is.
|
||||
//
|
||||
//
|
||||
// RequestTunnel(source_own_id,destination_id) -
|
||||
// | |
|
||||
// +---------------------------> p3Turtle::monitorTunnels( hash(destination_id) ) |
|
||||
// | |
|
||||
// [Turtle async work] -------------------+ | Turtle layer: one virtual peer id
|
||||
// | | |
|
||||
// handleTunnelRequest() <-----------------------------------------------+ | |
|
||||
// | | |
|
||||
// +---------------- keep record in _gxs_tunnel_virtual_peer_id, initiate DH exchange | -
|
||||
// | |
|
||||
// handleDHPublicKey() <-----------------------------------------------------------------------------+ |
|
||||
// | |
|
||||
// +---------------- update _gxs_tunnel_contacts[ tunnel_hash = hash(own_id, destination_id) ] | GxsTunnelId level
|
||||
// | |
|
||||
// +---------------- notify client service that Peer(destination_id, tunnel_hash) is ready to talk to |
|
||||
// -
|
||||
|
||||
#include <turtle/turtleclientservice.h>
|
||||
#include <retroshare/rsgxstunnel.h>
|
||||
#include <services/p3service.h>
|
||||
#include <gxstunnel/rsgxstunnelitems.h>
|
||||
|
||||
class RsGixs ;
|
||||
|
||||
static const uint32_t GXS_TUNNEL_AES_KEY_SIZE = 16 ;
|
||||
|
||||
class p3GxsTunnelService: public RsGxsTunnelService, public RsTurtleClientService, public p3Service
|
||||
{
|
||||
public:
|
||||
p3GxsTunnelService(RsGixs *pids) ;
|
||||
virtual void connectToTurtleRouter(p3turtle *) ;
|
||||
|
||||
// Creates the invite if the public key of the distant peer is available.
|
||||
// Om success, stores the invite in the map above, so that we can respond to tunnel requests.
|
||||
//
|
||||
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t service_id,uint32_t& error_code) ;
|
||||
|
||||
virtual bool closeExistingTunnel(const RsGxsTunnelId &tunnel_id,uint32_t service_id) ;
|
||||
virtual bool getTunnelsInfo(std::vector<GxsTunnelInfo>& infos);
|
||||
virtual bool getTunnelInfo(const RsGxsTunnelId& tunnel_id,GxsTunnelInfo& info);
|
||||
virtual bool sendData(const RsGxsTunnelId& tunnel_id,uint32_t service_id,const uint8_t *data,uint32_t size) ;
|
||||
|
||||
virtual bool registerClientService(uint32_t service_id,RsGxsTunnelClientService *service) ;
|
||||
|
||||
// derived from p3service
|
||||
|
||||
virtual int tick();
|
||||
virtual RsServiceInfo getServiceInfo();
|
||||
|
||||
private:
|
||||
void flush() ;
|
||||
virtual void handleIncomingItem(const RsGxsTunnelId &tunnel_id, RsGxsTunnelItem *) ;
|
||||
|
||||
class GxsTunnelPeerInfo
|
||||
{
|
||||
public:
|
||||
GxsTunnelPeerInfo() : last_contact(0), last_keep_alive_sent(0), status(0), direction(0)
|
||||
{
|
||||
memset(aes_key, 0, GXS_TUNNEL_AES_KEY_SIZE);
|
||||
|
||||
total_sent = 0 ;
|
||||
total_received = 0 ;
|
||||
}
|
||||
|
||||
time_t last_contact ; // used to keep track of working connexion
|
||||
time_t last_keep_alive_sent ; // last time we sent a keep alive packet.
|
||||
|
||||
unsigned char aes_key[GXS_TUNNEL_AES_KEY_SIZE] ;
|
||||
|
||||
uint32_t status ; // info: do we have a tunnel ?
|
||||
RsPeerId virtual_peer_id; // given by the turtle router. Identifies the tunnel.
|
||||
RsGxsId to_gxs_id; // gxs id we're talking to
|
||||
RsGxsId own_gxs_id ; // gxs id we're using to talk.
|
||||
RsTurtleGenericTunnelItem::Direction direction ; // specifiec wether we are client(managing the tunnel) or server.
|
||||
TurtleFileHash hash ; // hash that is last used. This is necessary for handling tunnel establishment
|
||||
std::set<uint32_t> client_services ;// services that used this tunnel
|
||||
uint32_t total_sent ;
|
||||
uint32_t total_received ;
|
||||
};
|
||||
|
||||
class GxsTunnelDHInfo
|
||||
{
|
||||
public:
|
||||
GxsTunnelDHInfo() : dh(0), direction(0), status(0) {}
|
||||
|
||||
DH *dh ;
|
||||
RsGxsId gxs_id ;
|
||||
RsGxsId own_gxs_id ;
|
||||
RsGxsTunnelId tunnel_id ; // this is a proxy, since we cna always recompute that from the two previous values.
|
||||
RsTurtleGenericTunnelItem::Direction direction ;
|
||||
uint32_t status ;
|
||||
TurtleFileHash hash ;
|
||||
};
|
||||
|
||||
struct GxsTunnelData
|
||||
{
|
||||
RsGxsTunnelDataItem *data_item ;
|
||||
time_t last_sending_attempt ;
|
||||
};
|
||||
|
||||
// This maps contains the current peers to talk to with distant chat.
|
||||
//
|
||||
std::map<RsGxsTunnelId,GxsTunnelPeerInfo> _gxs_tunnel_contacts ; // current peers we can talk to
|
||||
std::map<TurtleVirtualPeerId,GxsTunnelDHInfo> _gxs_tunnel_virtual_peer_ids ; // current virtual peers. Used to figure out tunnels, etc.
|
||||
|
||||
// List of items to be sent asap. Used to store items that we cannot pass directly to
|
||||
// sendTurtleData(), because of Mutex protection.
|
||||
|
||||
std::map<uint64_t,GxsTunnelData> pendingGxsTunnelDataItems ; // items that need provable transport and encryption
|
||||
std::list<RsGxsTunnelItem*> pendingGxsTunnelItems ; // items that do not need provable transport, yet need encryption
|
||||
std::list<RsGxsTunnelDHPublicKeyItem*> pendingDHItems ;
|
||||
|
||||
// Overloaded from RsTurtleClientService
|
||||
|
||||
virtual bool handleTunnelRequest(const RsFileHash &hash,const RsPeerId& peer_id) ;
|
||||
virtual void receiveTurtleData(RsTurtleGenericTunnelItem *item,const RsFileHash& hash,const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction) ;
|
||||
void addVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&,RsTurtleGenericTunnelItem::Direction dir) ;
|
||||
void removeVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&) ;
|
||||
|
||||
// session handling handles
|
||||
|
||||
void startClientGxsTunnelConnection(const RsGxsId &to_gxs_id, const RsGxsId& from_gxs_id, uint32_t service_id, RsGxsTunnelId &tunnel_id) ;
|
||||
void locked_restartDHSession(const RsPeerId &virtual_peer_id, const RsGxsId &own_gxs_id) ;
|
||||
|
||||
// utility functions
|
||||
|
||||
static TurtleFileHash randomHashFromDestinationGxsId(const RsGxsId& destination) ;
|
||||
static RsGxsId destinationGxsIdFromHash(const TurtleFileHash& sum) ;
|
||||
|
||||
// Cryptography management
|
||||
|
||||
void handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item) ;
|
||||
bool locked_sendDHPublicKey(const DH *dh, const RsGxsId& own_gxs_id, const RsPeerId& virtual_peer_id) ;
|
||||
bool locked_initDHSessionKey(DH *&dh);
|
||||
|
||||
TurtleVirtualPeerId virtualPeerIdFromHash(const TurtleFileHash& hash) ; // ... and to a hash for p3turtle
|
||||
RsGxsTunnelId makeGxsTunnelId(const RsGxsId &own_id, const RsGxsId &distant_id) const; // creates a unique ID from two GXS ids.
|
||||
|
||||
// item handling
|
||||
|
||||
void handleRecvStatusItem(const RsGxsTunnelId& id,RsGxsTunnelStatusItem *item) ;
|
||||
void handleRecvTunnelDataItem(const RsGxsTunnelId& id,RsGxsTunnelDataItem *item) ;
|
||||
void handleRecvTunnelDataAckItem(const RsGxsTunnelId &id, RsGxsTunnelDataAckItem *item);
|
||||
|
||||
// Comunication with Turtle service
|
||||
|
||||
bool locked_sendEncryptedTunnelData(RsGxsTunnelItem *item) ;
|
||||
bool locked_sendClearTunnelData(RsGxsTunnelDHPublicKeyItem *item); // this limits the usage to DH items. Others should be encrypted!
|
||||
|
||||
bool handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id) ;
|
||||
|
||||
// local data
|
||||
|
||||
p3turtle *mTurtle ;
|
||||
RsGixs *mGixs ;
|
||||
RsMutex mGxsTunnelMtx ;
|
||||
|
||||
uint64_t global_item_counter ;
|
||||
|
||||
std::map<uint32_t,RsGxsTunnelClientService*> mRegisteredServices ;
|
||||
|
||||
void debug_dump();
|
||||
};
|
||||
|
486
libretroshare/src/gxstunnel/rsgxstunnelitems.cc
Normal file
486
libretroshare/src/gxstunnel/rsgxstunnelitems.cc
Normal file
@ -0,0 +1,486 @@
|
||||
|
||||
/*
|
||||
* libretroshare/src/serialiser: rsbaseitems.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 <stdexcept>
|
||||
#include <time.h>
|
||||
#include "serialiser/rsbaseserial.h"
|
||||
#include "serialiser/rstlvbase.h"
|
||||
#include "util/rsprint.h"
|
||||
|
||||
#include "gxstunnel/rsgxstunnelitems.h"
|
||||
|
||||
#define GXS_TUNNEL_ITEM_DEBUG 1
|
||||
|
||||
std::ostream& RsGxsTunnelDHPublicKeyItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsGxsTunnelDHPublicKeyItem", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << " Signature Key ID: " << signature.keyId << std::endl ;
|
||||
out << " Public Key ID: " << gxs_key.keyId << std::endl ;
|
||||
|
||||
printRsItemEnd(out, "RsGxsTunnelMsgItem", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& RsGxsTunnelDataItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsGxsTunnelDataItem", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << " message id : " << std::hex << unique_item_counter << std::dec << std::endl ;
|
||||
out << " service id : " << std::hex << service_id << std::dec << std::endl ;
|
||||
out << " flags : " << std::hex << flags << std::dec << std::endl ;
|
||||
out << " size : " << data_size << std::endl ;
|
||||
out << " data : " << RsUtil::BinToHex(data,std::min(50u,data_size)) << ((data_size>50u)?"...":"") << std::endl ;
|
||||
|
||||
printRsItemEnd(out, "RsGxsTunnelDataItem", indent);
|
||||
return out;
|
||||
}
|
||||
std::ostream& RsGxsTunnelDataAckItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsGxsTunnelDataItem", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << " message id : " << std::hex << unique_item_counter << std::dec << std::endl ;
|
||||
|
||||
printRsItemEnd(out, "RsGxsTunnelDataAckItem", indent);
|
||||
return out;
|
||||
}
|
||||
std::ostream& RsGxsTunnelStatusItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsGxsTunnelDataItem", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << " flags : " << std::hex << status << std::dec << std::endl ;
|
||||
|
||||
printRsItemEnd(out, "RsGxsTunnelStatusItem", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
RsGxsTunnelDHPublicKeyItem::~RsGxsTunnelDHPublicKeyItem()
|
||||
{
|
||||
BN_free(public_key) ;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
RsItem *RsGxsTunnelSerialiser::deserialise(void *data, uint32_t *pktsize)
|
||||
{
|
||||
uint32_t rstype = getRsItemId(data);
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
|
||||
#ifdef GXS_TUNNEL_ITEM_DEBUG
|
||||
std::cerr << "deserializing packet..."<< std::endl ;
|
||||
#endif
|
||||
// look what we have...
|
||||
if (*pktsize < rssize) /* check size */
|
||||
{
|
||||
std::cerr << "GxsTunnel deserialisation: not enough size: pktsize=" << *pktsize << ", rssize=" << rssize << std::endl ;
|
||||
return NULL; /* not enough data */
|
||||
}
|
||||
|
||||
/* set the packet length */
|
||||
*pktsize = rssize;
|
||||
|
||||
/* ready to load */
|
||||
|
||||
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_GXS_TUNNEL != getRsItemService(rstype)))
|
||||
{
|
||||
#ifdef GXS_TUNNEL_ITEM_DEBUG
|
||||
std::cerr << "GxsTunnel deserialisation: wrong type !" << std::endl ;
|
||||
#endif
|
||||
return NULL; /* wrong type */
|
||||
}
|
||||
|
||||
switch(getRsItemSubType(rstype))
|
||||
{
|
||||
case RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY: return deserialise_RsGxsTunnelDHPublicKeyItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA: return deserialise_RsGxsTunnelDataItem (data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK: return deserialise_RsGxsTunnelDataAckItem (data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS: return deserialise_RsGxsTunnelStatusItem (data,*pktsize) ;
|
||||
default:
|
||||
std::cerr << "Unknown packet type in chat!" << std::endl ;
|
||||
return NULL ;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
uint32_t RsGxsTunnelDHPublicKeyItem::serial_size()
|
||||
{
|
||||
uint32_t s = 8 ; // header
|
||||
s += 4 ; // BN size
|
||||
s += BN_num_bytes(public_key) ; // public_key
|
||||
s += signature.TlvSize() ; // signature
|
||||
s += gxs_key.TlvSize() ; // gxs_key
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsGxsTunnelDataItem::serial_size()
|
||||
{
|
||||
uint32_t s = 8 ; // header
|
||||
s += 8 ; // counter
|
||||
s += 4 ; // flags
|
||||
s += 4 ; // service id
|
||||
s += 4 ; // data_size
|
||||
s += data_size; // data
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsGxsTunnelDataAckItem::serial_size()
|
||||
{
|
||||
uint32_t s = 8 ; // header
|
||||
s += 8 ; // counter
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsGxsTunnelStatusItem::serial_size()
|
||||
{
|
||||
uint32_t s = 8 ; // header
|
||||
s += 4 ; // flags
|
||||
|
||||
return s ;
|
||||
}
|
||||
/*************************************************************************/
|
||||
|
||||
bool RsGxsTunnelDHPublicKeyItem::serialise(void *data,uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size() ;
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
uint32_t s = BN_num_bytes(public_key) ;
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, s);
|
||||
|
||||
BN_bn2bin(public_key,&((unsigned char *)data)[offset]) ;
|
||||
offset += s ;
|
||||
|
||||
ok &= signature.SetTlv(data, tlvsize, &offset);
|
||||
ok &= gxs_key.SetTlv(data, tlvsize, &offset);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "RsGxsTunnelDHPublicKeyItem::serialiseItem() Size Error! offset=" << offset << ", tlvsize=" << tlvsize << std::endl;
|
||||
}
|
||||
return ok ;
|
||||
}
|
||||
|
||||
bool RsGxsTunnelStatusItem::serialise(void *data, uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size() ;
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize);
|
||||
|
||||
#ifdef GXS_TUNNEL_ITEM_DEBUG
|
||||
std::cerr << "RsGxsTunnelSerialiser serialising chat status item." << std::endl;
|
||||
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Header: " << ok << std::endl;
|
||||
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Size: " << tlvsize << std::endl;
|
||||
#endif
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, status);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Size Error! " << std::endl;
|
||||
}
|
||||
#ifdef GXS_TUNNEL_ITEM_DEBUG
|
||||
std::cerr << "computed size: " << 256*((unsigned char*)data)[6]+((unsigned char*)data)[7] << std::endl ;
|
||||
#endif
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RsGxsTunnelDataItem::serialise(void *dt, uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size() ;
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(dt, tlvsize, PacketId(), tlvsize);
|
||||
|
||||
#ifdef GXS_TUNNEL_ITEM_DEBUG
|
||||
std::cerr << "RsGxsTunnelSerialiser serialising chat status item." << std::endl;
|
||||
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Header: " << ok << std::endl;
|
||||
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Size: " << tlvsize << std::endl;
|
||||
#endif
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= setRawUInt64(dt, tlvsize, &offset, unique_item_counter);
|
||||
ok &= setRawUInt32(dt, tlvsize, &offset, flags);
|
||||
ok &= setRawUInt32(dt, tlvsize, &offset, service_id);
|
||||
ok &= setRawUInt32(dt, tlvsize, &offset, data_size);
|
||||
|
||||
if(offset + data_size <= tlvsize)
|
||||
{
|
||||
memcpy(&((uint8_t*)dt)[offset],data,data_size) ;
|
||||
offset += data_size ;
|
||||
}
|
||||
else
|
||||
ok = false ;
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Size Error! " << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
bool RsGxsTunnelDataAckItem::serialise(void *data, uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size() ;
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize);
|
||||
|
||||
#ifdef GXS_TUNNEL_ITEM_DEBUG
|
||||
std::cerr << "RsGxsTunnelSerialiser serialising chat status item." << std::endl;
|
||||
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Header: " << ok << std::endl;
|
||||
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Size: " << tlvsize << std::endl;
|
||||
#endif
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= setRawUInt64(data, tlvsize, &offset, unique_item_counter);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Size Error! " << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
RsGxsTunnelDHPublicKeyItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelDHPublicKeyItem(void *data,uint32_t /*size*/)
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
bool ok = true ;
|
||||
|
||||
RsGxsTunnelDHPublicKeyItem *item = new RsGxsTunnelDHPublicKeyItem() ;
|
||||
|
||||
uint32_t s=0 ;
|
||||
/* get mandatory parts first */
|
||||
ok &= getRawUInt32(data, rssize, &offset, &s);
|
||||
|
||||
item->public_key = BN_bin2bn(&((unsigned char *)data)[offset],s,NULL) ;
|
||||
offset += s ;
|
||||
|
||||
ok &= item->signature.GetTlv(data, rssize, &offset) ;
|
||||
ok &= item->gxs_key.GetTlv(data, rssize, &offset) ;
|
||||
|
||||
if (offset != rssize)
|
||||
{
|
||||
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Size error while deserializing." << std::endl ;
|
||||
delete item ;
|
||||
return NULL ;
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Unknown error while deserializing." << std::endl ;
|
||||
delete item ;
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
return item ;
|
||||
}
|
||||
|
||||
RsGxsTunnelDataItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelDataItem(void *dat,uint32_t size)
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(dat);
|
||||
bool ok = true ;
|
||||
|
||||
RsGxsTunnelDataItem *item = new RsGxsTunnelDataItem();
|
||||
|
||||
/* get mandatory parts first */
|
||||
|
||||
ok &= getRawUInt64(dat, rssize, &offset, &item->unique_item_counter);
|
||||
ok &= getRawUInt32(dat, rssize, &offset, &item->flags);
|
||||
ok &= getRawUInt32(dat, rssize, &offset, &item->service_id);
|
||||
ok &= getRawUInt32(dat, rssize, &offset, &item->data_size);
|
||||
|
||||
if(offset + item->data_size <= size)
|
||||
{
|
||||
item->data = (unsigned char*)malloc(item->data_size) ;
|
||||
|
||||
if(dat == NULL)
|
||||
{
|
||||
delete item ;
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
memcpy(item->data,&((uint8_t*)dat)[offset],item->data_size) ;
|
||||
offset += item->data_size ;
|
||||
}
|
||||
else
|
||||
ok = false ;
|
||||
|
||||
|
||||
if (offset != rssize)
|
||||
{
|
||||
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Size error while deserializing." << std::endl ;
|
||||
delete item ;
|
||||
return NULL ;
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Unknown error while deserializing." << std::endl ;
|
||||
delete item ;
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
return item ;
|
||||
}
|
||||
|
||||
RsGxsTunnelDataAckItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelDataAckItem(void *dat,uint32_t /* size */)
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(dat);
|
||||
bool ok = true ;
|
||||
|
||||
RsGxsTunnelDataAckItem *item = new RsGxsTunnelDataAckItem();
|
||||
|
||||
/* get mandatory parts first */
|
||||
|
||||
ok &= getRawUInt64(dat, rssize, &offset, &item->unique_item_counter);
|
||||
|
||||
if (offset != rssize)
|
||||
{
|
||||
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Size error while deserializing." << std::endl ;
|
||||
delete item ;
|
||||
return NULL ;
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Unknown error while deserializing." << std::endl ;
|
||||
delete item ;
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
return item ;
|
||||
}
|
||||
|
||||
RsGxsTunnelStatusItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelStatusItem(void *dat,uint32_t size)
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(dat);
|
||||
bool ok = true ;
|
||||
|
||||
RsGxsTunnelStatusItem *item = new RsGxsTunnelStatusItem();
|
||||
|
||||
/* get mandatory parts first */
|
||||
|
||||
ok &= getRawUInt32(dat, rssize, &offset, &item->status);
|
||||
|
||||
if (offset != rssize)
|
||||
{
|
||||
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Size error while deserializing." << std::endl ;
|
||||
delete item ;
|
||||
return NULL ;
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Unknown error while deserializing." << std::endl ;
|
||||
delete item ;
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
return item ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
177
libretroshare/src/gxstunnel/rsgxstunnelitems.h
Normal file
177
libretroshare/src/gxstunnel/rsgxstunnelitems.h
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* libretroshare/src/serialiser: rschatitems.h
|
||||
*
|
||||
* 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".
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "retroshare/rstypes.h"
|
||||
#include "serialiser/rstlvkeys.h"
|
||||
#include "serialiser/rsserviceids.h"
|
||||
#include "serialiser/rsserial.h"
|
||||
|
||||
#include "serialiser/rstlvidset.h"
|
||||
#include "serialiser/rstlvfileitem.h"
|
||||
|
||||
/* chat Flags */
|
||||
const uint32_t RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION = 0x0400;
|
||||
const uint32_t RS_GXS_TUNNEL_FLAG_ACK_DISTANT_CONNECTION = 0x0800;
|
||||
const uint32_t RS_GXS_TUNNEL_FLAG_KEEP_ALIVE = 0x1000;
|
||||
|
||||
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DATA = 0x01 ;
|
||||
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY = 0x02 ;
|
||||
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS = 0x03 ;
|
||||
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK = 0x04 ;
|
||||
|
||||
typedef uint64_t GxsTunnelDHSessionId ;
|
||||
|
||||
class RsGxsTunnelItem: public RsItem
|
||||
{
|
||||
public:
|
||||
RsGxsTunnelItem(uint8_t item_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_GXS_TUNNEL,item_subtype)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_CHAT_ITEM) ;
|
||||
}
|
||||
|
||||
virtual ~RsGxsTunnelItem() {}
|
||||
virtual void clear() {}
|
||||
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) = 0 ;
|
||||
|
||||
virtual bool serialise(void *data,uint32_t& size) = 0 ; // Isn't it better that items can serialize themselves ?
|
||||
virtual uint32_t serial_size() = 0 ; // deserialise is handled using a constructor
|
||||
};
|
||||
|
||||
/*!
|
||||
* For sending distant communication data. The item is not encrypted after being serialised, but the data it.
|
||||
* The MAC is computed over encrypted data using the PFS key. All other items (except DH keys) are serialised, encrypted, and
|
||||
* sent as data in a RsGxsTunnelDataItem.
|
||||
*
|
||||
* @see p3GxsTunnelService
|
||||
*/
|
||||
class RsGxsTunnelDataItem: public RsGxsTunnelItem
|
||||
{
|
||||
public:
|
||||
RsGxsTunnelDataItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DATA) { data=NULL ;data_size=0; }
|
||||
RsGxsTunnelDataItem(uint8_t subtype) :RsGxsTunnelItem(subtype) { data=NULL ;data_size=0; }
|
||||
|
||||
virtual ~RsGxsTunnelDataItem() {}
|
||||
virtual void clear() {}
|
||||
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
|
||||
|
||||
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
|
||||
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
|
||||
|
||||
uint64_t unique_item_counter; // this allows to make the item unique
|
||||
uint32_t flags; // mainly NEEDS_HACK?
|
||||
uint32_t service_id ;
|
||||
uint32_t data_size ; // encrypted data size
|
||||
unsigned char *data ; // encrypted data
|
||||
};
|
||||
|
||||
// Used to send status of connection. This can be closing orders, flushing orders, etc.
|
||||
// These items are always sent encrypted.
|
||||
|
||||
class RsGxsTunnelStatusItem: public RsGxsTunnelItem
|
||||
{
|
||||
public:
|
||||
RsGxsTunnelStatusItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS) {}
|
||||
RsGxsTunnelStatusItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual ~RsGxsTunnelStatusItem() {}
|
||||
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
|
||||
|
||||
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
|
||||
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
|
||||
|
||||
uint32_t status ;
|
||||
};
|
||||
|
||||
// Used to confirm reception of an encrypted item.
|
||||
|
||||
class RsGxsTunnelDataAckItem: public RsGxsTunnelItem
|
||||
{
|
||||
public:
|
||||
RsGxsTunnelDataAckItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK) {}
|
||||
RsGxsTunnelDataAckItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual ~RsGxsTunnelDataAckItem() {}
|
||||
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
|
||||
|
||||
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
|
||||
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
|
||||
|
||||
uint64_t unique_item_counter ; // unique identifier for that item
|
||||
};
|
||||
|
||||
|
||||
// This class contains the public Diffie-Hellman parameters to be sent
|
||||
// when performing a DH agreement over a distant chat tunnel.
|
||||
//
|
||||
class RsGxsTunnelDHPublicKeyItem: public RsGxsTunnelItem
|
||||
{
|
||||
public:
|
||||
RsGxsTunnelDHPublicKeyItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY) {}
|
||||
RsGxsTunnelDHPublicKeyItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual ~RsGxsTunnelDHPublicKeyItem() ;
|
||||
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
|
||||
|
||||
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
|
||||
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
|
||||
|
||||
// Private data to DH public key item
|
||||
//
|
||||
BIGNUM *public_key ;
|
||||
|
||||
RsTlvKeySignature signature ; // signs the public key in a row.
|
||||
RsTlvSecurityKey gxs_key ; // public key of the signer
|
||||
|
||||
private:
|
||||
// make the object non copy-able
|
||||
RsGxsTunnelDHPublicKeyItem(const RsGxsTunnelDHPublicKeyItem&) : RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY) {}
|
||||
const RsGxsTunnelDHPublicKeyItem& operator=(const RsGxsTunnelDHPublicKeyItem&) { return *this ;}
|
||||
};
|
||||
|
||||
class RsGxsTunnelSerialiser: public RsSerialType
|
||||
{
|
||||
public:
|
||||
RsGxsTunnelSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_TUNNEL) {}
|
||||
|
||||
virtual uint32_t size (RsItem *item)
|
||||
{
|
||||
return static_cast<RsGxsTunnelItem *>(item)->serial_size() ;
|
||||
}
|
||||
virtual bool serialise(RsItem *item, void *data, uint32_t *size)
|
||||
{
|
||||
return static_cast<RsGxsTunnelItem *>(item)->serialise(data,*size) ;
|
||||
}
|
||||
RsItem *deserialise(void *data, uint32_t *pktsize);
|
||||
private:
|
||||
static RsGxsTunnelDataAckItem *deserialise_RsGxsTunnelDataAckItem (void *data, uint32_t size) ;
|
||||
static RsGxsTunnelDataItem *deserialise_RsGxsTunnelDataItem (void *data, uint32_t size) ;
|
||||
static RsGxsTunnelStatusItem *deserialise_RsGxsTunnelStatusItem (void *data, uint32_t size) ;
|
||||
static RsGxsTunnelDHPublicKeyItem *deserialise_RsGxsTunnelDHPublicKeyItem(void *data, uint32_t size) ;
|
||||
};
|
||||
|
@ -731,6 +731,13 @@ SOURCES += serialiser/rsnxsitems.cc \
|
||||
gxs/rsgxsutil.cc \
|
||||
gxs/rsgxsrequesttypes.cc
|
||||
|
||||
# gxs tunnels
|
||||
HEADERS += gxstunnel/p3gxstunnel.h \
|
||||
gxstunnel/rsgxstunnelitems.h \
|
||||
retroshare/rsgxstunnel.h
|
||||
|
||||
SOURCES += gxstunnel/p3gxstunnel.cc \
|
||||
gxstunnel/rsgxstunnelitems.cc
|
||||
|
||||
# Identity Service
|
||||
HEADERS += retroshare/rsidentity.h \
|
||||
@ -851,3 +858,4 @@ test_bitdht {
|
||||
|
||||
# ENABLED UDP NOW.
|
||||
}
|
||||
|
||||
|
@ -208,7 +208,7 @@ p3Config::p3Config()
|
||||
}
|
||||
|
||||
|
||||
bool p3Config::loadConfiguration(RsFileHash &loadHash)
|
||||
bool p3Config::loadConfiguration(RsFileHash& /* loadHash */)
|
||||
{
|
||||
return loadConfig();
|
||||
}
|
||||
|
@ -103,17 +103,14 @@ void p3HistoryMgr::addMessage(const ChatMessage& cm)
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
if (cm.chat_id.isGxsId() && mPrivateEnable == true) {
|
||||
if (cm.incoming) {
|
||||
peerName = cm.chat_id.toGxsId().toStdString();
|
||||
} else {
|
||||
uint32_t status;
|
||||
RsGxsId from_gxs_id;
|
||||
if (rsMsgs->getDistantChatStatus(cm.chat_id.toGxsId(), status, &from_gxs_id))
|
||||
peerName = from_gxs_id.toStdString();
|
||||
}
|
||||
enabled = true;
|
||||
}
|
||||
if(cm.chat_id.isDistantChatId())
|
||||
{
|
||||
uint32_t status;
|
||||
DistantChatPeerInfo dcpinfo;
|
||||
if (rsMsgs->getDistantChatStatus(cm.chat_id.toDistantChatId(), dcpinfo))
|
||||
peerName = cm.chat_id.toPeerId().toStdString();
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
if(enabled == false)
|
||||
return;
|
||||
@ -411,8 +408,8 @@ bool p3HistoryMgr::chatIdToVirtualPeerId(ChatId chat_id, RsPeerId &peer_id)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (chat_id.isGxsId()) {
|
||||
peer_id = RsPeerId(chat_id.toGxsId());
|
||||
if (chat_id.isDistantChatId()) {
|
||||
peer_id = RsPeerId(chat_id.toDistantChatId());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -450,7 +447,7 @@ bool p3HistoryMgr::getMessages(const ChatId &chatId, std::list<HistoryMsg> &msgs
|
||||
if (chatId.isLobbyId() && mLobbyEnable == true) {
|
||||
enabled = true;
|
||||
}
|
||||
if (chatId.isGxsId() && mPrivateEnable == true) {
|
||||
if (chatId.isDistantChatId() && mPrivateEnable == true) {
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
|
132
libretroshare/src/retroshare/rsgxstunnel.h
Normal file
132
libretroshare/src/retroshare/rsgxstunnel.h
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* libretroshare/src/services: rsgrouter.h
|
||||
*
|
||||
* Services for RetroShare.
|
||||
*
|
||||
* Copyright 2013 by Cyril Soler
|
||||
*
|
||||
* 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 "csoler@users.sourceforge.net".
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "util/rsdir.h"
|
||||
#include "retroshare/rsids.h"
|
||||
#include "retroshare/rsturtle.h"
|
||||
#include "retroshare/rsgxsifacetypes.h"
|
||||
|
||||
class RsGxsTunnelService
|
||||
{
|
||||
public:
|
||||
typedef GXSTunnelId RsGxsTunnelId ;
|
||||
|
||||
enum {
|
||||
RS_GXS_TUNNEL_ERROR_NO_ERROR = 0x0000,
|
||||
RS_GXS_TUNNEL_ERROR_UNKNOWN_GXS_ID = 0x0001
|
||||
};
|
||||
|
||||
enum {
|
||||
RS_GXS_TUNNEL_STATUS_UNKNOWN = 0x00,
|
||||
RS_GXS_TUNNEL_STATUS_TUNNEL_DN = 0x01,
|
||||
RS_GXS_TUNNEL_STATUS_CAN_TALK = 0x02,
|
||||
RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED = 0x03
|
||||
};
|
||||
|
||||
class RsGxsTunnelClientService
|
||||
{
|
||||
public:
|
||||
// The client should derive this in order to handle notifications from the tunnel service.
|
||||
// This cannot be ignored because the client needs to know when the tunnel is active.
|
||||
|
||||
virtual void notifyTunnelStatus(const RsGxsTunnelId& tunnel_id,uint32_t tunnel_status) =0;
|
||||
|
||||
// Data obtained from the corresponding GXS id. The memory ownership is transferred to the client, which
|
||||
// is responsible to free it using free() once used.
|
||||
|
||||
virtual void receiveData(const RsGxsTunnelId& id,unsigned char *data,uint32_t data_size) =0;
|
||||
|
||||
// Used by the creator of the service to supply a pointer to the GXS tunnel service for it to be able to send data etc.
|
||||
|
||||
virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) =0;
|
||||
};
|
||||
|
||||
class GxsTunnelInfo
|
||||
{
|
||||
public:
|
||||
// Tunnel information
|
||||
|
||||
RsGxsTunnelId tunnel_id ;
|
||||
RsGxsId destination_gxs_id ; // GXS Id we're talking to
|
||||
RsGxsId source_gxs_id ; // GXS Id we're using to talk
|
||||
uint32_t tunnel_status ; // active, requested, DH pending, etc.
|
||||
uint32_t total_size_sent ; // total bytes sent through that tunnel since openned (including management).
|
||||
uint32_t total_size_received ; // total bytes received through that tunnel since openned (including management).
|
||||
|
||||
// Data packets
|
||||
|
||||
uint32_t pending_data_packets; // number of packets not acknowledged by other side, still on their way. Should be 0 unless something bad happens.
|
||||
uint32_t total_data_packets_sent ; // total number of data packets sent (does not include tunnel management)
|
||||
uint32_t total_data_packets_received ; // total number of data packets received (does not include tunnel management)
|
||||
};
|
||||
|
||||
// This is the interface file for the secured tunnel service
|
||||
//
|
||||
//===================================================//
|
||||
// Debugging info //
|
||||
//===================================================//
|
||||
|
||||
virtual bool getTunnelsInfo(std::vector<GxsTunnelInfo>& infos) =0;
|
||||
virtual bool getTunnelInfo(const RsGxsTunnelId& tunnel_id,GxsTunnelInfo& info) =0;
|
||||
|
||||
// retrieve the routing probabilities
|
||||
|
||||
//===================================================//
|
||||
// Communication to other services. //
|
||||
//===================================================//
|
||||
|
||||
// Register a new client service. The service ID needs to be unique, and it's the coder's resonsibility to use an ID that is not used elsewhere
|
||||
// for the same purpose.
|
||||
|
||||
virtual bool registerClientService(uint32_t service_id,RsGxsTunnelClientService *service) =0;
|
||||
|
||||
// Asks for a tunnel. The service will request it to turtle router, and exchange a AES key using DH.
|
||||
// When the tunnel is secured, the client---here supplied as argument---will be notified. He can
|
||||
// then send data into the tunnel. The same tunnel may be used by different clients.
|
||||
// The service id is passed on so that the client is notified when the tunnel is up.
|
||||
|
||||
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t service_id,uint32_t& error_code) =0 ;
|
||||
|
||||
// Data is sent through the established tunnel, possibly multiple times, until reception is acknowledged. If the tunnel does not exist, the item is rejected and
|
||||
// an error is issued. In any case, the memory ownership of the data is *not* transferred to the tunnel service, so the client should delete it afterwards, if needed.
|
||||
|
||||
virtual bool sendData(const RsGxsTunnelId& tunnel_id, uint32_t client_service_id, const uint8_t *data, uint32_t data_size) =0;
|
||||
|
||||
// Removes any established tunnel to this GXS id. This makes the tunnel refuse further data, but the tunnel will be however kept alive
|
||||
// until all pending data is flushed. All clients attached to the tunnel will be notified that the tunnel gets closed.
|
||||
|
||||
virtual bool closeExistingTunnel(const RsGxsTunnelId& to_id,uint32_t service_id) =0;
|
||||
|
||||
//===================================================//
|
||||
// Routage feedback from other services //
|
||||
//===================================================//
|
||||
|
||||
};
|
||||
|
||||
// To access the GRouter from anywhere
|
||||
//
|
||||
extern RsGxsTunnelService *rsGxsTunnel ;
|
@ -209,15 +209,17 @@ static const int SHA1_SIZE = 20 ;
|
||||
|
||||
// These constants are random, but should be different, in order to make the various IDs incompatible with each other.
|
||||
//
|
||||
static const uint32_t RS_GENERIC_ID_SSL_ID_TYPE = 0x0001 ;
|
||||
static const uint32_t RS_GENERIC_ID_PGP_ID_TYPE = 0x0002 ;
|
||||
static const uint32_t RS_GENERIC_ID_SHA1_ID_TYPE = 0x0003 ;
|
||||
static const uint32_t RS_GENERIC_ID_PGP_FINGERPRINT_TYPE = 0x0004 ;
|
||||
static const uint32_t RS_GENERIC_ID_GXS_GROUP_ID_TYPE = 0x0005 ;
|
||||
static const uint32_t RS_GENERIC_ID_GXS_ID_TYPE = 0x0006 ;
|
||||
static const uint32_t RS_GENERIC_ID_GXS_MSG_ID_TYPE = 0x0007 ;
|
||||
static const uint32_t RS_GENERIC_ID_GXS_CIRCLE_ID_TYPE = 0x0008 ;
|
||||
static const uint32_t RS_GENERIC_ID_GROUTER_ID_TYPE = 0x0009 ;
|
||||
static const uint32_t RS_GENERIC_ID_SSL_ID_TYPE = 0x0001 ;
|
||||
static const uint32_t RS_GENERIC_ID_PGP_ID_TYPE = 0x0002 ;
|
||||
static const uint32_t RS_GENERIC_ID_SHA1_ID_TYPE = 0x0003 ;
|
||||
static const uint32_t RS_GENERIC_ID_PGP_FINGERPRINT_TYPE = 0x0004 ;
|
||||
static const uint32_t RS_GENERIC_ID_GXS_GROUP_ID_TYPE = 0x0005 ;
|
||||
static const uint32_t RS_GENERIC_ID_GXS_ID_TYPE = 0x0006 ;
|
||||
static const uint32_t RS_GENERIC_ID_GXS_MSG_ID_TYPE = 0x0007 ;
|
||||
static const uint32_t RS_GENERIC_ID_GXS_CIRCLE_ID_TYPE = 0x0008 ;
|
||||
static const uint32_t RS_GENERIC_ID_GROUTER_ID_TYPE = 0x0009 ;
|
||||
static const uint32_t RS_GENERIC_ID_GXS_TUNNEL_ID_TYPE = 0x0010 ;
|
||||
static const uint32_t RS_GENERIC_ID_GXS_DISTANT_CHAT_ID_TYPE = 0x0011 ;
|
||||
|
||||
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_SSL_ID_TYPE> SSLIdType ;
|
||||
typedef t_RsGenericIdType< PGP_KEY_ID_SIZE , true, RS_GENERIC_ID_PGP_ID_TYPE> PGPIdType ;
|
||||
@ -227,4 +229,6 @@ typedef t_RsGenericIdType< PGP_KEY_FINGERPRINT_SIZE, true, RS_GENERIC_ID_PGP_F
|
||||
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_GROUP_ID_TYPE > GXSGroupId ;
|
||||
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_ID_TYPE > GXSId ;
|
||||
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_CIRCLE_ID_TYPE > GXSCircleId ;
|
||||
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_GXS_TUNNEL_ID_TYPE > GXSTunnelId ;
|
||||
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_GXS_DISTANT_CHAT_ID_TYPE > DistantChatPeerId ;
|
||||
|
||||
|
@ -99,9 +99,6 @@ typedef uint64_t ChatLobbyId ;
|
||||
typedef uint64_t ChatLobbyMsgId ;
|
||||
typedef std::string ChatLobbyNickName ;
|
||||
|
||||
typedef RsPeerId DistantChatPeerId ;
|
||||
//typedef GRouterKeyId DistantMsgPeerId ;
|
||||
|
||||
typedef uint64_t MessageId ;
|
||||
|
||||
|
||||
@ -253,12 +250,10 @@ public:
|
||||
#define RS_CHAT_PRIVATE 0x0002
|
||||
#define RS_CHAT_AVATAR_AVAILABLE 0x0004
|
||||
|
||||
#define RS_DISTANT_CHAT_STATUS_UNKNOWN 0x0000
|
||||
#define RS_DISTANT_CHAT_STATUS_TUNNEL_DN 0x0001
|
||||
#define RS_DISTANT_CHAT_STATUS_TUNNEL_OK 0x0002
|
||||
#define RS_DISTANT_CHAT_STATUS_CAN_TALK 0x0003
|
||||
#define RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED 0x0004
|
||||
#define RS_DISTANT_CHAT_STATUS_WAITING_DH 0x0005
|
||||
#define RS_DISTANT_CHAT_STATUS_UNKNOWN 0x0000
|
||||
#define RS_DISTANT_CHAT_STATUS_TUNNEL_DN 0x0001
|
||||
#define RS_DISTANT_CHAT_STATUS_CAN_TALK 0x0002
|
||||
#define RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED 0x0003
|
||||
|
||||
#define RS_DISTANT_CHAT_ERROR_NO_ERROR 0x0000
|
||||
#define RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED 0x0001
|
||||
@ -269,6 +264,14 @@ public:
|
||||
#define RS_DISTANT_CHAT_FLAG_SIGNED 0x0001
|
||||
#define RS_DISTANT_CHAT_FLAG_SIGNATURE_OK 0x0002
|
||||
|
||||
struct DistantChatPeerInfo
|
||||
{
|
||||
RsGxsId to_id ;
|
||||
RsGxsId own_id ;
|
||||
DistantChatPeerId peer_id ; // this is the tunnel id actually
|
||||
uint32_t status ; // see the values in rsmsgs.h
|
||||
};
|
||||
|
||||
// Identifier for an chat endpoint like
|
||||
// neighbour peer, distant peer, chatlobby, broadcast
|
||||
class ChatId
|
||||
@ -276,8 +279,8 @@ class ChatId
|
||||
public:
|
||||
ChatId();
|
||||
explicit ChatId(RsPeerId id);
|
||||
explicit ChatId(RsGxsId id);
|
||||
explicit ChatId(ChatLobbyId id);
|
||||
explicit ChatId(DistantChatPeerId id);
|
||||
explicit ChatId(std::string str);
|
||||
static ChatId makeBroadcastId();
|
||||
|
||||
@ -289,13 +292,14 @@ public:
|
||||
|
||||
bool isNotSet() const;
|
||||
bool isPeerId() const;
|
||||
bool isGxsId() const;
|
||||
bool isDistantChatId() const;
|
||||
bool isLobbyId() const;
|
||||
bool isBroadcast() const;
|
||||
|
||||
RsPeerId toPeerId() const;
|
||||
RsGxsId toGxsId() const;
|
||||
ChatLobbyId toLobbyId() const;
|
||||
DistantChatPeerId toDistantChatId() const;
|
||||
|
||||
// for the very specific case of transfering a status string
|
||||
// from the chatservice to the gui,
|
||||
@ -311,7 +315,7 @@ private:
|
||||
|
||||
Type type;
|
||||
RsPeerId peer_id;
|
||||
RsGxsId gxs_id;
|
||||
DistantChatPeerId distant_chat_id;
|
||||
ChatLobbyId lobby_id;
|
||||
};
|
||||
|
||||
@ -372,15 +376,6 @@ class ChatLobbyInfo
|
||||
time_t last_activity ; // last recorded activity. Useful for removing dead lobbies.
|
||||
};
|
||||
|
||||
struct DistantChatInviteInfo
|
||||
{
|
||||
DistantChatPeerId pid ; // pid to contact the invite and refer to it.
|
||||
std::string encrypted_radix64_string ; // encrypted radix string used to for the chat link
|
||||
RsPgpId destination_pgp_id ; // pgp is of the destination of the chat link
|
||||
time_t time_of_validity ; // time when te invite becomes unusable
|
||||
uint32_t invite_flags ; // used to keep track of wether signature was ok or not.
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const Rs::Msgs::MessageInfo &info);
|
||||
|
||||
class RsMsgs;
|
||||
@ -481,9 +476,9 @@ virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const RsGxsId&
|
||||
/* Distant chat */
|
||||
/****************************************/
|
||||
|
||||
virtual bool initiateDistantChatConnexion(const RsGxsId& to_pid,const RsGxsId& from_pid,uint32_t& error_code) = 0;
|
||||
virtual bool getDistantChatStatus(const RsGxsId& gxs_id,uint32_t& status, RsGxsId *from_gxs_id = NULL) = 0;
|
||||
virtual bool closeDistantChatConnexion(const RsGxsId& pid) = 0;
|
||||
virtual bool initiateDistantChatConnexion(const RsGxsId& to_pid,const RsGxsId& from_pid,DistantChatPeerId& pid,uint32_t& error_code) = 0;
|
||||
virtual bool getDistantChatStatus(const DistantChatPeerId& pid,DistantChatPeerInfo& info)=0;
|
||||
virtual bool closeDistantChatConnexion(const DistantChatPeerId& pid)=0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -42,6 +42,7 @@ class p3Service ;
|
||||
class RsServiceControl ;
|
||||
class RsReputations ;
|
||||
class RsTurtle ;
|
||||
class RsGxsTunnelService ;
|
||||
class RsDht ;
|
||||
class RsDisc ;
|
||||
class RsMsgs ;
|
||||
@ -117,6 +118,7 @@ public:
|
||||
RsUtil::inited_ptr<PgpAuxUtils> mPgpAuxUtils;
|
||||
RsUtil::inited_ptr<RsGxsForums> mGxsForums;
|
||||
RsUtil::inited_ptr<RsGxsChannels> mGxsChannels;
|
||||
RsUtil::inited_ptr<RsGxsTunnelService> mGxsTunnels;
|
||||
RsUtil::inited_ptr<RsReputations> mReputations;
|
||||
};
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "util/rsthreads.h"
|
||||
|
||||
#include "chat/p3chatservice.h"
|
||||
#include "gxstunnel/p3gxstunnel.h"
|
||||
|
||||
#include "services/p3msgservice.h"
|
||||
#include "services/p3statusservice.h"
|
||||
@ -160,6 +161,7 @@ class RsServer: public RsControl, public RsTickingThread
|
||||
p3MsgService *msgSrv;
|
||||
p3ChatService *chatSrv;
|
||||
p3StatusService *mStatusSrv;
|
||||
p3GxsTunnelService *mGxsTunnels;
|
||||
|
||||
// This list contains all threaded services. It will be used to shut them down properly.
|
||||
|
||||
|
@ -65,11 +65,11 @@ ChatId::ChatId(RsPeerId id):
|
||||
peer_id = id;
|
||||
}
|
||||
|
||||
ChatId::ChatId(RsGxsId id):
|
||||
ChatId::ChatId(DistantChatPeerId id):
|
||||
lobby_id(0)
|
||||
{
|
||||
type = TYPE_PRIVATE_DISTANT;
|
||||
gxs_id = id;
|
||||
distant_chat_id = id;
|
||||
}
|
||||
|
||||
ChatId::ChatId(ChatLobbyId id):
|
||||
@ -93,7 +93,7 @@ ChatId::ChatId(std::string str):
|
||||
else if(str[0] == 'D')
|
||||
{
|
||||
type = TYPE_PRIVATE_DISTANT;
|
||||
gxs_id == GXSId(str.substr(1));
|
||||
distant_chat_id == DistantChatPeerId(str.substr(1));
|
||||
}
|
||||
else if(str[0] == 'L')
|
||||
{
|
||||
@ -143,7 +143,7 @@ std::string ChatId::toStdString() const
|
||||
else if(type == TYPE_PRIVATE_DISTANT)
|
||||
{
|
||||
str += "D";
|
||||
str += gxs_id.toStdString();
|
||||
str += distant_chat_id.toStdString();
|
||||
}
|
||||
else if(type == TYPE_LOBBY)
|
||||
{
|
||||
@ -186,7 +186,7 @@ bool ChatId::operator <(const ChatId& other) const
|
||||
case TYPE_PRIVATE:
|
||||
return peer_id < other.peer_id;
|
||||
case TYPE_PRIVATE_DISTANT:
|
||||
return gxs_id < other.gxs_id;
|
||||
return distant_chat_id < other.distant_chat_id;
|
||||
case TYPE_LOBBY:
|
||||
return lobby_id < other.lobby_id;
|
||||
case TYPE_BROADCAST:
|
||||
@ -210,7 +210,7 @@ bool ChatId::isSameEndpoint(const ChatId &other) const
|
||||
case TYPE_PRIVATE:
|
||||
return peer_id == other.peer_id;
|
||||
case TYPE_PRIVATE_DISTANT:
|
||||
return gxs_id == other.gxs_id;
|
||||
return distant_chat_id == other.distant_chat_id;
|
||||
case TYPE_LOBBY:
|
||||
return lobby_id == other.lobby_id;
|
||||
case TYPE_BROADCAST:
|
||||
@ -229,7 +229,7 @@ bool ChatId::isPeerId() const
|
||||
{
|
||||
return type == TYPE_PRIVATE;
|
||||
}
|
||||
bool ChatId::isGxsId() const
|
||||
bool ChatId::isDistantChatId() const
|
||||
{
|
||||
return type == TYPE_PRIVATE_DISTANT;
|
||||
}
|
||||
@ -251,14 +251,15 @@ RsPeerId ChatId::toPeerId() const
|
||||
return RsPeerId();
|
||||
}
|
||||
}
|
||||
RsGxsId ChatId::toGxsId() const
|
||||
|
||||
DistantChatPeerId ChatId::toDistantChatId() const
|
||||
{
|
||||
if(type == TYPE_PRIVATE_DISTANT)
|
||||
return gxs_id;
|
||||
return distant_chat_id;
|
||||
else
|
||||
{
|
||||
std::cerr << "ChatId Warning: conversation to RsGxsId requested, but type is different. Current value=\"" << toStdString() << "\"" << std::endl;
|
||||
return RsGxsId();
|
||||
std::cerr << "ChatId Warning: conversation to DistantChatPeerId requested, but type is different. Current value=\"" << toStdString() << "\"" << std::endl;
|
||||
return DistantChatPeerId();
|
||||
}
|
||||
}
|
||||
ChatLobbyId ChatId::toLobbyId() const
|
||||
@ -523,15 +524,15 @@ void p3Msgs::getPendingChatLobbyInvites(std::list<ChatLobbyInvite>& invites)
|
||||
{
|
||||
mChatSrv->getPendingChatLobbyInvites(invites) ;
|
||||
}
|
||||
bool p3Msgs::initiateDistantChatConnexion(const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id,uint32_t& error_code)
|
||||
bool p3Msgs::initiateDistantChatConnexion(const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id,DistantChatPeerId& pid,uint32_t& error_code)
|
||||
{
|
||||
return mChatSrv->initiateDistantChatConnexion(to_gxs_id,from_gxs_id,error_code) ;
|
||||
return mChatSrv->initiateDistantChatConnexion(to_gxs_id,from_gxs_id,pid,error_code) ;
|
||||
}
|
||||
bool p3Msgs::getDistantChatStatus(const RsGxsId &gxs_id,uint32_t &status,RsGxsId *from_gxs_id)
|
||||
bool p3Msgs::getDistantChatStatus(const DistantChatPeerId& pid,DistantChatPeerInfo& info)
|
||||
{
|
||||
return mChatSrv->getDistantChatStatus(gxs_id,status,from_gxs_id) ;
|
||||
return mChatSrv->getDistantChatStatus(pid,info) ;
|
||||
}
|
||||
bool p3Msgs::closeDistantChatConnexion(const RsGxsId& pid)
|
||||
bool p3Msgs::closeDistantChatConnexion(const DistantChatPeerId &pid)
|
||||
{
|
||||
return mChatSrv->closeDistantChatConnexion(pid) ;
|
||||
}
|
||||
|
@ -155,9 +155,9 @@ class p3Msgs: public RsMsgs
|
||||
virtual bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id);
|
||||
virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const RsGxsId& lobby_identity,const std::string& lobby_topic,const std::set<RsPeerId>& invited_friends,ChatLobbyFlags privacy_type) ;
|
||||
|
||||
virtual bool initiateDistantChatConnexion(const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id,uint32_t& error_code) ;
|
||||
virtual bool getDistantChatStatus(const RsGxsId& gxs_id,uint32_t& status, RsGxsId *from_gxs_id=NULL) ;
|
||||
virtual bool closeDistantChatConnexion(const RsGxsId &pid) ;
|
||||
virtual bool initiateDistantChatConnexion(const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, DistantChatPeerId &pid, uint32_t& error_code) ;
|
||||
virtual bool getDistantChatStatus(const DistantChatPeerId& gxs_id,DistantChatPeerInfo& info);
|
||||
virtual bool closeDistantChatConnexion(const DistantChatPeerId &pid) ;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -56,6 +56,8 @@
|
||||
#include <openssl/rand.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <gxstunnel/p3gxstunnel.h>
|
||||
|
||||
#define ENABLE_GROUTER
|
||||
|
||||
#if (defined(__unix__) || defined(unix)) && !defined(USG)
|
||||
@ -264,7 +266,7 @@ bool doPortRestrictions = false;
|
||||
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
int RsInit::InitRetroShare(int argc, char **argv, bool strictCheck)
|
||||
int RsInit::InitRetroShare(int argc, char **argv, bool /* strictCheck */)
|
||||
{
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#else
|
||||
@ -1486,13 +1488,17 @@ int RsServer::StartupRetroShare()
|
||||
pqih -> addService(tr,true);
|
||||
pqih -> addService(ftserver,true);
|
||||
|
||||
mGxsTunnels = new p3GxsTunnelService(mGxsIdService) ;
|
||||
mGxsTunnels->connectToTurtleRouter(tr) ;
|
||||
rsGxsTunnel = mGxsTunnels;
|
||||
|
||||
rsDisc = mDisc;
|
||||
rsMsgs = new p3Msgs(msgSrv, chatSrv);
|
||||
|
||||
// connect components to turtle router.
|
||||
|
||||
ftserver->connectToTurtleRouter(tr) ;
|
||||
chatSrv->connectToTurtleRouter(tr) ;
|
||||
chatSrv->connectToGxsTunnelService(mGxsTunnels) ;
|
||||
gr->connectToTurtleRouter(tr) ;
|
||||
#ifdef ENABLE_GROUTER
|
||||
msgSrv->connectToGlobalRouter(gr) ;
|
||||
@ -1504,6 +1510,7 @@ int RsServer::StartupRetroShare()
|
||||
pqih -> addService(msgSrv,true);
|
||||
pqih -> addService(chatSrv,true);
|
||||
pqih -> addService(mStatusSrv,true);
|
||||
pqih -> addService(mGxsTunnels,true);
|
||||
pqih -> addService(mReputations,true);
|
||||
|
||||
// set interfaces for plugins
|
||||
@ -1525,6 +1532,7 @@ int RsServer::StartupRetroShare()
|
||||
interfaces.mPgpAuxUtils = pgpAuxUtils;
|
||||
interfaces.mGxsForums = mGxsForums;
|
||||
interfaces.mGxsChannels = mGxsChannels;
|
||||
interfaces.mGxsTunnels = mGxsTunnels;
|
||||
interfaces.mReputations = mReputations;
|
||||
|
||||
mPluginsManager->setInterfaces(interfaces);
|
||||
|
@ -38,32 +38,33 @@
|
||||
*/
|
||||
|
||||
/* These are Cache Only */
|
||||
const uint16_t RS_SERVICE_TYPE_FILE_INDEX = 0x0001;
|
||||
const uint16_t RS_SERVICE_TYPE_FILE_INDEX = 0x0001;
|
||||
|
||||
/* These are Services only */
|
||||
const uint16_t RS_SERVICE_TYPE_DISC = 0x0011;
|
||||
const uint16_t RS_SERVICE_TYPE_CHAT = 0x0012;
|
||||
const uint16_t RS_SERVICE_TYPE_MSG = 0x0013;
|
||||
const uint16_t RS_SERVICE_TYPE_TURTLE = 0x0014;
|
||||
const uint16_t RS_SERVICE_TYPE_TUNNEL = 0x0015;
|
||||
const uint16_t RS_SERVICE_TYPE_HEARTBEAT = 0x0016;
|
||||
const uint16_t RS_SERVICE_TYPE_FILE_TRANSFER = 0x0017;
|
||||
const uint16_t RS_SERVICE_TYPE_GROUTER = 0x0018;
|
||||
const uint16_t RS_SERVICE_TYPE_DISC = 0x0011;
|
||||
const uint16_t RS_SERVICE_TYPE_CHAT = 0x0012;
|
||||
const uint16_t RS_SERVICE_TYPE_MSG = 0x0013;
|
||||
const uint16_t RS_SERVICE_TYPE_TURTLE = 0x0014;
|
||||
const uint16_t RS_SERVICE_TYPE_TUNNEL = 0x0015;
|
||||
const uint16_t RS_SERVICE_TYPE_HEARTBEAT = 0x0016;
|
||||
const uint16_t RS_SERVICE_TYPE_FILE_TRANSFER = 0x0017;
|
||||
const uint16_t RS_SERVICE_TYPE_GROUTER = 0x0018;
|
||||
|
||||
const uint16_t RS_SERVICE_TYPE_SERVICEINFO = 0x0020;
|
||||
const uint16_t RS_SERVICE_TYPE_SERVICEINFO = 0x0020;
|
||||
/* Bandwidth Control */
|
||||
const uint16_t RS_SERVICE_TYPE_BWCTRL = 0x0021;
|
||||
// New Mail Service (replace old Msg Service)
|
||||
const uint16_t RS_SERVICE_TYPE_MAIL = 0x0022;
|
||||
const uint16_t RS_SERVICE_TYPE_DIRECT_MAIL = 0x0023;
|
||||
const uint16_t RS_SERVICE_TYPE_DISTANT_MAIL = 0x0024;
|
||||
const uint16_t RS_SERVICE_TYPE_GWEMAIL_MAIL = 0x0025;
|
||||
const uint16_t RS_SERVICE_TYPE_BWCTRL = 0x0021;
|
||||
// New Mail Service (replace old Msg Service)
|
||||
const uint16_t RS_SERVICE_TYPE_MAIL = 0x0022;
|
||||
const uint16_t RS_SERVICE_TYPE_DIRECT_MAIL = 0x0023;
|
||||
const uint16_t RS_SERVICE_TYPE_DISTANT_MAIL = 0x0024;
|
||||
const uint16_t RS_SERVICE_TYPE_GWEMAIL_MAIL = 0x0025;
|
||||
const uint16_t RS_SERVICE_TYPE_SERVICE_CONTROL= 0x0026;
|
||||
const uint16_t RS_SERVICE_TYPE_DISTANT_CHAT = 0x0027;
|
||||
const uint16_t RS_SERVICE_TYPE_DISTANT_CHAT = 0x0027;
|
||||
const uint16_t RS_SERVICE_TYPE_GXS_TUNNEL = 0x0028;
|
||||
|
||||
// Non essential services.
|
||||
const uint16_t RS_SERVICE_TYPE_BANLIST = 0x0101;
|
||||
const uint16_t RS_SERVICE_TYPE_STATUS = 0x0102;
|
||||
const uint16_t RS_SERVICE_TYPE_BANLIST = 0x0101;
|
||||
const uint16_t RS_SERVICE_TYPE_STATUS = 0x0102;
|
||||
|
||||
/* New Cache Services */
|
||||
/* Rs Network Exchange Service */
|
||||
|
@ -122,7 +122,7 @@ uint32_t p3GxsChannels::channelsAuthenPolicy()
|
||||
|
||||
|
||||
/** Overloaded to cache new groups **/
|
||||
RsGenExchange::ServiceCreate_Return p3GxsChannels::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet)
|
||||
RsGenExchange::ServiceCreate_Return p3GxsChannels::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& /* keySet */)
|
||||
{
|
||||
updateSubscribedGroup(grpItem->meta);
|
||||
return SERVICE_CREATE_SUCCESS;
|
||||
|
@ -40,8 +40,8 @@ class upnphandler: public pqiNetAssistFirewall
|
||||
virtual bool getExternalAddress(struct sockaddr_storage &addr);
|
||||
|
||||
/* TO IMPLEMENT: New Port Forward interface to support as many ports as necessary */
|
||||
virtual bool requestPortForward(const PortForwardParams ¶ms) { return false; }
|
||||
virtual bool statusPortForward(const uint32_t fwdId, PortForwardParams ¶ms) { return false; }
|
||||
virtual bool requestPortForward(const PortForwardParams & /* params */) { return false; }
|
||||
virtual bool statusPortForward(const uint32_t /* fwdId */, PortForwardParams & /*params*/) { return false; }
|
||||
|
||||
/* Public functions - for background thread operation,
|
||||
* but effectively private from rest of RS, as in derived class
|
||||
|
@ -40,6 +40,10 @@ std::string RsUtil::BinToHex(const std::string &bin)
|
||||
return BinToHex(bin.c_str(), bin.length());
|
||||
}
|
||||
|
||||
std::string RsUtil::BinToHex(const unsigned char *arr, const uint32_t len)
|
||||
{
|
||||
return BinToHex((char*)arr,len) ;
|
||||
}
|
||||
std::string RsUtil::BinToHex(const char *arr, const uint32_t len)
|
||||
{
|
||||
std::string out;
|
||||
|
@ -35,6 +35,7 @@ namespace RsUtil {
|
||||
|
||||
std::string BinToHex(const std::string &bin);
|
||||
std::string BinToHex(const char *arr, const uint32_t len);
|
||||
std::string BinToHex(const unsigned char *arr, const uint32_t len);
|
||||
std::string HashId(const std::string &id, bool reverse = false);
|
||||
|
||||
//std::string AccurateTimeString();
|
||||
|
@ -364,7 +364,7 @@ Changes for 0.5.5a
|
||||
|
||||
* Bug fixes
|
||||
- Fixed proper display of crypto params for UDP connections
|
||||
- Added missing location from cert when addign new friend
|
||||
- Added missing location from cert when adding new friend
|
||||
- Added missing IndicateConfigChanged to p3PeerMgrIMPL::setDynDNS
|
||||
- Fixed crash when closing the main window without the setting "Minimize to Tray Icon"
|
||||
- Renamed the setting "Do not Minimize to Tray Icon" to "Minimize to Tray
|
||||
@ -1189,7 +1189,7 @@ Changes for v0.5.3b
|
||||
- Added BSD specific changes - data directory and #including <sys/params.h>
|
||||
- improved plugin management to allow services to be used, and config pages to be added
|
||||
- Improvement to plugin system:
|
||||
- made config page system more automatic, to allow addign config pages from plugins
|
||||
- made config page system more automatic, to allow adding config pages from plugins
|
||||
- added (disabled) checkbox and function to allow all plugins for development
|
||||
- added config page methods to RsPlugin class
|
||||
- Mark local existing files in SearchDialog with red text color.
|
||||
@ -1202,7 +1202,7 @@ Changes for v0.5.3b
|
||||
- Added Cache system for GPG Certificates.
|
||||
- This should reduce gpg calls by 90+%.
|
||||
- Added translation for "[ ... Missing Message ... ]".
|
||||
- removed cache adding strategy to DL queue that was O(n^2). Now addign cache at the end of the queue
|
||||
- removed cache adding strategy to DL queue that was O(n^2). Now adding cache at the end of the queue
|
||||
- The channel message (in channels) is set to read when the user clicks on the show more button.
|
||||
- The forum/channel news feed is removed when the user reads the message in forums/channels.
|
||||
- The standard font is now used for new chat lobbies.
|
||||
|
@ -1004,8 +1004,9 @@ void IdDialog::chatIdentity()
|
||||
|
||||
RsGxsId from_gxs_id(action->data().toString().toStdString());
|
||||
uint32_t error_code ;
|
||||
DistantChatPeerId did ;
|
||||
|
||||
if(!rsMsgs->initiateDistantChatConnexion(RsGxsId(keyId), from_gxs_id, error_code))
|
||||
if(!rsMsgs->initiateDistantChatConnexion(RsGxsId(keyId), from_gxs_id, did, error_code))
|
||||
QMessageBox::information(NULL, tr("Distant chat cannot work"), QString("%1 %2: %3").arg(tr("Distant chat refused with this person.")).arg(tr("Error code")).arg(error_code)) ;
|
||||
}
|
||||
|
||||
|
@ -401,7 +401,7 @@ void MainWindow::initStackedPage()
|
||||
else
|
||||
icon = QIcon(":images/extension_48.png") ;
|
||||
|
||||
std::cerr << " Addign widget page for plugin " << rsPlugins->plugin(i)->getPluginName() << std::endl;
|
||||
std::cerr << " Adding widget page for plugin " << rsPlugins->plugin(i)->getPluginName() << std::endl;
|
||||
pluginPage->setIconPixmap(icon);
|
||||
pluginPage->setPageName(QString::fromUtf8(rsPlugins->plugin(i)->getPluginName().c_str()));
|
||||
addPage(pluginPage, grp, ¬ify);
|
||||
|
@ -1341,7 +1341,7 @@ void FlatStyle_RDM::updateRefs()
|
||||
if(details->type == DIR_TYPE_FILE) // only push files, not directories nor persons.
|
||||
_ref_entries.push_back(std::pair<void*,QString>(ref,computeDirectoryPath(*details)));
|
||||
#ifdef RDM_DEBUG
|
||||
std::cerr << "FlatStyle_RDM::postMods(): addign ref " << ref << std::endl;
|
||||
std::cerr << "FlatStyle_RDM::postMods(): adding ref " << ref << std::endl;
|
||||
#endif
|
||||
for(std::list<DirStub>::const_iterator it = details->children.begin(); it != details->children.end(); ++it)
|
||||
_ref_stack.push_back(it->ref) ;
|
||||
|
@ -96,7 +96,7 @@ void ChatDialog::init(ChatId id, const QString &title)
|
||||
|
||||
if (cd == NULL) {
|
||||
|
||||
if(id.isGxsId())
|
||||
if(id.isDistantChatId())
|
||||
chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // force open for distant chat
|
||||
|
||||
if (chatflags & RS_CHAT_OPEN) {
|
||||
@ -104,12 +104,16 @@ void ChatDialog::init(ChatId id, const QString &title)
|
||||
ChatLobbyDialog* cld = new ChatLobbyDialog(id.toLobbyId());
|
||||
cld->init();
|
||||
cd = cld;
|
||||
} else if(id.isGxsId()) {
|
||||
PopupDistantChatDialog* pdcd = new PopupDistantChatDialog();
|
||||
QString peer_name = pdcd->getPeerName(id) ;
|
||||
pdcd->init(id.toGxsId(), tr("Talking to")+" "+peer_name) ;
|
||||
}
|
||||
else if(id.isDistantChatId())
|
||||
{
|
||||
PopupDistantChatDialog* pdcd = new PopupDistantChatDialog(id.toDistantChatId());
|
||||
|
||||
pdcd->init(id.toDistantChatId());
|
||||
cd = pdcd;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
RsPeerDetails sslDetails;
|
||||
if (rsPeers->getPeerDetails(id.toPeerId(), sslDetails)) {
|
||||
PopupChatDialog* pcd = new PopupChatDialog();
|
||||
@ -168,7 +172,7 @@ void ChatDialog::init(ChatId id, const QString &title)
|
||||
if(msg.chat_id.isBroadcast())
|
||||
return; // broadcast is not handled by a chat dialog
|
||||
|
||||
if(msg.incoming && (msg.chat_id.isPeerId() || msg.chat_id.isGxsId()))
|
||||
if(msg.incoming && (msg.chat_id.isPeerId() || msg.chat_id.isDistantChatId()))
|
||||
// play sound when recv a message
|
||||
SoundManager::play(SOUND_NEW_CHAT_MESSAGE);
|
||||
|
||||
@ -334,8 +338,8 @@ void ChatDialog::setPeerStatus(uint32_t status)
|
||||
RsPeerId vpid;
|
||||
if(mChatId.isPeerId())
|
||||
vpid = mChatId.toPeerId();
|
||||
if(mChatId.isGxsId())
|
||||
vpid = RsPeerId(mChatId.toGxsId());
|
||||
if(mChatId.isDistantChatId())
|
||||
vpid = RsPeerId(mChatId.toDistantChatId());
|
||||
cw->updateStatus(QString::fromStdString(vpid.toStdString()), status);
|
||||
}
|
||||
}
|
||||
|
@ -562,8 +562,9 @@ void ChatLobbyDialog::distantChatParticipant()
|
||||
rsMsgs->getIdentityForChatLobby(lobbyId, own_id);
|
||||
|
||||
uint32_t error_code ;
|
||||
DistantChatPeerId tunnel_id;
|
||||
|
||||
if(! rsMsgs->initiateDistantChatConnexion(gxs_id,own_id,error_code))
|
||||
if(! rsMsgs->initiateDistantChatConnexion(gxs_id,own_id,tunnel_id,error_code))
|
||||
{
|
||||
QString error_str ;
|
||||
switch(error_code)
|
||||
|
@ -109,7 +109,7 @@ void ChatUserNotify::chatMessageReceived(ChatMessage msg)
|
||||
if(!msg.chat_id.isBroadcast()
|
||||
&&( ChatDialog::getExistingChat(msg.chat_id)
|
||||
|| (Settings->getChatFlags() & RS_CHAT_OPEN)
|
||||
|| msg.chat_id.isGxsId()))
|
||||
|| msg.chat_id.isDistantChatId()))
|
||||
{
|
||||
ChatDialog::chatMessageReceived(msg);
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title)
|
||||
RsPeerId ownId = rsPeers->getOwnId();
|
||||
setName(QString::fromUtf8(rsPeers->getPeerName(ownId).c_str()));
|
||||
|
||||
if(chatId.isPeerId() || chatId.isGxsId())
|
||||
if(chatId.isPeerId() || chatId.isDistantChatId())
|
||||
chatStyle.setStyleFromSettings(ChatStyle::TYPE_PRIVATE);
|
||||
if(chatId.isBroadcast() || chatId.isLobbyId())
|
||||
chatStyle.setStyleFromSettings(ChatStyle::TYPE_PUBLIC);
|
||||
@ -334,7 +334,8 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title)
|
||||
continue;
|
||||
|
||||
QString name;
|
||||
if (chatId.isLobbyId() || chatId.isGxsId()) {
|
||||
if (chatId.isLobbyId() || chatId.isDistantChatId())
|
||||
{
|
||||
RsIdentityDetails details;
|
||||
if (rsIdentity->getIdDetails(RsGxsId(historyIt->peerName), details))
|
||||
name = QString::fromUtf8(details.mNickname.c_str());
|
||||
@ -366,7 +367,7 @@ ChatWidget::ChatType ChatWidget::chatType()
|
||||
// but maybe it is good to have separate types in libretroshare and gui
|
||||
if(chatId.isPeerId())
|
||||
return CHATTYPE_PRIVATE;
|
||||
if(chatId.isGxsId())
|
||||
if(chatId.isDistantChatId())
|
||||
return CHATTYPE_DISTANT;
|
||||
if(chatId.isLobbyId())
|
||||
return CHATTYPE_LOBBY;
|
||||
@ -1522,77 +1523,83 @@ void ChatWidget::updateStatus(const QString &peer_id, int status)
|
||||
|
||||
// make virtual peer id from gxs id in case of distant chat
|
||||
RsPeerId vpid;
|
||||
if(chatId.isGxsId())
|
||||
vpid = RsPeerId(chatId.toGxsId());
|
||||
if(chatId.isDistantChatId())
|
||||
vpid = RsPeerId(chatId.toDistantChatId());
|
||||
else
|
||||
vpid = chatId.toPeerId();
|
||||
|
||||
/* set font size for status */
|
||||
if (peer_id.toStdString() == vpid.toStdString()) {
|
||||
// the peers status has changed
|
||||
if (peer_id.toStdString() == vpid.toStdString())
|
||||
{
|
||||
// the peers status has changed
|
||||
|
||||
QString peerName ;
|
||||
if(chatId.isGxsId())
|
||||
{
|
||||
RsIdentityDetails details ;
|
||||
if(rsIdentity->getIdDetails(chatId.toGxsId(),details))
|
||||
peerName = QString::fromUtf8( details.mNickname.c_str() ) ;
|
||||
else
|
||||
peerName = QString::fromStdString(chatId.toGxsId().toStdString()) ;
|
||||
}
|
||||
else
|
||||
peerName = QString::fromUtf8(rsPeers->getPeerName(chatId.toPeerId()).c_str());
|
||||
QString peerName ;
|
||||
if(chatId.isDistantChatId())
|
||||
{
|
||||
DistantChatPeerInfo dcpinfo ;
|
||||
RsIdentityDetails details ;
|
||||
|
||||
// is scrollbar at the end?
|
||||
QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar();
|
||||
bool atEnd = (scrollbar->value() == scrollbar->maximum());
|
||||
if(rsMsgs->getDistantChatStatus(chatId.toDistantChatId(),dcpinfo))
|
||||
if(rsIdentity->getIdDetails(dcpinfo.to_id,details))
|
||||
peerName = QString::fromUtf8( details.mNickname.c_str() ) ;
|
||||
else
|
||||
peerName = QString::fromStdString(dcpinfo.to_id.toStdString()) ;
|
||||
else
|
||||
peerName = QString::fromStdString(chatId.toDistantChatId().toStdString()) ;
|
||||
}
|
||||
else
|
||||
peerName = QString::fromUtf8(rsPeers->getPeerName(chatId.toPeerId()).c_str());
|
||||
|
||||
switch (status) {
|
||||
case RS_STATUS_OFFLINE:
|
||||
ui->infoFrame->setVisible(true);
|
||||
ui->infoLabel->setText(peerName + " " + tr("appears to be Offline.") +"\n" + tr("Messages you send will be delivered after Friend is again Online"));
|
||||
break;
|
||||
// is scrollbar at the end?
|
||||
QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar();
|
||||
bool atEnd = (scrollbar->value() == scrollbar->maximum());
|
||||
|
||||
case RS_STATUS_INACTIVE:
|
||||
ui->infoFrame->setVisible(true);
|
||||
ui->infoLabel->setText(peerName + " " + tr("is Idle and may not reply"));
|
||||
break;
|
||||
switch (status) {
|
||||
case RS_STATUS_OFFLINE:
|
||||
ui->infoFrame->setVisible(true);
|
||||
ui->infoLabel->setText(peerName + " " + tr("appears to be Offline.") +"\n" + tr("Messages you send will be delivered after Friend is again Online"));
|
||||
break;
|
||||
|
||||
case RS_STATUS_ONLINE:
|
||||
ui->infoFrame->setVisible(false);
|
||||
break;
|
||||
case RS_STATUS_INACTIVE:
|
||||
ui->infoFrame->setVisible(true);
|
||||
ui->infoLabel->setText(peerName + " " + tr("is Idle and may not reply"));
|
||||
break;
|
||||
|
||||
case RS_STATUS_AWAY:
|
||||
ui->infoLabel->setText(peerName + " " + tr("is Away and may not reply"));
|
||||
ui->infoFrame->setVisible(true);
|
||||
break;
|
||||
case RS_STATUS_ONLINE:
|
||||
ui->infoFrame->setVisible(false);
|
||||
break;
|
||||
|
||||
case RS_STATUS_BUSY:
|
||||
ui->infoLabel->setText(peerName + " " + tr("is Busy and may not reply"));
|
||||
ui->infoFrame->setVisible(true);
|
||||
break;
|
||||
}
|
||||
case RS_STATUS_AWAY:
|
||||
ui->infoLabel->setText(peerName + " " + tr("is Away and may not reply"));
|
||||
ui->infoFrame->setVisible(true);
|
||||
break;
|
||||
|
||||
ui->titleLabel->setText(peerName);
|
||||
ui->statusLabel->setText(QString("(%1)").arg(StatusDefs::name(status)));
|
||||
case RS_STATUS_BUSY:
|
||||
ui->infoLabel->setText(peerName + " " + tr("is Busy and may not reply"));
|
||||
ui->infoFrame->setVisible(true);
|
||||
break;
|
||||
}
|
||||
|
||||
peerStatus = status;
|
||||
ui->titleLabel->setText(peerName);
|
||||
ui->statusLabel->setText(QString("(%1)").arg(StatusDefs::name(status)));
|
||||
|
||||
if (atEnd) {
|
||||
// scroll to the end
|
||||
scrollbar->setValue(scrollbar->maximum());
|
||||
}
|
||||
peerStatus = status;
|
||||
|
||||
emit infoChanged(this);
|
||||
emit statusChanged(status);
|
||||
if (atEnd) {
|
||||
// scroll to the end
|
||||
scrollbar->setValue(scrollbar->maximum());
|
||||
}
|
||||
|
||||
// Notify all ChatWidgetHolder
|
||||
foreach (ChatWidgetHolder *chatWidgetHolder, mChatWidgetHolder) {
|
||||
chatWidgetHolder->updateStatus(status);
|
||||
}
|
||||
emit infoChanged(this);
|
||||
emit statusChanged(status);
|
||||
|
||||
return;
|
||||
}
|
||||
// Notify all ChatWidgetHolder
|
||||
foreach (ChatWidgetHolder *chatWidgetHolder, mChatWidgetHolder) {
|
||||
chatWidgetHolder->updateStatus(status);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore status change
|
||||
}
|
||||
|
@ -43,9 +43,11 @@ PopupDistantChatDialog::~PopupDistantChatDialog()
|
||||
delete _update_timer ;
|
||||
}
|
||||
|
||||
PopupDistantChatDialog::PopupDistantChatDialog(QWidget *parent, Qt::WindowFlags flags)
|
||||
PopupDistantChatDialog::PopupDistantChatDialog(const DistantChatPeerId& tunnel_id,QWidget *parent, Qt::WindowFlags flags)
|
||||
: PopupChatDialog(parent,flags)
|
||||
{
|
||||
_tunnel_id = tunnel_id ;
|
||||
|
||||
_status_label = new QToolButton ;
|
||||
_update_timer = new QTimer ;
|
||||
|
||||
@ -61,97 +63,98 @@ PopupDistantChatDialog::PopupDistantChatDialog(QWidget *parent, Qt::WindowFlags
|
||||
updateDisplay() ;
|
||||
}
|
||||
|
||||
void PopupDistantChatDialog::init(const RsGxsId &gxs_id,const QString & title)
|
||||
void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id)
|
||||
{
|
||||
_pid = gxs_id ;
|
||||
PopupChatDialog::init(ChatId(gxs_id), title) ;
|
||||
_tunnel_id = peer_id;
|
||||
DistantChatPeerInfo tinfo;
|
||||
|
||||
if(!rsMsgs->getDistantChatStatus(_tunnel_id,tinfo))
|
||||
return ;
|
||||
|
||||
RsIdentityDetails iddetails ;
|
||||
|
||||
if(rsIdentity->getIdDetails(tinfo.to_id,iddetails))
|
||||
PopupChatDialog::init(ChatId(peer_id), QString::fromUtf8(iddetails.mNickname.c_str())) ;
|
||||
else
|
||||
PopupChatDialog::init(ChatId(peer_id), QString::fromStdString(tinfo.to_id.toStdString())) ;
|
||||
|
||||
RsGxsId own_gxs_id ;
|
||||
uint32_t status ;
|
||||
|
||||
// do not use setOwnId, because we don't want the user to change the GXS avatar from the chat window
|
||||
// Do not use setOwnId, because we don't want the user to change the GXS avatar from the chat window
|
||||
// it will not be transmitted.
|
||||
|
||||
if(rsMsgs->getDistantChatStatus(gxs_id,status,&own_gxs_id))
|
||||
ui.ownAvatarWidget->setId(ChatId(own_gxs_id));
|
||||
ui.ownAvatarWidget->setOwnId() ; // sets the flag
|
||||
ui.ownAvatarWidget->setId(ChatId(peer_id)) ; // sets the actual Id
|
||||
}
|
||||
|
||||
void PopupDistantChatDialog::updateDisplay()
|
||||
{
|
||||
if(RsAutoUpdatePage::eventsLocked()) // we need to do that by end, because it's not possible to derive from both PopupChatDialog and RsAutoUpdatePage
|
||||
return ; // which both derive from QObject. Signals-slot connexions won't work anymore.
|
||||
if(RsAutoUpdatePage::eventsLocked()) // we need to do that by end, because it's not possible to derive from both PopupChatDialog and RsAutoUpdatePage
|
||||
return ; // which both derive from QObject. Signals-slot connexions won't work anymore.
|
||||
|
||||
if(!isVisible())
|
||||
return ;
|
||||
if(!isVisible())
|
||||
return ;
|
||||
|
||||
//std::cerr << "Checking tunnel..." ;
|
||||
// make sure about the tunnel status
|
||||
//
|
||||
|
||||
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
|
||||
rsMsgs->getDistantChatStatus(_pid,status) ;
|
||||
//std::cerr << "Checking tunnel..." ;
|
||||
// make sure about the tunnel status
|
||||
//
|
||||
|
||||
ui.avatarWidget->setId(ChatId(_pid));
|
||||
DistantChatPeerInfo tinfo;
|
||||
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
|
||||
|
||||
ui.avatarWidget->setId(ChatId(_tunnel_id));
|
||||
|
||||
QString msg;
|
||||
switch(status)
|
||||
{
|
||||
case RS_DISTANT_CHAT_STATUS_UNKNOWN: //std::cerr << "Unknown hash. Error!" << std::endl;
|
||||
_status_label->setIcon(QIcon(IMAGE_GRY_LED)) ;
|
||||
msg = tr("Hash Error. No tunnel.");
|
||||
_status_label->setToolTip(msg) ;
|
||||
getChatWidget()->updateStatusString("%1", msg, true);
|
||||
getChatWidget()->blockSending(tr("Can't send message, because there is no tunnel."));
|
||||
setPeerStatus(RS_STATUS_OFFLINE) ;
|
||||
break ;
|
||||
case RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED: std::cerr << "Chat remotely closed. " << std::endl;
|
||||
_status_label->setIcon(QIcon(IMAGE_RED_LED)) ;
|
||||
_status_label->setToolTip(QObject::tr("Distant peer has closed the chat")) ;
|
||||
|
||||
getChatWidget()->updateStatusString("%1", tr("The person you're talking to has deleted the secured chat tunnel. You may remove the chat window now."), true);
|
||||
getChatWidget()->blockSending(tr("Can't send message, because the chat partner deleted the secure tunnel."));
|
||||
setPeerStatus(RS_STATUS_OFFLINE) ;
|
||||
switch(tinfo.status)
|
||||
{
|
||||
case RS_DISTANT_CHAT_STATUS_UNKNOWN: //std::cerr << "Unknown hash. Error!" << std::endl;
|
||||
_status_label->setIcon(QIcon(IMAGE_GRY_LED)) ;
|
||||
msg = tr("Chat remotely closed. Please close this window.");
|
||||
_status_label->setToolTip(msg) ;
|
||||
getChatWidget()->updateStatusString("%1", msg, true);
|
||||
getChatWidget()->blockSending(tr("Can't send message, because there is no tunnel."));
|
||||
setPeerStatus(RS_STATUS_OFFLINE) ;
|
||||
break ;
|
||||
case RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED: std::cerr << "Chat remotely closed. " << std::endl;
|
||||
_status_label->setIcon(QIcon(IMAGE_RED_LED)) ;
|
||||
_status_label->setToolTip(QObject::tr("Distant peer has closed the chat")) ;
|
||||
|
||||
break ;
|
||||
case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: //std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl;
|
||||
_status_label->setIcon(QIcon(IMAGE_RED_LED)) ;
|
||||
msg = QObject::tr("Tunnel is pending...");
|
||||
_status_label->setToolTip(msg) ;
|
||||
getChatWidget()->updateStatusString("%1", msg, true);
|
||||
getChatWidget()->blockSending(msg);
|
||||
setPeerStatus(RS_STATUS_OFFLINE) ;
|
||||
break ;
|
||||
case RS_DISTANT_CHAT_STATUS_TUNNEL_OK: //std::cerr << "Tunnel is ok. " << std::endl;
|
||||
_status_label->setIcon(QIcon(IMAGE_YEL_LED)) ;
|
||||
msg = QObject::tr("Secured tunnel established. Waiting for ACK...");
|
||||
_status_label->setToolTip(msg) ;
|
||||
getChatWidget()->updateStatusString("%1", msg, true);
|
||||
getChatWidget()->blockSending(msg);
|
||||
setPeerStatus(RS_STATUS_ONLINE) ;
|
||||
break ;
|
||||
case RS_DISTANT_CHAT_STATUS_CAN_TALK: //std::cerr << "Tunnel is ok and data is transmitted." << std::endl;
|
||||
_status_label->setIcon(QIcon(IMAGE_GRN_LED)) ;
|
||||
msg = QObject::tr("Secured tunnel is working. You can talk!");
|
||||
_status_label->setToolTip(msg) ;
|
||||
getChatWidget()->unblockSending();
|
||||
setPeerStatus(RS_STATUS_ONLINE) ;
|
||||
break ;
|
||||
}
|
||||
getChatWidget()->updateStatusString("%1", tr("The person you're talking to has deleted the secured chat tunnel. You may remove the chat window now."), true);
|
||||
getChatWidget()->blockSending(tr("Can't send message, because the chat partner deleted the secure tunnel."));
|
||||
setPeerStatus(RS_STATUS_OFFLINE) ;
|
||||
|
||||
break ;
|
||||
case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: //std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl;
|
||||
_status_label->setIcon(QIcon(IMAGE_RED_LED)) ;
|
||||
msg = QObject::tr("Tunnel is pending...");
|
||||
_status_label->setToolTip(msg) ;
|
||||
getChatWidget()->updateStatusString("%1", msg, true);
|
||||
getChatWidget()->blockSending(msg);
|
||||
setPeerStatus(RS_STATUS_OFFLINE) ;
|
||||
break ;
|
||||
case RS_DISTANT_CHAT_STATUS_CAN_TALK: //std::cerr << "Tunnel is ok and data is transmitted." << std::endl;
|
||||
_status_label->setIcon(QIcon(IMAGE_GRN_LED)) ;
|
||||
msg = QObject::tr("Secured tunnel is working. You can talk!");
|
||||
_status_label->setToolTip(msg) ;
|
||||
getChatWidget()->unblockSending();
|
||||
setPeerStatus(RS_STATUS_ONLINE) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
void PopupDistantChatDialog::closeEvent(QCloseEvent *e)
|
||||
{
|
||||
//std::cerr << "Closing window => closing distant chat for hash " << _pid << std::endl;
|
||||
//std::cerr << "Closing window => closing distant chat for hash " << _pid << std::endl;
|
||||
|
||||
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
|
||||
rsMsgs->getDistantChatStatus(_pid,status) ;
|
||||
DistantChatPeerInfo tinfo ;
|
||||
|
||||
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
|
||||
|
||||
if(status != RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED)
|
||||
if(tinfo.status != RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED)
|
||||
{
|
||||
QString msg = tr("Closing this window will end the conversation, notify the peer and remove the encrypted tunnel.") ;
|
||||
|
||||
if(QMessageBox::Ok == QMessageBox::critical(NULL,tr("Kill the tunnel?"),msg, QMessageBox::Ok | QMessageBox::Cancel))
|
||||
rsMsgs->closeDistantChatConnexion(_pid) ;
|
||||
rsMsgs->closeDistantChatConnexion(_tunnel_id) ;
|
||||
else
|
||||
{
|
||||
e->ignore() ;
|
||||
@ -166,23 +169,26 @@ void PopupDistantChatDialog::closeEvent(QCloseEvent *e)
|
||||
|
||||
QString PopupDistantChatDialog::getPeerName(const ChatId &id) const
|
||||
{
|
||||
DistantChatPeerInfo tinfo;
|
||||
|
||||
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
|
||||
|
||||
RsIdentityDetails details ;
|
||||
if(rsIdentity->getIdDetails(id.toGxsId(),details))
|
||||
if(rsIdentity->getIdDetails(tinfo.to_id,details))
|
||||
return QString::fromUtf8( details.mNickname.c_str() ) ;
|
||||
else
|
||||
return QString::fromStdString(id.toGxsId().toStdString()) ;
|
||||
return QString::fromStdString(tinfo.to_id.toStdString()) ;
|
||||
}
|
||||
|
||||
QString PopupDistantChatDialog::getOwnName() const
|
||||
{
|
||||
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
|
||||
RsGxsId from_gxs_id ;
|
||||
DistantChatPeerInfo tinfo;
|
||||
|
||||
rsMsgs->getDistantChatStatus(_pid,status,&from_gxs_id) ;
|
||||
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
|
||||
|
||||
RsIdentityDetails details ;
|
||||
if(rsIdentity->getIdDetails(from_gxs_id,details))
|
||||
if(rsIdentity->getIdDetails(tinfo.own_id,details))
|
||||
return QString::fromUtf8( details.mNickname.c_str() ) ;
|
||||
else
|
||||
return QString::fromStdString(from_gxs_id.toStdString()) ;
|
||||
return QString::fromStdString(tinfo.own_id.toStdString()) ;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <retroshare/rsgxstunnel.h>
|
||||
#include "PopupChatDialog.h"
|
||||
|
||||
class QTimer ;
|
||||
@ -33,11 +34,11 @@ class PopupDistantChatDialog: public PopupChatDialog
|
||||
|
||||
protected:
|
||||
/** Default constructor */
|
||||
PopupDistantChatDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
|
||||
PopupDistantChatDialog(const DistantChatPeerId &tunnel_id, QWidget *parent = 0, Qt::WindowFlags flags = 0);
|
||||
/** Default destructor */
|
||||
virtual ~PopupDistantChatDialog();
|
||||
|
||||
virtual void init(const RsGxsId &gxs_id, const QString &title);
|
||||
virtual void init(const DistantChatPeerId& peer_id);
|
||||
virtual void closeEvent(QCloseEvent *e) ;
|
||||
|
||||
virtual QString getPeerName(const ChatId &id) const ;
|
||||
@ -48,7 +49,7 @@ class PopupDistantChatDialog: public PopupChatDialog
|
||||
|
||||
private:
|
||||
QTimer *_update_timer ;
|
||||
RsGxsId _pid ;
|
||||
DistantChatPeerId _tunnel_id ;
|
||||
QToolButton *_status_label ;
|
||||
|
||||
friend class ChatDialog;
|
||||
|
@ -124,24 +124,33 @@ void AvatarWidget::setFrameType(FrameType type)
|
||||
void AvatarWidget::setId(const ChatId &id)
|
||||
{
|
||||
mId = id;
|
||||
// mPgpId = rsPeers->getGPGId(id) ;
|
||||
// mFlag.isGpg = false ;
|
||||
mGxsId.clear();
|
||||
|
||||
setPixmap(QPixmap());
|
||||
|
||||
if (id.isNotSet()) {
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
refreshAvatarImage();
|
||||
refreshStatus();
|
||||
}
|
||||
|
||||
void AvatarWidget::setGxsId(const RsGxsId &id)
|
||||
{
|
||||
mId = ChatId();
|
||||
mGxsId = id;
|
||||
|
||||
setPixmap(QPixmap());
|
||||
|
||||
if (id.isNull()) {
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
refreshAvatarImage();
|
||||
refreshStatus();
|
||||
}
|
||||
void AvatarWidget::setOwnId(const RsGxsId& own_gxs_id)
|
||||
{
|
||||
mFlag.isOwnId = true;
|
||||
|
||||
setId(ChatId(own_gxs_id));
|
||||
}
|
||||
void AvatarWidget::setOwnId()
|
||||
{
|
||||
mFlag.isOwnId = true;
|
||||
@ -181,7 +190,7 @@ void AvatarWidget::refreshStatus()
|
||||
rsStatus->getOwnStatus(statusInfo);
|
||||
status = statusInfo.status ;
|
||||
}
|
||||
else if(mId.isGxsId())
|
||||
else if(mId.isDistantChatId())
|
||||
status = RS_STATUS_ONLINE ;
|
||||
else
|
||||
{
|
||||
@ -198,11 +207,15 @@ void AvatarWidget::refreshStatus()
|
||||
rsStatus->getStatus(mId.toPeerId(), statusInfo);
|
||||
status = statusInfo.status ;
|
||||
}
|
||||
else if(mId.isGxsId())
|
||||
{
|
||||
if(!rsMsgs->getDistantChatStatus(mId.toGxsId(),status))
|
||||
status = RS_STATUS_OFFLINE ;
|
||||
}
|
||||
else if(mId.isDistantChatId())
|
||||
{
|
||||
DistantChatPeerInfo dcpinfo ;
|
||||
|
||||
if(rsMsgs->getDistantChatStatus(mId.toDistantChatId(),dcpinfo))
|
||||
status = dcpinfo.status ;
|
||||
else
|
||||
std::cerr << "(EE) cannot get distant chat status for ID=" << mId.toDistantChatId() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Unhandled chat id type in AvatarWidget::refreshStatus()" << std::endl;
|
||||
@ -235,13 +248,22 @@ void AvatarWidget::updateStatus(int status)
|
||||
void AvatarWidget::updateAvatar(const QString &peerId)
|
||||
{
|
||||
if(mId.isPeerId() && mId.toPeerId() == RsPeerId(peerId.toStdString()))
|
||||
refreshAvatarImage() ;
|
||||
|
||||
if(mId.isGxsId() && mId.toGxsId() == RsGxsId(peerId.toStdString()))
|
||||
refreshAvatarImage() ;
|
||||
refreshAvatarImage() ;
|
||||
else if(mId.isDistantChatId() && mId.toDistantChatId() == DistantChatPeerId(peerId.toStdString()))
|
||||
refreshAvatarImage() ;
|
||||
else
|
||||
std::cerr << "(EE) cannot update avatar. mId has unhandled type." << std::endl;
|
||||
}
|
||||
void AvatarWidget::refreshAvatarImage()
|
||||
{
|
||||
if (mGxsId.isNull()==false)
|
||||
{
|
||||
QPixmap avatar;
|
||||
|
||||
AvatarDefs::getAvatarFromGxsId(mGxsId, avatar, defaultAvatar);
|
||||
setPixmap(avatar);
|
||||
return;
|
||||
}
|
||||
if (mId.isNotSet())
|
||||
{
|
||||
QPixmap avatar(defaultAvatar);
|
||||
@ -262,12 +284,21 @@ void AvatarWidget::refreshAvatarImage()
|
||||
setPixmap(avatar);
|
||||
return;
|
||||
}
|
||||
else if (mId.isGxsId())
|
||||
else if (mId.isDistantChatId())
|
||||
{
|
||||
QPixmap avatar;
|
||||
AvatarDefs::getAvatarFromGxsId(mId.toGxsId(), avatar, defaultAvatar);
|
||||
setPixmap(avatar);
|
||||
return;
|
||||
QPixmap avatar;
|
||||
|
||||
DistantChatPeerInfo dcpinfo ;
|
||||
|
||||
if(rsMsgs->getDistantChatStatus(mId.toDistantChatId(),dcpinfo))
|
||||
{
|
||||
if(mFlag.isOwnId)
|
||||
AvatarDefs::getAvatarFromGxsId(dcpinfo.own_id, avatar, defaultAvatar);
|
||||
else
|
||||
AvatarDefs::getAvatarFromGxsId(dcpinfo.to_id, avatar, defaultAvatar);
|
||||
setPixmap(avatar);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
std::cerr << "WARNING: unhandled situation in AvatarWidget::refreshAvatarImage()" << std::endl;
|
||||
|
@ -50,8 +50,8 @@ public:
|
||||
QString frameState();
|
||||
void setFrameType(FrameType type);
|
||||
void setId(const ChatId& id) ;
|
||||
void setGxsId(const RsGxsId& id) ;
|
||||
void setOwnId();
|
||||
void setOwnId(const RsGxsId&);
|
||||
void setDefaultAvatar(const QString &avatar_file_name);
|
||||
|
||||
protected:
|
||||
@ -71,6 +71,7 @@ private:
|
||||
Ui::AvatarWidget *ui;
|
||||
|
||||
ChatId mId;
|
||||
RsGxsId mGxsId;
|
||||
|
||||
struct {
|
||||
bool isOwnId : 1;
|
||||
|
@ -46,7 +46,7 @@ void GroupSelectionBox::selectedGroupIds(std::list<std::string> &groupIds) const
|
||||
QListWidgetItem *listItem = item(i);
|
||||
if (listItem->checkState() == Qt::Checked) {
|
||||
groupIds.push_back(item(i)->data(ROLE_ID).toString().toStdString());
|
||||
std::cerr << "Addign selected item " << groupIds.back() << std::endl;
|
||||
std::cerr << "Adding selected item " << groupIds.back() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -74,7 +74,7 @@ void GroupSelectionBox::selectedGroupNames(QList<QString> &groupNames) const
|
||||
QListWidgetItem *listItem = item(i);
|
||||
if (listItem->checkState() == Qt::Checked) {
|
||||
groupNames.push_back(item(i)->text());
|
||||
std::cerr << "Addign selected item " << groupNames.back().toUtf8().constData() << std::endl;
|
||||
std::cerr << "Adding selected item " << groupNames.back().toUtf8().constData() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,11 +88,9 @@ void MsgItem::updateItemStatic()
|
||||
/* get peer Id */
|
||||
|
||||
if(mi.msgflags & RS_MSG_SIGNED)
|
||||
mPeerId = ChatId(mi.rsgxsid_srcId);
|
||||
avatar->setGxsId(mi.rsgxsid_srcId);
|
||||
else
|
||||
mPeerId = ChatId(mi.rspeerid_srcId);
|
||||
|
||||
avatar->setId(mPeerId);
|
||||
avatar->setId(ChatId(mi.rspeerid_srcId));
|
||||
|
||||
QString title;
|
||||
QString srcName;
|
||||
|
@ -64,7 +64,6 @@ private:
|
||||
FeedHolder *mParent;
|
||||
uint32_t mFeedId;
|
||||
|
||||
ChatId mPeerId;
|
||||
std::string mMsgId;
|
||||
QString mMsg;
|
||||
|
||||
|
@ -259,6 +259,13 @@ void GxsGroupFrameDialog::groupTreeCustomPopupMenu(QPoint point)
|
||||
QMenu contextMnu(this);
|
||||
|
||||
QAction *action;
|
||||
|
||||
if (mMessageWidget) {
|
||||
action = contextMnu.addAction(QIcon(IMAGE_TABNEW), tr("Open in new tab"), this, SLOT(openInNewTab()));
|
||||
if (mGroupId.isNull() || messageWidget(mGroupId, true)) {
|
||||
action->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (isSubscribed) {
|
||||
action = contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Unsubscribe"), this, SLOT(unsubscribeGroup()));
|
||||
@ -268,13 +275,6 @@ void GxsGroupFrameDialog::groupTreeCustomPopupMenu(QPoint point)
|
||||
action->setDisabled (mGroupId.isNull() || IS_GROUP_SUBSCRIBED(subscribeFlags));
|
||||
}
|
||||
|
||||
if (mMessageWidget) {
|
||||
action = contextMnu.addAction(QIcon(IMAGE_TABNEW), tr("Open in new tab"), this, SLOT(openInNewTab()));
|
||||
if (mGroupId.isNull() || messageWidget(mGroupId, true)) {
|
||||
action->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
contextMnu.addSeparator();
|
||||
|
||||
contextMnu.addAction(QIcon(icon(ICON_NEW)), text(TEXT_NEW), this, SLOT(newGroup()));
|
||||
|
@ -116,7 +116,7 @@ ImHistoryBrowser::ImHistoryBrowser(const ChatId &chatId, QTextEdit *edit, QWidge
|
||||
ui.filterLineEdit->showFilterIcon();
|
||||
|
||||
// embed smileys ?
|
||||
if (m_chatId.isPeerId() || m_chatId.isGxsId()) {
|
||||
if (m_chatId.isPeerId() || m_chatId.isDistantChatId()) {
|
||||
embedSmileys = Settings->valueFromGroup("Chat", "Emoteicons_PrivatChat", true).toBool();
|
||||
} else {
|
||||
embedSmileys = Settings->valueFromGroup("Chat", "Emoteicons_GroupChat", true).toBool();
|
||||
@ -275,7 +275,7 @@ void ImHistoryBrowser::fillItem(QListWidgetItem *itemWidget, HistoryMsg& msg)
|
||||
QString messageText = RsHtml().formatText(NULL, QString::fromUtf8(msg.message.c_str()), formatTextFlag);
|
||||
|
||||
QString name;
|
||||
if (m_chatId.isLobbyId() || m_chatId.isGxsId()) {
|
||||
if (m_chatId.isLobbyId() || m_chatId.isDistantChatId()) {
|
||||
RsIdentityDetails details;
|
||||
if (rsIdentity->getIdDetails(RsGxsId(msg.peerName), details))
|
||||
name = QString::fromUtf8(details.mNickname.c_str());
|
||||
|
@ -112,7 +112,7 @@ bool RsharePeerSettings::getSettingsIdOfPeerId(const ChatId& chatId, std::string
|
||||
m_SslToGpg[peerId] = settingsId ;
|
||||
return true;
|
||||
}
|
||||
if(chatId.isGxsId() || chatId.isLobbyId() || chatId.isBroadcast())
|
||||
if(chatId.isDistantChatId() || chatId.isLobbyId() || chatId.isBroadcast())
|
||||
{
|
||||
settingsId = chatId.toStdString();
|
||||
return true;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <QObject>
|
||||
#include <retroshare/rsturtle.h>
|
||||
#include <retroshare/rspeers.h>
|
||||
#include <retroshare/rsgxstunnel.h>
|
||||
#include "TurtleRouterDialog.h"
|
||||
#include <QPainter>
|
||||
#include <QStylePainter>
|
||||
@ -216,3 +217,156 @@ QTreeWidgetItem *TurtleRouterDialog::findParentHashItem(const std::string& hash)
|
||||
else
|
||||
return items.front() ;
|
||||
}
|
||||
//=======================================================================================================================//
|
||||
|
||||
|
||||
GxsTunnelsDialog::GxsTunnelsDialog(QWidget *parent)
|
||||
: RsAutoUpdatePage(2000,parent)
|
||||
{
|
||||
// setupUi(this) ;
|
||||
|
||||
m_bProcessSettings = false;
|
||||
|
||||
float fontHeight = QFontMetricsF(font()).height();
|
||||
float fact = fontHeight/14.0;
|
||||
|
||||
maxWidth = 200 ;
|
||||
maxHeight = 200 ;
|
||||
|
||||
// load settings
|
||||
processSettings(true);
|
||||
}
|
||||
|
||||
GxsTunnelsDialog::~GxsTunnelsDialog()
|
||||
{
|
||||
|
||||
// save settings
|
||||
processSettings(false);
|
||||
}
|
||||
|
||||
void GxsTunnelsDialog::processSettings(bool bLoad)
|
||||
{
|
||||
m_bProcessSettings = true;
|
||||
|
||||
Settings->beginGroup(QString("TurtleRouterStatistics"));
|
||||
|
||||
if (bLoad) {
|
||||
// load settings
|
||||
} else {
|
||||
// save settings
|
||||
}
|
||||
|
||||
Settings->endGroup();
|
||||
|
||||
m_bProcessSettings = false;
|
||||
}
|
||||
|
||||
void GxsTunnelsDialog::updateDisplay()
|
||||
{
|
||||
// Request info about ongoing tunnels
|
||||
|
||||
std::vector<RsGxsTunnelService::GxsTunnelInfo> tunnel_infos ;
|
||||
|
||||
rsGxsTunnel->getTunnelsInfo(tunnel_infos) ;
|
||||
|
||||
// // Tunnel information
|
||||
//
|
||||
// GxsTunnelId tunnel_id ; // GXS Id we're talking to
|
||||
// RsGxsId destination_gxs_id ; // GXS Id we're talking to
|
||||
// RsGxsId source_gxs_id ; // GXS Id we're using to talk
|
||||
// uint32_t tunnel_status ; // active, requested, DH pending, etc.
|
||||
// uint32_t total_size_sent ; // total bytes sent through that tunnel since openned (including management).
|
||||
// uint32_t total_size_received ; // total bytes received through that tunnel since openned (including management).
|
||||
|
||||
// // Data packets
|
||||
|
||||
// uint32_t pending_data_packets; // number of packets not acknowledged by other side, still on their way. Should be 0 unless something bad happens.
|
||||
// uint32_t total_data_packets_sent ; // total number of data packets sent (does not include tunnel management)
|
||||
// uint32_t total_data_packets_received ; // total number of data packets received (does not include tunnel management)
|
||||
|
||||
// now draw the shit
|
||||
QPixmap tmppixmap(maxWidth, maxHeight);
|
||||
tmppixmap.fill(Qt::transparent);
|
||||
//setFixedHeight(maxHeight);
|
||||
|
||||
QPainter painter(&tmppixmap);
|
||||
painter.initFrom(this);
|
||||
|
||||
// extracts the height of the fonts in pixels. This is used to calibrate the size of the objects to draw.
|
||||
|
||||
float fontHeight = QFontMetricsF(font()).height();
|
||||
float fact = fontHeight/14.0;
|
||||
//maxHeight = 500*fact ;
|
||||
|
||||
int cellx = 6*fact ;
|
||||
int celly = (10+4)*fact ;
|
||||
int ox=5*fact,oy=5*fact ;
|
||||
|
||||
painter.setPen(QColor::fromRgb(0,0,0)) ;
|
||||
painter.drawText(ox+2*cellx,oy+celly,tr("Authenticated tunnels:")) ; oy += celly ;
|
||||
|
||||
for(uint32_t i=0;i<tunnel_infos.size();++i)
|
||||
{
|
||||
// std::cerr << "Drawing into pixmap of size " << maxWidth << "x" << maxHeight << std::endl;
|
||||
// draw...
|
||||
|
||||
painter.drawText(ox+4*cellx,oy+celly,tr("Tunnel ID: %1").arg(QString::fromStdString(tunnel_infos[i].tunnel_id.toStdString()))) ; oy += celly ;
|
||||
painter.drawText(ox+6*cellx,oy+celly,tr("from: %1").arg(QString::fromStdString(tunnel_infos[i].source_gxs_id.toStdString()))) ; oy += celly ;
|
||||
painter.drawText(ox+6*cellx,oy+celly,tr("to: %1").arg(QString::fromStdString(tunnel_infos[i].destination_gxs_id.toStdString()))) ; oy += celly ;
|
||||
painter.drawText(ox+6*cellx,oy+celly,tr("status: %1").arg(QString::number(tunnel_infos[i].tunnel_status))) ; oy += celly ;
|
||||
painter.drawText(ox+6*cellx,oy+celly,tr("total sent: %1 bytes").arg(QString::number(tunnel_infos[i].total_size_sent))) ; oy += celly ;
|
||||
painter.drawText(ox+6*cellx,oy+celly,tr("total recv: %1 bytes").arg(QString::number(tunnel_infos[i].total_size_received))) ; oy += celly ;
|
||||
|
||||
// painter.drawLine(0,oy,maxWidth,oy) ;
|
||||
// oy += celly ;
|
||||
}
|
||||
|
||||
// update the pixmap
|
||||
//
|
||||
pixmap = tmppixmap;
|
||||
maxHeight = std::max(oy,10*celly);
|
||||
}
|
||||
|
||||
QString GxsTunnelsDialog::getPeerName(const RsPeerId &peer_id)
|
||||
{
|
||||
static std::map<RsPeerId, QString> names ;
|
||||
|
||||
std::map<RsPeerId,QString>::const_iterator it = names.find(peer_id) ;
|
||||
|
||||
if( it != names.end())
|
||||
return it->second ;
|
||||
else
|
||||
{
|
||||
RsPeerDetails detail ;
|
||||
if(!rsPeers->getPeerDetails(peer_id,detail))
|
||||
return tr("Unknown Peer");
|
||||
|
||||
return (names[peer_id] = QString::fromUtf8(detail.name.c_str())) ;
|
||||
}
|
||||
}
|
||||
|
||||
QString GxsTunnelsDialog::speedString(float f)
|
||||
{
|
||||
if(f < 1.0f)
|
||||
return QString("0 B/s") ;
|
||||
if(f < 1024.0f)
|
||||
return QString::number((int)f)+" B/s" ;
|
||||
|
||||
return QString::number(f/1024.0,'f',2) + " KB/s";
|
||||
}
|
||||
|
||||
void GxsTunnelsDialog::paintEvent(QPaintEvent */*event*/)
|
||||
{
|
||||
QStylePainter(this).drawPixmap(0, 0, pixmap);
|
||||
}
|
||||
|
||||
void GxsTunnelsDialog::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QRect TaskGraphRect = geometry();
|
||||
|
||||
maxWidth = TaskGraphRect.width();
|
||||
maxHeight = TaskGraphRect.height() ;
|
||||
|
||||
QWidget::resizeEvent(event);
|
||||
update();
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <retroshare/rsturtle.h>
|
||||
#include <retroshare/rstypes.h>
|
||||
#include "ui_TurtleRouterDialog.h"
|
||||
#include "ui_TurtleRouterStatistics.h"
|
||||
#include "RsAutoUpdatePage.h"
|
||||
|
||||
|
||||
@ -35,3 +36,30 @@ class TurtleRouterDialog: public RsAutoUpdatePage, public Ui::TurtleRouterDialog
|
||||
QTreeWidgetItem *top_level_t_requests ;
|
||||
|
||||
} ;
|
||||
|
||||
class GxsTunnelsDialog: public RsAutoUpdatePage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GxsTunnelsDialog(QWidget *parent = NULL) ;
|
||||
~GxsTunnelsDialog();
|
||||
|
||||
// Cache for peer names.
|
||||
static QString getPeerName(const RsPeerId &peer_id) ;
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent *);
|
||||
virtual void resizeEvent(QResizeEvent *event);
|
||||
private:
|
||||
void processSettings(bool bLoad);
|
||||
bool m_bProcessSettings;
|
||||
static QString speedString(float f);
|
||||
|
||||
virtual void updateDisplay() ;
|
||||
|
||||
int maxWidth ;
|
||||
int maxHeight ;
|
||||
|
||||
QPixmap pixmap;
|
||||
} ;
|
||||
|
@ -195,8 +195,8 @@ TurtleRouterStatistics::TurtleRouterStatistics(QWidget *parent)
|
||||
_tunnel_statistics_F->setFrameStyle(QFrame::NoFrame);
|
||||
_tunnel_statistics_F->setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
routertabWidget->addTab(new TurtleRouterDialog(),QString(tr("Tunnel Requests")));
|
||||
|
||||
routertabWidget->addTab(new TurtleRouterDialog(),QString(tr("Anonymous tunnels")));
|
||||
routertabWidget->addTab(new GxsTunnelsDialog(),QString(tr("Authenticated tunnels")));
|
||||
|
||||
float fontHeight = QFontMetricsF(font()).height();
|
||||
float fact = fontHeight/14.0;
|
||||
|
@ -45,7 +45,7 @@ ChatLobbyToaster::ChatLobbyToaster(const ChatLobbyId &lobby_id, const RsGxsId &s
|
||||
if(!rsIdentity->getIdDetails(sender_id, idd))
|
||||
return;
|
||||
|
||||
ui.avatarWidget->setId(ChatId(sender_id));
|
||||
ui.avatarWidget->setGxsId(sender_id);
|
||||
|
||||
QString lobbyName = RsHtml::plainText(idd.mNickname);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user