mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-06-03 05:32:53 -04:00
fixed a few bugs in distant chat: disabled history (for now), improved tunnel handling
This commit is contained in:
parent
b198f1a007
commit
318be3a2ad
4 changed files with 157 additions and 140 deletions
|
@ -381,6 +381,11 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg)
|
|||
#endif
|
||||
|
||||
RsServer::notify()->notifyChatMessage(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);
|
||||
|
@ -752,7 +757,13 @@ bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *ci)
|
|||
cm.incoming = true;
|
||||
cm.online = true;
|
||||
RsServer::notify()->notifyChatMessage(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 ;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
#include "p3gxstunnel.h"
|
||||
|
||||
#define DEBUG_GXS_TUNNEL
|
||||
//#define DEBUG_GXS_TUNNEL
|
||||
|
||||
static const uint32_t GXS_TUNNEL_KEEP_ALIVE_TIMEOUT = 6 ; // send keep alive packet so as to avoid tunnel breaks.
|
||||
|
||||
|
@ -373,14 +373,25 @@ void p3GxsTunnelService::handleRecvStatusItem(const RsGxsTunnelId& tunnel_id, Rs
|
|||
return ;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << " Marking distant chat as remotely closed for tunnel id " << tunnel_id << std::endl;
|
||||
#endif
|
||||
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) ;
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << " This is server side. The tunnel cannot be re-openned, so we give it up." << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
it->second.status = RS_GXS_TUNNEL_STATUS_TUNNEL_DN ;
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << " This is client side. The tunnel will be re-openned automatically." << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
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 ;
|
||||
|
||||
|
@ -1467,7 +1478,7 @@ bool p3GxsTunnelService::closeExistingTunnel(const RsGxsTunnelId& tunnel_id, uin
|
|||
close_tunnel = true ;
|
||||
}
|
||||
|
||||
if(close_tunnel && direction == RsTurtleGenericTunnelItem::DIRECTION_SERVER) // nothing more to do for server side.
|
||||
if(close_tunnel)
|
||||
{
|
||||
// send a status item saying that we're closing the connection
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
|
@ -1481,14 +1492,14 @@ bool p3GxsTunnelService::closeExistingTunnel(const RsGxsTunnelId& tunnel_id, uin
|
|||
|
||||
locked_sendEncryptedTunnelData(cs) ; // that needs to be done off-mutex and before we close the tunnel also ignoring failure.
|
||||
|
||||
if(direction == RsTurtleGenericTunnelItem::DIRECTION_SERVER) // nothing more to do for server side.
|
||||
{
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << " This is client side. Stopping tunnel manageement for tunnel_id " << tunnel_id << std::endl;
|
||||
#endif
|
||||
mTurtle->stopMonitoringTunnels( hash ) ; // still valid if the hash is null
|
||||
}
|
||||
|
||||
if(close_tunnel)
|
||||
{
|
||||
RsStackMutex stack(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ;
|
||||
|
||||
|
|
|
@ -28,10 +28,14 @@
|
|||
// Generic tunnel service
|
||||
//
|
||||
// Preconditions:
|
||||
// * multiple services can use the same tunnel
|
||||
// * tunnels are automatically encrypted and ensure transport (items stored in a queue until ACKed by the other side)
|
||||
// * 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:
|
||||
|
@ -41,7 +45,7 @@
|
|||
// - 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
|
||||
// We can use an additional tab "Authenticated tunnels" in the statistics->turtle window for that purpose.
|
||||
//
|
||||
// Interaction with services:
|
||||
//
|
||||
|
@ -52,14 +56,20 @@
|
|||
// 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
|
||||
//
|
||||
// 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.
|
||||
// - 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
|
||||
|
@ -72,25 +82,18 @@
|
|||
// - 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.
|
||||
// - multiple tunnels may end up to the same hash, but will correspond to different GXS tunnels since the GXS id in the other side is different.
|
||||
//
|
||||
// Turtle hash: [ 0 ---------------15 16---19 ]
|
||||
// Destination Source
|
||||
// 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.
|
||||
//
|
||||
// Another option is to use random bytes in 16-19. But then, we would digg multiple times different tunnels between the same two peers even when requesting
|
||||
// a GXS tunnel for the same pair of GXS ids. Is that a problem?
|
||||
// - that solves the problem of colliding source GXS ids (since 4 bytes is too small)
|
||||
// - the DH will make it clear that we're talking to the same person if it already exist.
|
||||
//
|
||||
// * 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) -
|
||||
// | |
|
||||
|
@ -108,14 +111,6 @@
|
|||
// | |
|
||||
// +---------------- 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.
|
||||
// Without this, it's not possible to request two tunnels to a same server GXS id but from a different client GXS id. Indeed, if the two hashes are the same,
|
||||
// from the same peer, the tunnel names will be identical and so will be the virtual peer ids, if the route is the same (because of multi-tunneling, they
|
||||
// will be different if the route is different).
|
||||
//
|
||||
// *
|
||||
|
||||
#include <turtle/turtleclientservice.h>
|
||||
#include <retroshare/rsgxstunnel.h>
|
||||
|
|
|
@ -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("Tunnels")));
|
||||
routertabWidget->addTab(new GxsTunnelsDialog(),QString(tr("Authenticated pipes")));
|
||||
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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue