mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-27 08:29:26 -05:00
fixed GUI update of avatars and status for distant chat. Updated backend for new model. Fixed a few bugs in serialisation
This commit is contained in:
parent
6951d730a5
commit
81ab43beb9
@ -72,7 +72,7 @@ StreamBase& operator << (StreamBase& left, ChatHandler::Lobby& l)
|
||||
<< makeKeyValueReference("subscribed", l.subscribed)
|
||||
<< makeKeyValueReference("auto_subscribe", l.auto_subscribe)
|
||||
<< makeKeyValueReference("is_private", l.is_private)
|
||||
<< makeKeyValueReference("gxs_id", l.gxs_id);
|
||||
<< makeKeyValueReference("distant_chat_id", l.distant_chat_id);
|
||||
return left;
|
||||
}
|
||||
|
||||
@ -81,7 +81,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;
|
||||
@ -157,7 +157,7 @@ void ChatHandler::tick()
|
||||
l.subscribed = true;
|
||||
l.auto_subscribe = info.lobby_flags & RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE;
|
||||
l.is_private = !(info.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC);
|
||||
l.gxs_id = info.gxs_id;
|
||||
l.distant_chat_id.clear() ;
|
||||
lobbies.push_back(l);
|
||||
}
|
||||
}
|
||||
@ -176,7 +176,7 @@ void ChatHandler::tick()
|
||||
l.subscribed = false;
|
||||
l.auto_subscribe = info.lobby_flags & RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE;
|
||||
l.is_private = !(info.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC);
|
||||
l.gxs_id = RsGxsId();
|
||||
l.distant_chat_id.clear();
|
||||
lobbies.push_back(l);
|
||||
}
|
||||
}
|
||||
@ -199,11 +199,19 @@ 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();
|
||||
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 ;
|
||||
}
|
||||
|
||||
author_id = dcpinfo.to_id.toStdString();
|
||||
RsIdentityDetails details;
|
||||
if(!gxs_id_failed && mRsIdentity->getIdDetails(msg.chat_id.toGxsId(), details))
|
||||
if(!gxs_id_failed && mRsIdentity->getIdDetails(dcpinfo.to_id, details))
|
||||
{
|
||||
author_name = details.mNickname;
|
||||
}
|
||||
@ -252,7 +260,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())
|
||||
@ -263,10 +271,13 @@ 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(dcpinfo.to_id, details))
|
||||
{
|
||||
info.remote_author_id = msg.chat_id.toGxsId().toStdString();
|
||||
info.remote_author_name = details.mNickname;
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
bool auto_subscribe;
|
||||
bool is_private;
|
||||
|
||||
RsGxsId gxs_id;// for subscribed lobbies: the id we use to write messages
|
||||
DistantChatPeerId distant_chat_id;// for subscribed lobbies: the id we use to write messages
|
||||
|
||||
bool operator==(const Lobby& l) const
|
||||
{
|
||||
@ -75,14 +75,14 @@ public:
|
||||
&& subscribed == l.subscribed
|
||||
&& auto_subscribe == l.auto_subscribe
|
||||
&& is_private == l.is_private
|
||||
&& gxs_id == l.gxs_id;
|
||||
&& distant_chat_id == l.distant_chat_id;
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include "util/rsaes.h"
|
||||
#include "util/rsmemory.h"
|
||||
#include "util/rsprint.h"
|
||||
|
||||
#include <serialiser/rsmsgitems.h>
|
||||
|
||||
@ -90,6 +91,8 @@ bool DistantChatService::handleOutgoingItem(RsChatItem *item)
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cerr << " sending: " << RsUtil::BinToHex(mem,size) << std::endl;
|
||||
|
||||
mGxsTunnels->sendData( RsGxsTunnelId(item->PeerId()),DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID,mem,size);
|
||||
return true;
|
||||
}
|
||||
@ -108,18 +111,62 @@ void DistantChatService::handleRecvChatStatusItem(RsChatStatusItem *cs)
|
||||
void DistantChatService::notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId &tunnel_id, uint32_t tunnel_status)
|
||||
{
|
||||
std::cerr << "DistantChatService::notifyTunnelStatus(): got notification " << std::hex << tunnel_status << std::dec << " for tunnel " << tunnel_id << std::endl;
|
||||
#warning do something here
|
||||
|
||||
switch(tunnel_status)
|
||||
{
|
||||
default:
|
||||
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_UNKNOWN: std::cerr << "(EE) don't know how to handle RS_GXS_TUNNEL_STATUS_UNKNOWN !" << std::endl;
|
||||
break ;
|
||||
|
||||
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_CAN_TALK: RsServer::notify()->notifyChatStatus(ChatId(DistantChatPeerId(tunnel_id)),"Tunnel is secured. You can talk!") ;
|
||||
RsServer::notify()->notifyPeerStatusChanged(tunnel_id.toStdString(),RS_STATUS_ONLINE) ;
|
||||
break ;
|
||||
|
||||
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_TUNNEL_DN: RsServer::notify()->notifyChatStatus(ChatId(DistantChatPeerId(tunnel_id)),"tunnel is down...") ;
|
||||
RsServer::notify()->notifyPeerStatusChanged(tunnel_id.toStdString(),RS_STATUS_OFFLINE) ;
|
||||
break ;
|
||||
|
||||
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED: RsServer::notify()->notifyChatStatus(ChatId(DistantChatPeerId(tunnel_id)),"tunnel is down...") ;
|
||||
RsServer::notify()->notifyPeerStatusChanged(tunnel_id.toStdString(),RS_STATUS_OFFLINE) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
void DistantChatService::receiveData(const RsGxsTunnelService::RsGxsTunnelId &tunnel_id, unsigned char *data, uint32_t data_size)
|
||||
{
|
||||
std::cerr << "DistantChatService::receiveData(): got data of size " << data_size << " for tunnel " << tunnel_id << std::endl;
|
||||
#warning do something here
|
||||
std::cerr << " received: " << RsUtil::BinToHex(data,data_size) << std::endl;
|
||||
std::cerr << " deserialising..." << std::endl;
|
||||
|
||||
RsItem *item = RsChatSerialiser().deserialise(data,&data_size) ;
|
||||
|
||||
// always make the contact up to date. This is useful for server side, which doesn't know about the chat until it
|
||||
// receives the first item.
|
||||
{
|
||||
RS_STACK_MUTEX(mDistantChatMtx) ;
|
||||
|
||||
RsGxsTunnelService::GxsTunnelInfo tinfo;
|
||||
if(!mGxsTunnels->getTunnelInfo(tunnel_id,tinfo))
|
||||
return ;
|
||||
|
||||
DistantChatContact& contact(mDistantChatContacts[DistantChatPeerId(tunnel_id)]) ;
|
||||
|
||||
contact.to_id = tinfo.destination_gxs_id ;
|
||||
contact.from_id = tinfo.source_gxs_id ;
|
||||
}
|
||||
|
||||
if(item != NULL)
|
||||
{
|
||||
handleIncomingItem(item) ;
|
||||
RsServer::notify()->notifyListChange(NOTIFY_LIST_PRIVATE_INCOMING_CHAT, NOTIFY_TYPE_ADD);
|
||||
}
|
||||
else
|
||||
std::cerr << " (EE) item could not be deserialised!" << std::endl;
|
||||
}
|
||||
|
||||
void DistantChatService::markDistantChatAsClosed(const DistantChatPeerId& dcpid)
|
||||
{
|
||||
mGxsTunnels->closeExistingTunnel(RsGxsTunnelService::RsGxsTunnelId(dcpid)) ;
|
||||
mGxsTunnels->closeExistingTunnel(RsGxsTunnelService::RsGxsTunnelId(dcpid),DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID) ;
|
||||
|
||||
RS_STACK_MUTEX(mDistantChatMtx) ;
|
||||
|
||||
@ -132,10 +179,10 @@ void DistantChatService::markDistantChatAsClosed(const DistantChatPeerId& dcpid)
|
||||
bool DistantChatService::initiateDistantChatConnexion(const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, DistantChatPeerId& dcpid, uint32_t& error_code)
|
||||
{
|
||||
RsGxsTunnelId tunnel_id ;
|
||||
|
||||
if(!mGxsTunnels->requestSecuredTunnel(to_gxs_id,from_gxs_id,tunnel_id,error_code))
|
||||
|
||||
if(!mGxsTunnels->requestSecuredTunnel(to_gxs_id,from_gxs_id,tunnel_id,DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID,error_code))
|
||||
return false ;
|
||||
|
||||
|
||||
dcpid = DistantChatPeerId(tunnel_id) ;
|
||||
|
||||
DistantChatContact& dc_contact(mDistantChatContacts[dcpid]) ;
|
||||
@ -145,6 +192,14 @@ bool DistantChatService::initiateDistantChatConnexion(const RsGxsId& to_gxs_id,
|
||||
|
||||
error_code = RS_DISTANT_CHAT_ERROR_NO_ERROR ;
|
||||
|
||||
// Make a self message to raise 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(tunnel_id)) ;
|
||||
handleRecvChatMsgItem(item) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
@ -160,14 +215,26 @@ bool DistantChatService::getDistantChatStatus(const DistantChatPeerId& tunnel_id
|
||||
cinfo.to_id = tinfo.destination_gxs_id;
|
||||
cinfo.own_id = tinfo.source_gxs_id;
|
||||
cinfo.peer_id = tunnel_id;
|
||||
cinfo.status = tinfo.tunnel_status; // see the values in rsmsgs.h
|
||||
|
||||
switch(tinfo.tunnel_status)
|
||||
{
|
||||
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_CAN_TALK : cinfo.status = RS_DISTANT_CHAT_STATUS_CAN_TALK;
|
||||
break ;
|
||||
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_TUNNEL_DN: cinfo.status = RS_DISTANT_CHAT_STATUS_TUNNEL_DN ;
|
||||
break ;
|
||||
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED: cinfo.status = RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED ;
|
||||
break ;
|
||||
default:
|
||||
case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_UNKNOWN: cinfo.status = RS_DISTANT_CHAT_STATUS_UNKNOWN;
|
||||
break ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool DistantChatService::closeDistantChatConnexion(const DistantChatPeerId &tunnel_id)
|
||||
{
|
||||
mGxsTunnels->closeExistingTunnel(RsGxsTunnelId(tunnel_id)) ;
|
||||
mGxsTunnels->closeExistingTunnel(RsGxsTunnelId(tunnel_id), DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID) ;
|
||||
|
||||
// also remove contact. Or do we wait for the notification?
|
||||
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
// So, public interface only uses DistandChatPeerId, but internally, this is converted into a RsGxsTunnelService::RsGxsTunnelId
|
||||
|
||||
|
||||
DistantChatService(RsGixs *pids) : mDistantChatMtx("distant chat")
|
||||
DistantChatService() : mDistantChatMtx("distant chat")
|
||||
{
|
||||
mGxsTunnels = NULL ;
|
||||
}
|
||||
@ -56,7 +56,7 @@ public:
|
||||
|
||||
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 ;
|
||||
|
||||
|
@ -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() ;
|
||||
|
||||
@ -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
|
||||
{
|
||||
@ -286,7 +287,6 @@ bool p3ChatService::isOnline(const RsPeerId& pid)
|
||||
{
|
||||
// check if the id is a tunnel id or a peer id.
|
||||
|
||||
uint32_t status ;
|
||||
DistantChatPeerInfo dcpinfo;
|
||||
|
||||
if(getDistantChatStatus(DistantChatPeerId(pid),dcpinfo))
|
||||
@ -304,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;
|
||||
@ -316,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();
|
||||
|
||||
@ -769,7 +769,6 @@ 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.
|
||||
@ -820,7 +819,6 @@ void p3ChatService::initChatMessage(RsChatMsgItem *c, ChatMessage &m)
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t status;
|
||||
DistantChatPeerInfo dcpinfo;
|
||||
if(DistantChatService::getDistantChatStatus(DistantChatPeerId(c->PeerId()), dcpinfo))
|
||||
m.chat_id = ChatId(DistantChatPeerId(c->PeerId()));
|
||||
|
@ -113,6 +113,8 @@ int p3GxsTunnelService::tick()
|
||||
}
|
||||
|
||||
flush() ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
RsServiceInfo p3GxsTunnelService::getServiceInfo()
|
||||
@ -199,8 +201,8 @@ void p3GxsTunnelService::flush()
|
||||
{
|
||||
RsGxsTunnelStatusItem *cs = new RsGxsTunnelStatusItem ;
|
||||
|
||||
cs->flags = RS_GXS_TUNNEL_FLAG_KEEP_ALIVE;
|
||||
cs->PeerId(it->second.virtual_peer_id) ;
|
||||
cs->status = RS_GXS_TUNNEL_FLAG_KEEP_ALIVE;
|
||||
cs->PeerId(RsPeerId(it->first)) ;
|
||||
|
||||
// we send off-mutex to avoid deadlock.
|
||||
|
||||
@ -274,7 +276,7 @@ void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id
|
||||
RsGxsTunnelDataAckItem *ackitem = new RsGxsTunnelDataAckItem ;
|
||||
|
||||
ackitem->unique_item_counter = item->unique_item_counter ;
|
||||
ackitem->PeerId(item->PeerId());
|
||||
ackitem->PeerId(RsPeerId(tunnel_id)) ;
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||
@ -299,6 +301,11 @@ void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id
|
||||
return ;
|
||||
}
|
||||
service = it->second ;
|
||||
|
||||
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it2 = _gxs_tunnel_contacts.find(tunnel_id) ;
|
||||
|
||||
if(it2 != _gxs_tunnel_contacts.end())
|
||||
it2->second.client_services.insert(item->service_id) ;
|
||||
}
|
||||
|
||||
service->receiveData(tunnel_id,item->data,item->data_size) ;
|
||||
@ -309,13 +316,84 @@ void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id
|
||||
|
||||
void p3GxsTunnelService::handleRecvStatusItem(const RsGxsTunnelId& tunnel_id, RsGxsTunnelStatusItem *cs)
|
||||
{
|
||||
if(cs->flags & RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION)
|
||||
markGxsTunnelAsClosed(tunnel_id);
|
||||
std::vector<uint32_t> notifications ;
|
||||
std::set<RsGxsTunnelClientService*> clients ;
|
||||
|
||||
// nothing more to do, because the decryption routing will update the last_contact time when decrypting.
|
||||
std::cerr << "p3GxsTunnelService::handleRecvStatusItem(): tunnel_id=" << tunnel_id << " status=" << cs->status << std::endl;
|
||||
|
||||
if(cs->flags & RS_GXS_TUNNEL_FLAG_KEEP_ALIVE)
|
||||
std::cerr << "GxsTunnelService::handleRecvGxsTunnelStatusItem(): received keep alive packet for inactive tunnel! peerId=" << cs->PeerId() << " tunnel=" << tunnel_id << std::endl;
|
||||
switch(cs->status)
|
||||
{
|
||||
case RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION:
|
||||
{
|
||||
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ;
|
||||
|
||||
if(it == _gxs_tunnel_contacts.end())
|
||||
{
|
||||
std::cerr << "(EE) Cannot mark tunnel connection as closed. No connection openned for tunnel id " << tunnel_id << ". Unexpected situation." << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
if(it->second.direction == RsTurtleGenericDataItem::DIRECTION_CLIENT)
|
||||
{
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << " This is server side. Marking distant chat as remotely closed for tunnel id " << tunnel_id << std::endl;
|
||||
#endif
|
||||
it->second.status = RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED ;
|
||||
notifications.push_back(RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED) ;
|
||||
}
|
||||
} // nothing more to do, because the decryption routing will update the last_contact time when decrypting.
|
||||
break ;
|
||||
|
||||
case RS_GXS_TUNNEL_FLAG_KEEP_ALIVE:
|
||||
std::cerr << "GxsTunnelService::handleRecvGxsTunnelStatusItem(): received keep alive packet for inactive tunnel! peerId=" << cs->PeerId() << " tunnel=" << tunnel_id << std::endl;
|
||||
break ;
|
||||
|
||||
case RS_GXS_TUNNEL_FLAG_ACK_DISTANT_CONNECTION:
|
||||
{
|
||||
std::cerr << "Received ACK item from the distant peer!" << std::endl;
|
||||
|
||||
// in this case we notify the clients using this tunnel.
|
||||
|
||||
notifications.push_back(RS_GXS_TUNNEL_STATUS_CAN_TALK) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
default:
|
||||
std::cerr << "(EE) unhandled tunnel status " << std::hex << cs->status << std::dec << std::endl;
|
||||
break ;
|
||||
}
|
||||
|
||||
// notify all clients
|
||||
|
||||
std::cerr << " notifying clients. Prending notifications: " << notifications.size() << std::endl;
|
||||
|
||||
if(notifications.size() > 0)
|
||||
{
|
||||
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ;
|
||||
|
||||
std::cerr << " " << it->second.client_services.size() << " client services for tunnel id " << tunnel_id << std::endl;
|
||||
|
||||
for(std::set<uint32_t>::const_iterator it2(it->second.client_services.begin());it2!=it->second.client_services.end();++it2)
|
||||
{
|
||||
std::map<uint32_t,RsGxsTunnelClientService*>::const_iterator it3=mRegisteredServices.find(*it2) ;
|
||||
|
||||
if(it3 != mRegisteredServices.end())
|
||||
clients.insert(it3->second) ;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << " notifying " << clients.size() << " clients." << std::endl;
|
||||
|
||||
for(std::set<RsGxsTunnelClientService*>::const_iterator it(clients.begin());it!=clients.end();++it)
|
||||
for(uint32_t i=0;i<notifications.size();++i)
|
||||
{
|
||||
(*it)->notifyTunnelStatus(tunnel_id,notifications[i]) ;
|
||||
std::cerr << " notifying client " << (void*)(*it) << " of status " << notifications[i] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
bool p3GxsTunnelService::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& /*peer_id*/)
|
||||
@ -435,6 +513,8 @@ void p3GxsTunnelService::locked_restartDHSession(const RsPeerId& virtual_peer_id
|
||||
void p3GxsTunnelService::removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id)
|
||||
{
|
||||
bool tunnel_dn = false ;
|
||||
std::set<RsGxsTunnelClientService*> client_services ;
|
||||
RsGxsTunnelId tunnel_id ;
|
||||
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << "GxsTunnelService: Removing virtual peer " << virtual_peer_id << " for hash " << hash << std::endl;
|
||||
@ -454,7 +534,7 @@ void p3GxsTunnelService::removeVirtualPeer(const TurtleFileHash& hash,const Turt
|
||||
return ;
|
||||
}
|
||||
|
||||
RsGxsTunnelId tunnel_id = it->second.tunnel_id ;
|
||||
tunnel_id = it->second.tunnel_id ;
|
||||
|
||||
if(it->second.dh != NULL)
|
||||
DH_free(it->second.dh) ;
|
||||
@ -474,13 +554,22 @@ void p3GxsTunnelService::removeVirtualPeer(const TurtleFileHash& hash,const Turt
|
||||
it2->second.virtual_peer_id.clear() ;
|
||||
tunnel_dn = true ;
|
||||
}
|
||||
|
||||
for(std::set<uint32_t>::const_iterator it(it2->second.client_services.begin());it!=it2->second.client_services.end();++it)
|
||||
{
|
||||
std::map<uint32_t,RsGxsTunnelClientService*>::const_iterator it2 = mRegisteredServices.find(*it) ;
|
||||
|
||||
if(it2 != mRegisteredServices.end())
|
||||
client_services.insert(it2->second) ;
|
||||
}
|
||||
}
|
||||
|
||||
if(tunnel_dn)
|
||||
{
|
||||
#warning we should notify the client here
|
||||
//RsServer::notify()->notifyChatStatus(ChatId(RsGxsId(virtual_peer_id)),"tunnel is down...") ;
|
||||
//RsServer::notify()->notifyPeerStatusChanged(virtual_peer_id.toStdString(),RS_STATUS_OFFLINE) ;
|
||||
// notify all client services that this tunnel is down
|
||||
|
||||
for(std::set<RsGxsTunnelClientService*>::const_iterator it(client_services.begin());it!=client_services.end();++it)
|
||||
(*it)->notifyTunnelStatus(tunnel_id,RS_GXS_TUNNEL_STATUS_TUNNEL_DN) ;
|
||||
}
|
||||
}
|
||||
|
||||
@ -824,8 +913,8 @@ void p3GxsTunnelService::handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item)
|
||||
|
||||
RsGxsTunnelStatusItem *cs = new RsGxsTunnelStatusItem ;
|
||||
|
||||
cs->flags = RS_GXS_TUNNEL_FLAG_ACK_DISTANT_CONNECTION;
|
||||
cs->PeerId(vpid) ;
|
||||
cs->status = RS_GXS_TUNNEL_FLAG_ACK_DISTANT_CONNECTION;
|
||||
cs->PeerId(RsPeerId(tunnel_id)) ;
|
||||
|
||||
pendingGxsTunnelItems.push_back(cs) ;
|
||||
}
|
||||
@ -958,7 +1047,9 @@ bool p3GxsTunnelService::locked_initDHSessionKey(DH *& dh)
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Encrypts and sends the item.
|
||||
// Sends the item in clear. This is only used for DH key exchange.
|
||||
// in this case only, the item's PeerId is equal to the virtual peer Id for the tunnel,
|
||||
// since we ight not now the tunnel id yet.
|
||||
|
||||
bool p3GxsTunnelService::locked_sendClearTunnelData(RsGxsTunnelDHPublicKeyItem *item)
|
||||
{
|
||||
@ -1013,27 +1104,21 @@ bool p3GxsTunnelService::locked_sendEncryptedTunnelData(RsGxsTunnelItem *item)
|
||||
uint64_t IV = 0;
|
||||
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << "Sending encrypted data to tunnel wuth vpid " << item->PeerId() << std::endl;
|
||||
std::cerr << "Sending encrypted data to tunnel with vpid " << item->PeerId() << std::endl;
|
||||
#endif
|
||||
TurtleVirtualPeerId vpid = item->PeerId() ;
|
||||
|
||||
RsGxsTunnelId tunnel_id ( item->PeerId() );
|
||||
|
||||
std::map<TurtleVirtualPeerId,GxsTunnelDHInfo>::const_iterator it2 = _gxs_tunnel_virtual_peer_ids.find(vpid) ;
|
||||
if(it2 == _gxs_tunnel_virtual_peer_ids.end())
|
||||
{
|
||||
std::cerr << "(EE) no virtual peer " << vpid << ". Something's wrong!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(it2->second.tunnel_id) ;
|
||||
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ;
|
||||
|
||||
if(it == _gxs_tunnel_contacts.end())
|
||||
{
|
||||
std::cerr << "(EE) Cannot find contact key info for virtual peer id " << vpid << ". Cannot send message!" << std::endl;
|
||||
std::cerr << "(EE) Cannot find contact key info for tunnel id " << tunnel_id << ". Cannot send message!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if(it->second.status != RS_GXS_TUNNEL_STATUS_CAN_TALK)
|
||||
{
|
||||
std::cerr << "(EE) Cannot talk to vpid " << vpid << ". Tunnel status is: " << it->second.status << std::endl;
|
||||
std::cerr << "(EE) Cannot talk to tunnel id " << tunnel_id << ". Tunnel status is: " << it->second.status << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1075,7 +1160,7 @@ bool p3GxsTunnelService::locked_sendEncryptedTunnelData(RsGxsTunnelItem *item)
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl;
|
||||
std::cerr << " Using Key: " << RsUtil::BinToHex((char*)aes_key,GXS_TUNNEL_AES_KEY_SIZE) ; std::cerr << std::endl;
|
||||
std::cerr << " hmac: " << RsUtil::BinToHex((char*)gitem->data_bytes,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) ;
|
||||
std::cerr << " hmac: " << RsUtil::BinToHex((char*)gitem->data_bytes,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) << std::endl;
|
||||
#endif
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << "GxsTunnelService::sendEncryptedTunnelData(): Sending encrypted data to virtual peer: " << virtual_peer_id << std::endl;
|
||||
@ -1089,7 +1174,7 @@ bool p3GxsTunnelService::locked_sendEncryptedTunnelData(RsGxsTunnelItem *item)
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool p3GxsTunnelService::requestSecuredTunnel(const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, RsGxsTunnelId &tunnel_id, uint32_t& error_code)
|
||||
bool p3GxsTunnelService::requestSecuredTunnel(const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, RsGxsTunnelId &tunnel_id, uint32_t service_id, uint32_t& error_code)
|
||||
{
|
||||
// should be a parameter.
|
||||
|
||||
@ -1112,7 +1197,7 @@ bool p3GxsTunnelService::requestSecuredTunnel(const RsGxsId& to_gxs_id, const Rs
|
||||
}
|
||||
RsGxsId own_gxs_id = from_gxs_id ;
|
||||
|
||||
startClientGxsTunnelConnection(to_gxs_id,own_gxs_id,tunnel_id) ;
|
||||
startClientGxsTunnelConnection(to_gxs_id,own_gxs_id,service_id,tunnel_id) ;
|
||||
|
||||
error_code = RS_GXS_TUNNEL_ERROR_NO_ERROR ;
|
||||
|
||||
@ -1155,6 +1240,7 @@ bool p3GxsTunnelService::sendData(const RsGxsTunnelId &tunnel_id, uint32_t servi
|
||||
item->service_id = service_id;
|
||||
item->data_size = size; // encrypted data size
|
||||
item->data = (uint8_t*)malloc(size); // encrypted data
|
||||
item->PeerId(RsPeerId(tunnel_id)) ;
|
||||
memcpy(item->data,data,size) ;
|
||||
|
||||
GxsTunnelData& tdata( pendingGxsTunnelDataItems[item->unique_item_counter] ) ;
|
||||
@ -1168,7 +1254,7 @@ bool p3GxsTunnelService::sendData(const RsGxsTunnelId &tunnel_id, uint32_t servi
|
||||
}
|
||||
|
||||
|
||||
void p3GxsTunnelService::startClientGxsTunnelConnection(const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id,RsGxsTunnelId& tunnel_id)
|
||||
void p3GxsTunnelService::startClientGxsTunnelConnection(const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id,uint32_t service_id,RsGxsTunnelId& tunnel_id)
|
||||
{
|
||||
// compute a random hash for that pair, and init the DH session for it so that we can recognise it when we get the virtual peer for it.
|
||||
|
||||
@ -1198,6 +1284,7 @@ void p3GxsTunnelService::startClientGxsTunnelConnection(const RsGxsId& to_gxs_id
|
||||
info.hash = hash ;
|
||||
info.direction = RsTurtleGenericTunnelItem::DIRECTION_SERVER ;
|
||||
info.virtual_peer_id.clear();
|
||||
info.client_services.insert(service_id) ;
|
||||
|
||||
memset(info.aes_key,0,GXS_TUNNEL_AES_KEY_SIZE) ;
|
||||
|
||||
@ -1222,8 +1309,6 @@ TurtleFileHash p3GxsTunnelService::randomHashFromDestinationGxsId(const RsGxsId&
|
||||
// This is in prevision for the "secured GXS tunnel" service, which will need a service ID to register,
|
||||
// just like GRouter does.
|
||||
|
||||
static const uint32_t client = RS_SERVICE_TYPE_GXS_TUNNEL ;
|
||||
|
||||
assert( destination.SIZE_IN_BYTES == 16) ;
|
||||
assert(Sha1CheckSum::SIZE_IN_BYTES == 20) ;
|
||||
|
||||
@ -1289,7 +1374,7 @@ bool p3GxsTunnelService::getTunnelStatus(const RsGxsTunnelId& tunnel_id,uint32_t
|
||||
return false ;
|
||||
}
|
||||
|
||||
bool p3GxsTunnelService::closeExistingTunnel(const RsGxsTunnelId& tunnel_id)
|
||||
bool p3GxsTunnelService::closeExistingTunnel(const RsGxsTunnelId& tunnel_id, uint32_t service_id)
|
||||
{
|
||||
// two cases:
|
||||
// - client needs to stop asking for tunnels => remove the hash from the list of tunnelled files
|
||||
@ -1298,9 +1383,10 @@ bool p3GxsTunnelService::closeExistingTunnel(const RsGxsTunnelId& tunnel_id)
|
||||
|
||||
TurtleFileHash hash ;
|
||||
TurtleVirtualPeerId vpid ;
|
||||
bool close_tunnel = false ;
|
||||
{
|
||||
RsStackMutex stack(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::const_iterator it = _gxs_tunnel_contacts.find(tunnel_id) ;
|
||||
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ;
|
||||
|
||||
if(it == _gxs_tunnel_contacts.end())
|
||||
{
|
||||
@ -1319,16 +1405,34 @@ bool p3GxsTunnelService::closeExistingTunnel(const RsGxsTunnelId& tunnel_id)
|
||||
|
||||
if(it2 != _gxs_tunnel_virtual_peer_ids.end())
|
||||
hash = it2->second.hash ;
|
||||
|
||||
// check how many clients are used. If empty, close the tunnel
|
||||
|
||||
std::set<uint32_t>::iterator it3 = it->second.client_services.find(service_id) ;
|
||||
|
||||
if(it3 == it->second.client_services.end())
|
||||
{
|
||||
std::cerr << "(EE) service id not currently using that tunnel. This is an error." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
it->second.client_services.erase(it3) ;
|
||||
|
||||
if(it->second.client_services.empty())
|
||||
close_tunnel = true ;
|
||||
}
|
||||
|
||||
if(!close_tunnel)
|
||||
return true ;
|
||||
|
||||
// send a status item saying that we're closing the connection
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << " Sending a ACK to close the tunnel since we're managing it. tunnel id=." << tunnel_id << std::endl;
|
||||
std::cerr << " Sending a ACK to close the tunnel since we're managing it and it's not used by any service. tunnel id=." << tunnel_id << std::endl;
|
||||
#endif
|
||||
|
||||
RsGxsTunnelStatusItem *cs = new RsGxsTunnelStatusItem ;
|
||||
|
||||
cs->flags = RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION;
|
||||
cs->status = RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION;
|
||||
cs->PeerId(vpid) ;
|
||||
|
||||
locked_sendEncryptedTunnelData(cs) ; // that needs to be done off-mutex and before we close the tunnel also ignoring failure.
|
||||
@ -1354,27 +1458,6 @@ bool p3GxsTunnelService::closeExistingTunnel(const RsGxsTunnelId& tunnel_id)
|
||||
return true ;
|
||||
}
|
||||
|
||||
void p3GxsTunnelService::markGxsTunnelAsClosed(const RsGxsTunnelId& tunnel_id)
|
||||
{
|
||||
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ;
|
||||
|
||||
if(it == _gxs_tunnel_contacts.end())
|
||||
{
|
||||
std::cerr << "(EE) Cannot mark distant chat connection as closed. No connection openned for tunnel id " << tunnel_id << ". Unexpected situation." << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
if(it->second.direction == RsTurtleGenericDataItem::DIRECTION_CLIENT)
|
||||
{
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << " This is server side. Marking distant chat as remotely closed for tunnel id " << tunnel_id << std::endl;
|
||||
#endif
|
||||
it->second.status = RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED ;
|
||||
}
|
||||
}
|
||||
|
||||
void p3GxsTunnelService::debug_dump()
|
||||
{
|
||||
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||
|
@ -45,7 +45,7 @@
|
||||
//
|
||||
// Interaction with services:
|
||||
//
|
||||
// Services request tunnels from a given GXS id and to a given GXS id. When ready, they get a handle (virtual peer id)
|
||||
// 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
|
||||
//
|
||||
@ -56,6 +56,18 @@
|
||||
//
|
||||
// Tunnel establishment
|
||||
// * 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 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)
|
||||
@ -80,22 +92,22 @@
|
||||
//
|
||||
|
||||
//
|
||||
// RequestTunnel(source_own_id,destination_id)
|
||||
// |
|
||||
// +---------------------------> p3Turtle::monitorTunnels( hash(destination_id) )
|
||||
// |
|
||||
// [Turtle async work] -------------------+
|
||||
// | |
|
||||
// handleTunnelRequest() <-----------------------------------------------+ |
|
||||
// | |
|
||||
// +---------------- keep record in _gxs_tunnel_virtual_peer_id, initiate DH exchange |
|
||||
// |
|
||||
// handleDHPublicKey() <-----------------------------------------------------------------------------+
|
||||
// |
|
||||
// +---------------- update _gxs_tunnel_contacts[ tunnel_hash = hash(own_id, destination_id) ]
|
||||
// |
|
||||
// +---------------- notify client service that Peer(destination_id, tunnel_hash) is ready to talk to
|
||||
//
|
||||
// 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 |
|
||||
// -
|
||||
// Notes
|
||||
// * one other option would be to make the turtle hash depend on both GXS ids in a way that it is possible to find which are the two ids on the server side.
|
||||
// but that would prevent the use of unknown IDs, which we would like to offer as well.
|
||||
@ -123,9 +135,9 @@ public:
|
||||
// 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& error_code) ;
|
||||
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) ;
|
||||
virtual bool closeExistingTunnel(const RsGxsTunnelId &tunnel_id,uint32_t service_id) ;
|
||||
virtual bool getTunnelStatus(const RsGxsTunnelId& tunnel_id,uint32_t &status);
|
||||
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) ;
|
||||
@ -160,6 +172,7 @@ private:
|
||||
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
|
||||
};
|
||||
|
||||
class GxsTunnelDHInfo
|
||||
@ -203,8 +216,7 @@ private:
|
||||
|
||||
// session handling handles
|
||||
|
||||
void markGxsTunnelAsClosed(const RsGxsTunnelId &tunnel_id) ;
|
||||
void startClientGxsTunnelConnection(const RsGxsId &to_gxs_id, const RsGxsId& from_gxs_id, RsGxsTunnelId &tunnel_id) ;
|
||||
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
|
||||
|
@ -79,7 +79,7 @@ std::ostream& RsGxsTunnelStatusItem::print(std::ostream &out, uint16_t indent)
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << " flags : " << std::hex << flags << std::dec << std::endl ;
|
||||
out << " flags : " << std::hex << status << std::dec << std::endl ;
|
||||
|
||||
printRsItemEnd(out, "RsGxsTunnelStatusItem", indent);
|
||||
return out;
|
||||
@ -235,7 +235,7 @@ bool RsGxsTunnelStatusItem::serialise(void *data, uint32_t& pktsize)
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, flags);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, status);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
@ -249,7 +249,7 @@ bool RsGxsTunnelStatusItem::serialise(void *data, uint32_t& pktsize)
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RsGxsTunnelDataItem::serialise(void *data, uint32_t& pktsize)
|
||||
bool RsGxsTunnelDataItem::serialise(void *dt, uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size() ;
|
||||
uint32_t offset = 0;
|
||||
@ -261,7 +261,7 @@ bool RsGxsTunnelDataItem::serialise(void *data, uint32_t& pktsize)
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize);
|
||||
ok &= setRsItemHeader(dt, tlvsize, PacketId(), tlvsize);
|
||||
|
||||
#ifdef GXS_TUNNEL_ITEM_DEBUG
|
||||
std::cerr << "RsGxsTunnelSerialiser serialising chat status item." << std::endl;
|
||||
@ -273,14 +273,14 @@ bool RsGxsTunnelDataItem::serialise(void *data, uint32_t& pktsize)
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= setRawUInt64(data, tlvsize, &offset, unique_item_counter);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, flags);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, service_id);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, data_size);
|
||||
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*)data)[offset],data,data_size) ;
|
||||
memcpy(&((uint8_t*)dt)[offset],data,data_size) ;
|
||||
offset += data_size ;
|
||||
}
|
||||
else
|
||||
@ -451,7 +451,7 @@ RsGxsTunnelStatusItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelStatusItem(
|
||||
|
||||
/* get mandatory parts first */
|
||||
|
||||
ok &= getRawUInt32(dat, rssize, &offset, &item->flags);
|
||||
ok &= getRawUInt32(dat, rssize, &offset, &item->status);
|
||||
|
||||
if (offset != rssize)
|
||||
{
|
||||
|
@ -105,7 +105,7 @@ class RsGxsTunnelStatusItem: public RsGxsTunnelItem
|
||||
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 flags ;
|
||||
uint32_t status ;
|
||||
};
|
||||
|
||||
// Used to confirm reception of an encrypted item.
|
||||
|
@ -208,7 +208,7 @@ p3Config::p3Config()
|
||||
}
|
||||
|
||||
|
||||
bool p3Config::loadConfiguration(RsFileHash &loadHash)
|
||||
bool p3Config::loadConfiguration(RsFileHash& /* loadHash */)
|
||||
{
|
||||
return loadConfig();
|
||||
}
|
||||
|
@ -99,17 +99,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;
|
||||
DistantChatPeerInfo dcpinfo;
|
||||
if (rsMsgs->getDistantChatStatus(cm.chat_id.toPeerId(), dcpinfo))
|
||||
peerName = cm.chat_id.toPeerId().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;
|
||||
@ -397,8 +394,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;
|
||||
}
|
||||
|
||||
@ -436,7 +433,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;
|
||||
}
|
||||
|
||||
|
@ -33,16 +33,20 @@
|
||||
class RsGxsTunnelService
|
||||
{
|
||||
public:
|
||||
static const uint32_t RS_GXS_TUNNEL_ERROR_NO_ERROR = 0x0000 ;
|
||||
static const uint32_t RS_GXS_TUNNEL_ERROR_UNKNOWN_GXS_ID = 0x0001 ;
|
||||
|
||||
static const uint32_t RS_GXS_TUNNEL_STATUS_UNKNOWN = 0x00 ;
|
||||
static const uint32_t RS_GXS_TUNNEL_STATUS_CAN_TALK = 0x01 ;
|
||||
static const uint32_t RS_GXS_TUNNEL_STATUS_TUNNEL_DN = 0x02 ;
|
||||
static const uint32_t RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED = 0x03 ;
|
||||
|
||||
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:
|
||||
@ -102,8 +106,9 @@ public:
|
||||
// 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& error_code) =0 ;
|
||||
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.
|
||||
@ -113,7 +118,7 @@ public:
|
||||
// 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) =0;
|
||||
virtual bool closeExistingTunnel(const RsGxsTunnelId& to_id,uint32_t service_id) =0;
|
||||
|
||||
//===================================================//
|
||||
// Routage feedback from other services //
|
||||
|
@ -209,16 +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_GXS_TUNNEL_ID_TYPE = 0x0010 ;
|
||||
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 ;
|
||||
@ -229,4 +230,5 @@ typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_G
|
||||
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,8 +99,6 @@ typedef uint64_t ChatLobbyId ;
|
||||
typedef uint64_t ChatLobbyMsgId ;
|
||||
typedef std::string ChatLobbyNickName ;
|
||||
|
||||
typedef RsPeerId DistantChatPeerId ;
|
||||
|
||||
typedef uint64_t MessageId ;
|
||||
|
||||
|
||||
@ -254,10 +252,8 @@ public:
|
||||
|
||||
#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_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
|
||||
@ -285,6 +281,7 @@ public:
|
||||
explicit ChatId(RsPeerId id);
|
||||
explicit ChatId(RsGxsId id);
|
||||
explicit ChatId(ChatLobbyId id);
|
||||
explicit ChatId(DistantChatPeerId id);
|
||||
explicit ChatId(std::string str);
|
||||
static ChatId makeBroadcastId();
|
||||
|
||||
@ -296,13 +293,15 @@ public:
|
||||
|
||||
bool isNotSet() const;
|
||||
bool isPeerId() const;
|
||||
bool isGxsId() const;
|
||||
bool isDistantChatId() const;
|
||||
bool isLobbyId() const;
|
||||
bool isGxsId() 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,
|
||||
@ -313,13 +312,15 @@ private:
|
||||
TYPE_PRIVATE, // private chat with directly connected friend, peer_id is valid
|
||||
TYPE_PRIVATE_DISTANT, // private chat with distant peer, gxs_id is valid
|
||||
TYPE_LOBBY, // chat lobby id, lobby_id is valid
|
||||
TYPE_GXS_ID, //
|
||||
TYPE_BROADCAST // message to/from all connected peers
|
||||
};
|
||||
|
||||
Type type;
|
||||
RsPeerId peer_id;
|
||||
RsGxsId gxs_id;
|
||||
DistantChatPeerId distant_chat_id;
|
||||
ChatLobbyId lobby_id;
|
||||
RsGxsId gxs_id;
|
||||
};
|
||||
|
||||
class ChatMessage
|
||||
|
@ -58,6 +58,13 @@ ChatId::ChatId():
|
||||
|
||||
}
|
||||
|
||||
ChatId::ChatId(RsGxsId id):
|
||||
lobby_id(0)
|
||||
{
|
||||
type = TYPE_GXS_ID;
|
||||
gxs_id = id;
|
||||
}
|
||||
|
||||
ChatId::ChatId(RsPeerId id):
|
||||
lobby_id(0)
|
||||
{
|
||||
@ -65,11 +72,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 +100,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 +150,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 +193,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 +217,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 +236,7 @@ bool ChatId::isPeerId() const
|
||||
{
|
||||
return type == TYPE_PRIVATE;
|
||||
}
|
||||
bool ChatId::isGxsId() const
|
||||
bool ChatId::isDistantChatId() const
|
||||
{
|
||||
return type == TYPE_PRIVATE_DISTANT;
|
||||
}
|
||||
@ -237,6 +244,10 @@ bool ChatId::isLobbyId() const
|
||||
{
|
||||
return type == TYPE_LOBBY;
|
||||
}
|
||||
bool ChatId::isGxsId() const
|
||||
{
|
||||
return type == TYPE_GXS_ID;
|
||||
}
|
||||
bool ChatId::isBroadcast() const
|
||||
{
|
||||
return type == TYPE_BROADCAST;
|
||||
@ -251,16 +262,27 @@ RsPeerId ChatId::toPeerId() const
|
||||
return RsPeerId();
|
||||
}
|
||||
}
|
||||
|
||||
RsGxsId ChatId::toGxsId() const
|
||||
{
|
||||
if(type == TYPE_PRIVATE_DISTANT)
|
||||
if(type == TYPE_GXS_ID)
|
||||
return gxs_id;
|
||||
else
|
||||
{
|
||||
std::cerr << "ChatId Warning: conversation to RsGxsId requested, but type is different. Current value=\"" << toStdString() << "\"" << std::endl;
|
||||
std::cerr << "ChatId Warning: conversation to gxs_id requested, but type is different. Current value=\"" << toStdString() << "\"" << std::endl;
|
||||
return RsGxsId();
|
||||
}
|
||||
}
|
||||
DistantChatPeerId ChatId::toDistantChatId() const
|
||||
{
|
||||
if(type == TYPE_PRIVATE_DISTANT)
|
||||
return distant_chat_id;
|
||||
else
|
||||
{
|
||||
std::cerr << "ChatId Warning: conversation to DistantChatPeerId requested, but type is different. Current value=\"" << toStdString() << "\"" << std::endl;
|
||||
return DistantChatPeerId();
|
||||
}
|
||||
}
|
||||
ChatLobbyId ChatId::toLobbyId() const
|
||||
{
|
||||
if(type == TYPE_LOBBY)
|
||||
|
@ -266,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
|
||||
|
@ -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
|
||||
|
@ -93,11 +93,10 @@ void ChatDialog::init(ChatId id, const QString &title)
|
||||
|
||||
/* see if it already exists */
|
||||
ChatDialog *cd = getExistingChat(id);
|
||||
DistantChatPeerInfo pinfo ;
|
||||
|
||||
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) {
|
||||
@ -106,10 +105,11 @@ void ChatDialog::init(ChatId id, const QString &title)
|
||||
cld->init();
|
||||
cd = cld;
|
||||
}
|
||||
else if(id.isPeerId() && rsMsgs->getDistantChatStatus(id.toPeerId(),pinfo))
|
||||
else if(id.isDistantChatId())
|
||||
{
|
||||
PopupDistantChatDialog* pdcd = new PopupDistantChatDialog(id.toPeerId());
|
||||
pdcd->init(pinfo.peer_id, QString("This is a distant chat")) ;
|
||||
PopupDistantChatDialog* pdcd = new PopupDistantChatDialog(id.toDistantChatId());
|
||||
|
||||
pdcd->init(id.toDistantChatId());
|
||||
cd = pdcd;
|
||||
}
|
||||
else
|
||||
@ -172,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);
|
||||
|
||||
@ -338,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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -249,7 +249,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);
|
||||
@ -328,7 +328,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());
|
||||
@ -360,7 +361,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;
|
||||
@ -1501,77 +1502,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
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ PopupDistantChatDialog::PopupDistantChatDialog(const DistantChatPeerId& tunnel_i
|
||||
updateDisplay() ;
|
||||
}
|
||||
|
||||
void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id, const QString &title)
|
||||
void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id)
|
||||
{
|
||||
_tunnel_id = peer_id;
|
||||
DistantChatPeerInfo tinfo;
|
||||
@ -68,12 +68,18 @@ void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id, const QStrin
|
||||
if(!rsMsgs->getDistantChatStatus(_tunnel_id,tinfo))
|
||||
return ;
|
||||
|
||||
PopupChatDialog::init(ChatId(tinfo.to_id), title) ;
|
||||
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())) ;
|
||||
|
||||
// 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.
|
||||
|
||||
ui.ownAvatarWidget->setId(ChatId(tinfo.own_id));
|
||||
ui.ownAvatarWidget->setOwnId() ; // sets the flag
|
||||
ui.ownAvatarWidget->setId(ChatId(peer_id)) ; // sets the actual Id
|
||||
}
|
||||
|
||||
void PopupDistantChatDialog::updateDisplay()
|
||||
@ -91,7 +97,7 @@ void PopupDistantChatDialog::updateDisplay()
|
||||
DistantChatPeerInfo tinfo;
|
||||
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
|
||||
|
||||
ui.avatarWidget->setId(ChatId(tinfo.to_id));
|
||||
ui.avatarWidget->setId(ChatId(_tunnel_id));
|
||||
|
||||
QString msg;
|
||||
switch(tinfo.status)
|
||||
|
@ -38,7 +38,7 @@ class PopupDistantChatDialog: public PopupChatDialog
|
||||
/** Default destructor */
|
||||
virtual ~PopupDistantChatDialog();
|
||||
|
||||
virtual void init(const DistantChatPeerId& peer_id, const QString &title);
|
||||
virtual void init(const DistantChatPeerId& peer_id);
|
||||
virtual void closeEvent(QCloseEvent *e) ;
|
||||
|
||||
virtual QString getPeerName(const ChatId &id) const ;
|
||||
|
@ -124,8 +124,6 @@ void AvatarWidget::setFrameType(FrameType type)
|
||||
void AvatarWidget::setId(const ChatId &id)
|
||||
{
|
||||
mId = id;
|
||||
// mPgpId = rsPeers->getGPGId(id) ;
|
||||
// mFlag.isGpg = false ;
|
||||
|
||||
setPixmap(QPixmap());
|
||||
|
||||
@ -133,15 +131,12 @@ void AvatarWidget::setId(const ChatId &id)
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
if(mId.isGxsId())
|
||||
std::cerr << "(EE) AvatarWidget should not be set to a GXS id." << std::endl;
|
||||
|
||||
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 +176,7 @@ void AvatarWidget::refreshStatus()
|
||||
rsStatus->getOwnStatus(statusInfo);
|
||||
status = statusInfo.status ;
|
||||
}
|
||||
else if(mId.isGxsId())
|
||||
else if(mId.isDistantChatId())
|
||||
status = RS_STATUS_ONLINE ;
|
||||
else
|
||||
{
|
||||
@ -198,12 +193,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 ;
|
||||
#warning we need to do something clever here
|
||||
}
|
||||
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;
|
||||
@ -236,10 +234,11 @@ 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()
|
||||
{
|
||||
@ -263,12 +262,29 @@ void AvatarWidget::refreshAvatarImage()
|
||||
setPixmap(avatar);
|
||||
return;
|
||||
}
|
||||
else if (mId.isGxsId())
|
||||
// else if (mId.isGxsId())
|
||||
// {
|
||||
// QPixmap avatar;
|
||||
//
|
||||
// AvatarDefs::getAvatarFromGxsId(mId.toGxsId(), avatar, defaultAvatar);
|
||||
// setPixmap(avatar);
|
||||
// return;
|
||||
// }
|
||||
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;
|
||||
|
@ -51,7 +51,6 @@ public:
|
||||
void setFrameType(FrameType type);
|
||||
void setId(const ChatId& id) ;
|
||||
void setOwnId();
|
||||
void setOwnId(const RsGxsId&);
|
||||
void setDefaultAvatar(const QString &avatar_file_name);
|
||||
|
||||
protected:
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user