From fd20f629dc910b1b4f0473dd9e116cf6ef154598 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 17 Nov 2014 21:56:41 +0000 Subject: [PATCH] fixed GUI for distant chat: correct display of peer names, chat window on client shows up when chat is openned. Window on server only shows up when first message is received. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7688 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/chat/distantchat.cc | 123 ++++++++++-------- libretroshare/src/chat/distantchat.h | 117 ++++++++--------- retroshare-gui/src/gui/chat/ChatWidget.cpp | 10 +- .../src/gui/chat/PopupDistantChatDialog.cpp | 17 +-- .../src/gui/chat/PopupDistantChatDialog.h | 2 +- 5 files changed, 139 insertions(+), 130 deletions(-) diff --git a/libretroshare/src/chat/distantchat.cc b/libretroshare/src/chat/distantchat.cc index 7169cf575..9916dc31b 100644 --- a/libretroshare/src/chat/distantchat.cc +++ b/libretroshare/src/chat/distantchat.cc @@ -45,7 +45,7 @@ #include #include "distantchat.h" -#define DEBUG_DISTANT_CHAT +//#define DEBUG_DISTANT_CHAT void DistantChatService::connectToTurtleRouter(p3turtle *tr) { @@ -250,11 +250,11 @@ void DistantChatService::addVirtualPeer(const TurtleFileHash& hash,const TurtleV // // privateIncomingList.push_back(item) ; - RsServer::notify()->AddPopupMessage(RS_POPUP_CHAT, virtual_peer_id.toStdString(), "Distant peer", "Conversation starts..."); +// RsServer::notify()->AddPopupMessage(RS_POPUP_CHAT, virtual_peer_id.toStdString(), "Distant peer", "Conversation starts..."); // Notify the GUI that the tunnel is up. // - RsServer::notify()->notifyChatShow(virtual_peer_id.toStdString()) ; +// RsServer::notify()->notifyChatShow(virtual_peer_id.toStdString()) ; } void DistantChatService::removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id) @@ -610,7 +610,7 @@ bool DistantChatService::locked_sendDHPublicKey(const DistantChatPeerInfo& pinfo dhitem->signature = signature ; dhitem->gxs_key = signature_key_public ; - dhitem->PeerId(RsPeerId(pinfo.gxs_id)) ; + dhitem->PeerId(RsPeerId(pinfo.virtual_peer_id)) ; // special case for DH items #ifdef DEBUG_DISTANT_CHAT std::cerr << " Pushing DH session key item to pending distant messages..." << std::endl; @@ -679,54 +679,76 @@ void DistantChatService::sendTurtleData(RsChatItem *item) std::cerr << " Serialized item has size " << rssize << std::endl; #endif - uint8_t aes_key[DISTANT_CHAT_AES_KEY_SIZE] ; - - TurtleFileHash hash = hashFromGxsId(RsGxsId(item->PeerId())) ; + uint8_t aes_key[DISTANT_CHAT_AES_KEY_SIZE] ; + uint64_t IV ; TurtleVirtualPeerId virtual_peer_id ; - { - RsStackMutex stack(mDistantChatMtx); /********** STACK LOCKED MTX ******/ - std::map::iterator it = _distant_chat_peers.find(hash) ; - - if(it == _distant_chat_peers.end()) - { - std::cerr << "(EE) No distant chat info for peer id = " << item->PeerId() << ". Dropping the item!" << std::endl; - delete[] buff ; - return ; - } - it->second.last_contact = time(NULL) ; - memcpy(aes_key,it->second.aes_key,DISTANT_CHAT_AES_KEY_SIZE) ; - virtual_peer_id = it->second.virtual_peer_id ; - } -#ifdef DEBUG_DISTANT_CHAT - std::cerr << "DistantChatService::sendTurtleData(): tunnel found. Encrypting data." << std::endl; -#endif - - // Now encrypt this data using AES. - // - uint8_t *encrypted_data = new uint8_t[RsAES::get_buffer_size(rssize)]; - uint32_t encrypted_size = RsAES::get_buffer_size(rssize); - uint64_t IV = RSRandom::random_u64() ; // make a random 8 bytes IV - - if(dynamic_cast(item) != NULL) + if(dynamic_cast(item)) { - memset(aes_key,0,16) ; - IV = 0 ; +#ifdef DEBUG_DISTANT_CHAT + std::cerr << " Packet is a DH session key. Using Peer Id " << item->PeerId() << " as virtual peer id" << std::endl; +#endif + RsStackMutex stack(mDistantChatMtx); /********** STACK LOCKED MTX ******/ + for(std::map::iterator it = _distant_chat_peers.begin();it!=_distant_chat_peers.end();++it) + if(it->second.virtual_peer_id == item->PeerId()) + { + it->second.last_contact = time(NULL) ; + break ; + } + + virtual_peer_id = item->PeerId() ; + #ifdef DEBUG_DISTANT_CHAT std::cerr << " Special item DH session key --> will be sent unencrypted." << std::endl ; #endif + memset(aes_key,0,DISTANT_CHAT_AES_KEY_SIZE) ; + IV = 0 ; } + else + { +#ifdef DEBUG_DISTANT_CHAT + std::cerr << " Packet is a normal chat message. Sending to GXS id " << item->PeerId() << std::endl; +#endif + bool found = false ; + + RsStackMutex stack(mDistantChatMtx); /********** STACK LOCKED MTX ******/ + for(std::map::iterator it = _distant_chat_peers.begin();it!=_distant_chat_peers.end();++it) + if(it->second.gxs_id == RsGxsId(item->PeerId())) + { + it->second.last_contact = time(NULL) ; + memcpy(aes_key,it->second.aes_key,DISTANT_CHAT_AES_KEY_SIZE) ; + virtual_peer_id = it->second.virtual_peer_id ; + IV = RSRandom::random_u64() ; // make a random 8 bytes IV + found = true ; + break ; + } + + if(!found) + { + std::cerr << "(EE) No distant chat info for peer id = " << item->PeerId() << ". Dropping the item!" << std::endl; + delete[] buff ; + return ; + } + } +#ifdef DEBUG_DISTANT_CHAT + std::cerr << "DistantChatService::sendTurtleData(): tunnel found. Encrypting data." << std::endl; +#endif + + // Now encrypt this data using AES. + // + uint8_t *encrypted_data = new uint8_t[RsAES::get_buffer_size(rssize)]; + uint32_t encrypted_size = RsAES::get_buffer_size(rssize); #ifdef DEBUG_DISTANT_CHAT std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl; std::cerr << " Using Key: " ; printBinaryData(aes_key,16) ; std::cerr << std::endl; #endif if(!RsAES::aes_crypt_8_16(buff,rssize,aes_key,(uint8_t*)&IV,encrypted_data,encrypted_size)) - { - std::cerr << "(EE) packet encryption failed." << std::endl; - delete[] encrypted_data ; - delete[] buff ; - return ; + { + std::cerr << "(EE) packet encryption failed." << std::endl; + delete[] encrypted_data ; + delete[] buff ; + return ; } delete[] buff ; @@ -773,8 +795,15 @@ bool DistantChatService::initiateDistantChatConnexion(const RsGxsId& gxs_id,uint // startClientDistantChatConnection(hash,gxs_id,own_gxs_id) ; + error_code = RS_DISTANT_CHAT_ERROR_NO_ERROR ; + + // spawn a status item so as to open the chat window. + RsChatMsgItem *item = new RsChatMsgItem; + item->message = "Starting distant chat. Please wait for secure tunnel to be established." ; + item->chatFlags = RS_CHAT_FLAG_PRIVATE ; + item->PeerId(RsPeerId(gxs_id)) ; + handleRecvChatMsgItem(item) ; - error_code = RS_DISTANT_CHAT_ERROR_NO_ERROR ; return true ; } @@ -805,20 +834,6 @@ void DistantChatService::startClientDistantChatConnection(const RsFileHash& hash mTurtle->monitorTunnels(hash,this) ; } -// DistantChatPeerId DistantChatService::virtualPeerIdFromHash(const TurtleFileHash& hash) -// { -// RsStackMutex stack(mDistantChatMtx); /********** STACK LOCKED MTX ******/ -// -// std::map::const_iterator it = _distant_chat_peers.find(hash) ; -// -// if(it == _distant_chat_peers.end()) -// { -// std::cerr << " (EE) Cannot find hash " << hash << " in distant peers list. Virtual peer id cannot be returned." << std::endl; -// return DistantChatPeerId() ; -// } -// else -// return it->second.virtual_peer_id ; -// } TurtleFileHash DistantChatService::hashFromGxsId(const RsGxsId& gid) { if(RsGxsId::SIZE_IN_BYTES > Sha1CheckSum::SIZE_IN_BYTES) diff --git a/libretroshare/src/chat/distantchat.h b/libretroshare/src/chat/distantchat.h index 212338435..af0311895 100644 --- a/libretroshare/src/chat/distantchat.h +++ b/libretroshare/src/chat/distantchat.h @@ -36,84 +36,85 @@ static const uint32_t DISTANT_CHAT_AES_KEY_SIZE = 16 ; class DistantChatService: public RsTurtleClientService { - public: - DistantChatService(p3IdService *pids) - : mIdService(pids), mDistantChatMtx("distant chat") - { - mTurtle = NULL ; - } +public: + DistantChatService(p3IdService *pids) + : mIdService(pids), mDistantChatMtx("distant chat") + { + mTurtle = NULL ; + } - void flush() ; + void flush() ; - virtual void connectToTurtleRouter(p3turtle *) ; + 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. - // - bool initiateDistantChatConnexion(const RsGxsId& gxs_id,uint32_t& error_code) ; - bool closeDistantChatConnexion(const RsGxsId& pid) ; - virtual bool getDistantChatStatus(const RsGxsId &gxs_id,uint32_t &status) ; + // 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& gxs_id,uint32_t& error_code) ; + bool closeDistantChatConnexion(const RsGxsId& pid) ; + virtual bool getDistantChatStatus(const RsGxsId &gxs_id,uint32_t &status) ; - // derived in p3ChatService - virtual void handleIncomingItem(RsItem *) = 0; + // derived in p3ChatService + virtual void handleIncomingItem(RsItem *) = 0; + virtual bool handleRecvChatMsgItem(RsChatMsgItem *ci)=0 ; - bool handleOutgoingItem(RsChatItem *) ; - bool handleRecvItem(RsChatItem *) ; - void handleRecvChatStatusItem(RsChatStatusItem *cs) ; + bool handleOutgoingItem(RsChatItem *) ; + bool handleRecvItem(RsChatItem *) ; + void handleRecvChatStatusItem(RsChatStatusItem *cs) ; - private: - class DistantChatPeerInfo - { - public: - DistantChatPeerInfo() { dh = NULL; } +private: + class DistantChatPeerInfo + { + public: + DistantChatPeerInfo() { dh = NULL; } - time_t last_contact ; // used to send keep alive packets + time_t last_contact ; // used to send keep alive packets - DH *dh ; - unsigned char aes_key[DISTANT_CHAT_AES_KEY_SIZE] ; + DH *dh ; + 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 gxs_id ; // gxs id of the peer 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. - }; + uint32_t status ; // info: do we have a tunnel ? + RsPeerId virtual_peer_id; // given by the turtle router. Identifies the tunnel. + RsGxsId gxs_id ; // gxs id of the peer 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. + }; - // This maps contains the current peers to talk to with distant chat. - // - std::map _distant_chat_peers ; + // This maps contains the current peers to talk to with distant chat. + // + std::map _distant_chat_peers ; - // List of items to be sent asap. Used to store items that we cannot pass directly to - // sendTurtleData(), because of Mutex protection. + // List of items to be sent asap. Used to store items that we cannot pass directly to + // sendTurtleData(), because of Mutex protection. - std::list pendingDistantChatItems ; + std::list pendingDistantChatItems ; - // Overloaded from RsTurtleClientService + // 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 &vpid) ; - void startClientDistantChatConnection(const RsFileHash& hash,const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id) ; - bool getHashFromVirtualPeerId(const TurtleVirtualPeerId& pid,RsFileHash& hash) ; - TurtleFileHash hashFromGxsId(const RsGxsId& pid) ; + 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 &vpid) ; + void startClientDistantChatConnection(const RsFileHash& hash,const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id) ; + bool getHashFromVirtualPeerId(const TurtleVirtualPeerId& pid,RsFileHash& hash) ; + TurtleFileHash hashFromGxsId(const RsGxsId& pid) ; - void handleRecvDHPublicKey(RsChatDHPublicKeyItem *item) ; - bool locked_sendDHPublicKey(const DistantChatPeerInfo& pinfo) ; - bool locked_initDHSessionKey(DistantChatPeerInfo& pinfo); - DistantChatPeerId virtualPeerIdFromHash(const TurtleFileHash& hash ) ; // ... and to a hash for p3turtle + void handleRecvDHPublicKey(RsChatDHPublicKeyItem *item) ; + bool locked_sendDHPublicKey(const DistantChatPeerInfo& pinfo) ; + bool locked_initDHSessionKey(DistantChatPeerInfo& pinfo); + DistantChatPeerId virtualPeerIdFromHash(const TurtleFileHash& hash ) ; // ... and to a hash for p3turtle - // Utility functions + // Utility functions - void sendTurtleData(RsChatItem *) ; + void sendTurtleData(RsChatItem *) ; - static TurtleFileHash hashFromVirtualPeerId(const DistantChatPeerId& peerId) ; // converts IDs so that we can talk to RsPeerId from outside + static TurtleFileHash hashFromVirtualPeerId(const DistantChatPeerId& peerId) ; // converts IDs so that we can talk to RsPeerId from outside - p3turtle *mTurtle ; - p3IdService *mIdService ; + p3turtle *mTurtle ; + p3IdService *mIdService ; - RsMutex mDistantChatMtx ; + RsMutex mDistantChatMtx ; }; diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index 656973a3d..6a909051c 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -224,8 +224,7 @@ void ChatWidget::init(const RsPeerId &peerId, const QString &title) mChatType = CHATTYPE_LOBBY; } else { uint32_t status; - RsGxsId gxs_id; - if (rsMsgs->getDistantChatStatus(peerId, gxs_id, status)) { + if (rsMsgs->getDistantChatStatus(RsGxsId(peerId), status)) { mChatType = CHATTYPE_DISTANT; } else { mChatType = CHATTYPE_PRIVATE; @@ -1299,15 +1298,14 @@ void ChatWidget::updateStatus(const QString &peer_id, int status) QString peerName ; uint32_t stts ; - RsGxsId gxs_id ; - if(rsMsgs->getDistantChatStatus(peerId,gxs_id,stts)) + if(rsMsgs->getDistantChatStatus(RsGxsId(peerId),stts)) { RsIdentityDetails details ; - if(rsIdentity->getIdDetails(gxs_id,details)) + if(rsIdentity->getIdDetails(RsGxsId(peerId),details)) peerName = QString::fromUtf8( details.mNickname.c_str() ) ; else - peerName = QString::fromStdString(gxs_id.toStdString()) ; + peerName = QString::fromStdString(peerId.toStdString()) ; } else peerName = QString::fromUtf8(rsPeers->getPeerName(peerId).c_str()); diff --git a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp index 95d104b47..468ee2c90 100644 --- a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp +++ b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp @@ -138,20 +138,15 @@ void PopupDistantChatDialog::closeEvent(QCloseEvent *e) PopupChatDialog::closeEvent(e) ; } -QString PopupDistantChatDialog::getPeerName(const RsGxsId& id) const +QString PopupDistantChatDialog::getPeerName(const RsPeerId& id) const { - uint32_t status ; + uint32_t status ; - if(rsMsgs->getDistantChatStatus(id,status)) - { - RsIdentityDetails details ; + RsIdentityDetails details ; if(rsIdentity->getIdDetails(RsGxsId(id),details)) - return QString::fromUtf8( details.mNickname.c_str() ) ; - else - return QString::fromStdString(id.toStdString()) ; - } - else - return ChatDialog::getPeerName(RsPeerId(id)) ; + return QString::fromUtf8( details.mNickname.c_str() ) ; + else + return QString::fromStdString(id.toStdString()) ; } diff --git a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h index 9db588356..baa8341ea 100644 --- a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h +++ b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h @@ -40,7 +40,7 @@ class PopupDistantChatDialog: public PopupChatDialog virtual void init(const RsPeerId &pid, const QString &title); virtual void closeEvent(QCloseEvent *e) ; - virtual QString getPeerName(const RsGxsId &id) const ; + virtual QString getPeerName(const RsPeerId &id) const ; protected slots: void updateDisplay() ; // overloads RsAutoUpdatePage