added consistent detection of time-shift in chat lobbies. Shows a warning when the shift is larger than 2^9 seconds (approx. 10 minutes. Warning shown only once).

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6242 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2013-03-18 23:19:37 +00:00
parent a850b18be2
commit 7f53f0e0cc
6 changed files with 95 additions and 0 deletions

View File

@ -185,6 +185,7 @@ class NotifyBase
virtual void notifyErrorMsg(int list, int sev, std::string msg) { (void) list; (void) sev; (void) msg; return; }
virtual void notifyChatStatus(const std::string& /* peer_id */, const std::string& /* status_string */ ,bool /* is_private */) {}
virtual void notifyChatLobbyEvent(uint64_t /* lobby id */,uint32_t /* event type */,const std::string& /* nickname */,const std::string& /* any string */) {}
virtual void notifyChatLobbyTimeShift(int time_shift) {}
virtual void notifyCustomState(const std::string& /* peer_id */, const std::string& /* status_string */) {}
virtual void notifyHashingInfo(uint32_t type, const std::string& fileinfo) { (void) type; (void)fileinfo; }
virtual void notifyTurtleSearchResult(uint32_t /* search_id */ ,const std::list<TurtleFileInfo>& files) { (void)files; }

View File

@ -22,6 +22,7 @@
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include <math.h>
#include "util/rsdir.h"
#include "util/rsrandom.h"
@ -58,6 +59,7 @@ p3ChatService::p3ChatService(p3LinkMgr *lm, p3HistoryMgr *historyMgr)
_own_avatar = NULL ;
_custom_status_string = "" ;
_time_shift_average = 0.0f ;
_default_nick_name = rsPeers->getPeerName(rsPeers->getOwnId());
_should_reset_lobby_counts = false ;
@ -798,6 +800,62 @@ void p3ChatService::handleRecvChatLobbyList(RsChatLobbyListItem *item)
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ;
_should_reset_lobby_counts = false ;
}
void p3ChatService::addTimeShiftStatistics(int D)
{
static const int S = 50 ; // accuracy up to 2^50 second. Quite conservative!
static int total = 0 ;
static std::vector<int> log_delay_histogram(S,0) ;
int delay = (D<0)?(-D):D ;
if(delay < 0)
delay = -delay ;
// compute log2.
int l = 0 ;
while(delay > 0) delay >>= 1, ++l ;
int bin = std::min(S-1,l) ;
++log_delay_histogram[bin] ;
++total ;
#ifdef CHAT_DEBUG
std::cerr << "New delay stat item. delay=" << D << ", log=" << bin << " total=" << total << ", histogram = " ;
for(int i=0;i<S;++i)
std::cerr << log_delay_histogram[i] << " " ;
#endif
if(total > 30)
{
float t = 0.0f ;
int i=0 ;
for(;i<S && t<0.5*total;++i)
t += log_delay_histogram[i] ;
if(i == 0) return ; // cannot happen, since total>0 so i is incremented
if(log_delay_histogram[i-1] == 0) return ; // cannot happen, either, but let's be cautious.
float expected = ( i * (log_delay_histogram[i-1] - t + total*0.5) + (i-1) * (t - total*0.5) ) / (float)log_delay_histogram[i-1] - 1;
#ifdef CHAT_DEBUG
std::cerr << ". Expected delay: " << expected << std::endl ;
#endif
if(expected > 9) // if more than 20 samples
rsicontrol->getNotify().notifyChatLobbyTimeShift( (int)pow(2.0f,expected)) ;
total = 0.0f ;
log_delay_histogram.clear() ;
log_delay_histogram.resize(S,0) ;
}
#ifdef CHAT_DEBUG
else
std::cerr << std::endl;
#endif
}
void p3ChatService::handleRecvChatLobbyEventItem(RsChatLobbyEventItem *item)
{
#ifdef CHAT_DEBUG
@ -805,6 +863,8 @@ void p3ChatService::handleRecvChatLobbyEventItem(RsChatLobbyEventItem *item)
#endif
time_t now = time(NULL) ;
addTimeShiftStatistics((int)now - (int)item->sendTime) ;
if(now+100 > (time_t) item->sendTime + MAX_KEEP_MSG_RECORD) // the message is older than the max cache keep minus 100 seconds ! It's too old, and is going to make an echo!
{
std::cerr << "Received severely outdated lobby event item (" << now - (time_t)item->sendTime << " in the past)! Dropping it!" << std::endl;

View File

@ -194,6 +194,8 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor
void initRsChatInfo(RsChatMsgItem *c, ChatInfo &i);
/// make some statistics about time shifts, to prevent various issues.
void addTimeShiftStatistics(int shift) ;
/// Send avatar info to peer in jpeg format.
void sendAvatarJpegData(const std::string& peer_id) ;
@ -286,6 +288,7 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor
std::map<ChatLobbyId,VisibleChatLobbyRecord> _visible_lobbies ;
std::map<std::string,ChatLobbyId> _lobby_ids ;
std::string _default_nick_name ;
float _time_shift_average ;
time_t last_lobby_challenge_time ; // prevents bruteforce attack
time_t last_visible_lobby_info_request_time ; // allows to ask for updates
bool _should_reset_lobby_counts ;

View File

@ -446,6 +446,32 @@ void NotifyQt::notifyCustomState(const std::string& peer_id, const std::string&
emit peerHasNewCustomStateString(QString::fromStdString(peer_id), QString::fromUtf8(status_string.c_str())) ;
}
void NotifyQt::notifyChatLobbyTimeShift(int shift)
{
{
QMutexLocker m(&_mutex) ;
if(!_enabled)
return ;
}
#ifdef NOTIFY_DEBUG
std::cerr << "notifyQt: Received chat lobby time shift message: shift = " << shift << std::endl;
#endif
emit chatLobbyTimeShift(shift) ;
}
void NotifyQt::handleChatLobbyTimeShift(int shift)
{
static bool already = false ;
if(!already)
{
QString string = tr("For the chat lobbies to work properly, the time of your computer needs to be correct. Please check that this is the case (A possible time shift of ")+QString::number(shift)+tr(" seconds with your friends was detected). ") ;
QMessageBox::warning(NULL,tr("Please check your system clock."),string) ;
already = true ;
}
}
void NotifyQt::notifyChatLobbyEvent(uint64_t lobby_id,uint32_t event_type,const std::string& nickname,const std::string& str)
{
{

View File

@ -46,6 +46,8 @@ class NotifyQt: public QObject, public NotifyBase
virtual void notifyPeerHasNewAvatar(std::string peer_id) ;
virtual void notifyOwnAvatarChanged() ;
virtual void notifyChatLobbyEvent(uint64_t /* lobby id */,uint32_t /* event type */,const std::string& /*nickname*/,const std::string& /* any string */) ;
virtual void notifyChatLobbyTimeShift(int time_shift) ;
virtual void notifyOwnStatusMessageChanged() ;
virtual void notifyDiskFull(uint32_t loc,uint32_t size_in_mb) ;
/* peer has changed the state */
@ -122,6 +124,7 @@ class NotifyQt: public QObject, public NotifyBase
void historyChanged(uint msgId, int type);
void chatLobbyInviteReceived() ;
void deferredSignatureHandlingRequested() ;
void chatLobbyTimeShift(int time_shift) ;
/* Notify from GUI */
void chatStyleChanged(int /*ChatStyle::enumStyleType*/ styleType);
@ -133,6 +136,7 @@ class NotifyQt: public QObject, public NotifyBase
private slots:
void runningTick();
void handleSignatureEvent() ;
void handleChatLobbyTimeShift(int) ;
private:
NotifyQt();

View File

@ -325,6 +325,7 @@ int main(int argc, char *argv[])
std::cerr << "connecting signals and slots" << std::endl ;
QObject::connect(notify,SIGNAL(gotTurtleSearchResult(qulonglong,FileDetail)),w->transfersDialog->searchDialog ,SLOT(updateFiles(qulonglong,FileDetail))) ;
QObject::connect(notify,SIGNAL(deferredSignatureHandlingRequested()),notify,SLOT(handleSignatureEvent()),Qt::QueuedConnection) ;
QObject::connect(notify,SIGNAL(chatLobbyTimeShift(int)),notify,SLOT(handleChatLobbyTimeShift(int)),Qt::QueuedConnection) ;
QObject::connect(notify,SIGNAL(diskFull(int,int)) ,w ,SLOT(displayDiskSpaceWarning(int,int))) ;
QObject::connect(notify,SIGNAL(filesPreModChanged(bool)) ,w->transfersDialog->localSharedFiles ,SLOT(preModDirectories(bool) )) ;
QObject::connect(notify,SIGNAL(filesPreModChanged(bool)) ,w->transfersDialog->remoteSharedFiles ,SLOT(preModDirectories(bool) )) ;