mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
801 lines
21 KiB
C++
801 lines
21 KiB
C++
/****************************************************************
|
|
* RetroShare is distributed under the following license:
|
|
*
|
|
* Copyright (C) 2011 Robert Fernie
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
****************************************************************/
|
|
|
|
#include "DhtWindow.h"
|
|
#include "ui_DhtWindow.h"
|
|
#include "util/QtVersion.h"
|
|
|
|
#include <QClipboard>
|
|
#include <QTimer>
|
|
#include <QDateTime>
|
|
#include <QMenu>
|
|
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <time.h>
|
|
|
|
#include "retroshare-gui/RsAutoUpdatePage.h"
|
|
#include "retroshare/rsdht.h"
|
|
#include "retroshare/rsconfig.h"
|
|
#include "retroshare/rspeers.h"
|
|
|
|
#define DTW_COL_BUCKET 0
|
|
#define DTW_COL_IPADDR 1
|
|
#define DTW_COL_PEERID 2
|
|
#define DTW_COL_FLAGS 3
|
|
#define DTW_COL_FOUND 4
|
|
#define DTW_COL_SEND 5
|
|
#define DTW_COL_RECV 6
|
|
|
|
DhtWindow::DhtWindow(QWidget *parent)
|
|
: RsAutoUpdatePage(1000,parent)
|
|
{
|
|
ui.setupUi(this);
|
|
|
|
connect( ui.filterLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(filterItems(QString)));
|
|
connect( ui.filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int)));
|
|
connect( ui.dhtTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(DHTCustomPopupMenu(QPoint)));
|
|
|
|
/* add filter actions */
|
|
ui.filterLineEdit->addFilter(QIcon(), tr("IP"), DTW_COL_IPADDR, tr("Search IP"));
|
|
ui.filterLineEdit->setCurrentFilter(DTW_COL_IPADDR);
|
|
}
|
|
|
|
DhtWindow::~DhtWindow()
|
|
{
|
|
|
|
}
|
|
|
|
void DhtWindow::DHTCustomPopupMenu( QPoint )
|
|
{
|
|
QMenu contextMnu( this );
|
|
|
|
QTreeWidgetItem *item = ui.dhtTreeWidget->currentItem();
|
|
if (item) {
|
|
|
|
QString Ip = item->text(DTW_COL_IPADDR);
|
|
|
|
contextMnu.addAction(QIcon(), tr("Copy %1 to clipboard").arg(Ip), this, SLOT(copyIP()));
|
|
|
|
}
|
|
|
|
contextMnu.exec(QCursor::pos());
|
|
}
|
|
|
|
void DhtWindow::updateDisplay()
|
|
{
|
|
/* do nothing if locked, or not visible */
|
|
if (RsAutoUpdatePage::eventsLocked() == true)
|
|
{
|
|
#ifdef DEBUG_DHTWINDOW
|
|
std::cerr << "DhtWindow::update() events Are Locked" << std::endl;
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
if (!rsDht)
|
|
{
|
|
#ifdef DEBUG_DHTWINDOW
|
|
std::cerr << "DhtWindow::update rsDht NOT Set" << std::endl;
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
RsAutoUpdatePage::lockAllEvents();
|
|
|
|
//std::cerr << "DhtWindow::update()" << std::endl;
|
|
updateNetStatus();
|
|
updateNetPeers();
|
|
updateDhtPeers();
|
|
updateRelays();
|
|
|
|
RsAutoUpdatePage::unlockAllEvents() ;
|
|
|
|
QHeaderView_setSectionResizeMode(ui.peerTreeWidget->header(), QHeaderView::ResizeToContents);
|
|
QHeaderView_setSectionResizeMode(ui.dhtTreeWidget->header(), QHeaderView::ResizeToContents);
|
|
QHeaderView_setSectionResizeMode(ui.relayTreeWidget->header(), QHeaderView::ResizeToContents);
|
|
}
|
|
|
|
|
|
void DhtWindow::updateNetStatus()
|
|
{
|
|
|
|
QString status;
|
|
QString oldstatus;
|
|
|
|
#if 0
|
|
status = QString::fromStdString(mPeerNet->getPeerStatusString());
|
|
oldstatus = ui.peerLine->text();
|
|
if (oldstatus != status)
|
|
{
|
|
ui.peerLine->setText(status);
|
|
}
|
|
#endif
|
|
|
|
status = QString::fromStdString(rsDht->getUdpAddressString());
|
|
oldstatus = ui.peerAddressLabel->text();
|
|
if (oldstatus != status)
|
|
{
|
|
ui.peerAddressLabel->setText(status);
|
|
}
|
|
|
|
uint32_t netMode = rsConfig->getNetworkMode();
|
|
|
|
QLabel *label = ui.networkLabel;
|
|
switch(netMode)
|
|
{
|
|
case RSNET_NETWORK_UNKNOWN:
|
|
label->setText(tr("Unknown NetState"));
|
|
break;
|
|
case RSNET_NETWORK_OFFLINE:
|
|
label->setText(tr("Offline"));
|
|
break;
|
|
case RSNET_NETWORK_LOCALNET:
|
|
label->setText(tr("Local Net"));
|
|
break;
|
|
case RSNET_NETWORK_BEHINDNAT:
|
|
label->setText(tr("Behind NAT"));
|
|
break;
|
|
case RSNET_NETWORK_EXTERNALIP:
|
|
label->setText(tr("External IP"));
|
|
break;
|
|
}
|
|
|
|
label = ui.natTypeLabel;
|
|
|
|
uint32_t natType = rsConfig->getNatTypeMode();
|
|
switch(natType)
|
|
{
|
|
case RSNET_NATTYPE_UNKNOWN:
|
|
label->setText(tr("UNKNOWN NAT STATE"));
|
|
break;
|
|
case RSNET_NATTYPE_SYMMETRIC:
|
|
label->setText(tr("SYMMETRIC NAT"));
|
|
break;
|
|
case RSNET_NATTYPE_DETERM_SYM:
|
|
label->setText(tr("DETERMINISTIC SYM NAT"));
|
|
break;
|
|
case RSNET_NATTYPE_RESTRICTED_CONE:
|
|
label->setText(tr("RESTRICTED CONE NAT"));
|
|
break;
|
|
case RSNET_NATTYPE_FULL_CONE:
|
|
label->setText(tr("FULL CONE NAT"));
|
|
break;
|
|
case RSNET_NATTYPE_OTHER:
|
|
label->setText(tr("OTHER NAT"));
|
|
break;
|
|
case RSNET_NATTYPE_NONE:
|
|
label->setText(tr("NO NAT"));
|
|
break;
|
|
}
|
|
|
|
|
|
|
|
label = ui.natHoleLabel;
|
|
uint32_t natHole = rsConfig->getNatHoleMode();
|
|
|
|
switch(natHole)
|
|
{
|
|
case RSNET_NATHOLE_UNKNOWN:
|
|
label->setText(tr("UNKNOWN NAT HOLE STATUS"));
|
|
break;
|
|
case RSNET_NATHOLE_NONE:
|
|
label->setText(tr("NO NAT HOLE"));
|
|
break;
|
|
case RSNET_NATHOLE_UPNP:
|
|
label->setText(tr("UPNP FORWARD"));
|
|
break;
|
|
case RSNET_NATHOLE_NATPMP:
|
|
label->setText(tr("NATPMP FORWARD"));
|
|
break;
|
|
case RSNET_NATHOLE_FORWARDED:
|
|
label->setText(tr("MANUAL FORWARD"));
|
|
break;
|
|
}
|
|
|
|
uint32_t connect = rsConfig->getConnectModes();
|
|
|
|
label = ui.connectLabel;
|
|
QString connOut;
|
|
if (connect & RSNET_CONNECT_OUTGOING_TCP)
|
|
{
|
|
connOut += "TCP_OUT ";
|
|
}
|
|
if (connect & RSNET_CONNECT_ACCEPT_TCP)
|
|
{
|
|
connOut += "TCP_IN ";
|
|
}
|
|
if (connect & RSNET_CONNECT_DIRECT_UDP)
|
|
{
|
|
connOut += "DIRECT_UDP ";
|
|
}
|
|
if (connect & RSNET_CONNECT_PROXY_UDP)
|
|
{
|
|
connOut += "PROXY_UDP ";
|
|
}
|
|
if (connect & RSNET_CONNECT_RELAY_UDP)
|
|
{
|
|
connOut += "RELAY_UDP ";
|
|
}
|
|
|
|
label->setText(connOut);
|
|
|
|
uint32_t netState = rsConfig->getNetState();
|
|
|
|
label = ui.netStatusLabel;
|
|
switch(netState)
|
|
{
|
|
case RSNET_NETSTATE_BAD_UNKNOWN:
|
|
label->setText(tr("NET BAD: Unknown State"));
|
|
break;
|
|
case RSNET_NETSTATE_BAD_OFFLINE:
|
|
label->setText(tr("NET BAD: Offline"));
|
|
break;
|
|
case RSNET_NETSTATE_BAD_NATSYM:
|
|
label->setText(tr("NET BAD: Behind Symmetric NAT"));
|
|
break;
|
|
case RSNET_NETSTATE_BAD_NODHT_NAT:
|
|
label->setText(tr("NET BAD: Behind NAT & No DHT"));
|
|
break;
|
|
case RSNET_NETSTATE_WARNING_RESTART:
|
|
label->setText(tr("NET WARNING: NET Restart"));
|
|
break;
|
|
case RSNET_NETSTATE_WARNING_NATTED:
|
|
label->setText(tr("NET WARNING: Behind NAT"));
|
|
break;
|
|
case RSNET_NETSTATE_WARNING_NODHT:
|
|
label->setText(tr("NET WARNING: No DHT"));
|
|
break;
|
|
case RSNET_NETSTATE_GOOD:
|
|
label->setText(tr("NET STATE GOOD!"));
|
|
break;
|
|
case RSNET_NETSTATE_ADV_FORWARD:
|
|
label->setText(tr("CAUTION: UNVERIFIABLE FORWARD!"));
|
|
break;
|
|
case RSNET_NETSTATE_ADV_DARK_FORWARD:
|
|
label->setText(tr("CAUTION: UNVERIFIABLE FORWARD & NO DHT"));
|
|
break;
|
|
}
|
|
}
|
|
|
|
void DhtWindow::updateNetPeers()
|
|
{
|
|
//QTreeWidget *peerTreeWidget = ui.peerTreeWidget;
|
|
|
|
std::list<RsPeerId> peerIds;
|
|
std::list<RsPeerId>::iterator it;
|
|
|
|
rsDht->getNetPeerList(peerIds);
|
|
|
|
/* collate peer stats */
|
|
int nPeers = peerIds.size();
|
|
|
|
// from DHT peers
|
|
int nOnlinePeers = 0;
|
|
int nUnreachablePeers = 0;
|
|
int nOfflinePeers = 0;
|
|
|
|
// Connect States.
|
|
int nDisconnPeers = 0;
|
|
int nDirectPeers = 0;
|
|
int nProxyPeers = 0;
|
|
int nRelayPeers = 0;
|
|
|
|
|
|
#define PTW_COL_RSNAME 0
|
|
#define PTW_COL_PEERID 1
|
|
#define PTW_COL_DHT_STATUS 2
|
|
|
|
#define PTW_COL_PEER_CONNECTLOGIC 3
|
|
|
|
#define PTW_COL_PEER_CONNECT_STATUS 4
|
|
#define PTW_COL_PEER_CONNECT_MODE 5
|
|
#define PTW_COL_PEER_REQ_STATUS 6
|
|
|
|
#define PTW_COL_PEER_CB_MSG 7
|
|
#define PTW_COL_RSID 8
|
|
|
|
#if 0
|
|
/* clear old entries */
|
|
int itemCount = peerTreeWidget->topLevelItemCount();
|
|
for (int nIndex = 0; nIndex < itemCount;)
|
|
{
|
|
QTreeWidgetItem *tmp_item = ui.peerTreeWidget->topLevelItem(nIndex);
|
|
std::string tmpid = tmp_item->data(PTW_COL_PEERID, Qt::DisplayRole).toString().toStdString();
|
|
if (peerIds.end() == std::find(peerIds.begin(), peerIds.end(), tmpid))
|
|
{
|
|
ui.peerTreeWidget->removeItemWidget(tmp_item, 0);
|
|
/* remove it! */
|
|
itemCount--;
|
|
}
|
|
else
|
|
{
|
|
++nIndex;
|
|
}
|
|
}
|
|
#endif
|
|
ui.peerTreeWidget->clear();
|
|
|
|
for(it = peerIds.begin(); it != peerIds.end(); ++it)
|
|
{
|
|
/* find the entry */
|
|
QTreeWidgetItem *peer_item = NULL;
|
|
#if 0
|
|
QString qpeerid = QString::fromStdString(*it);
|
|
int itemCount = ui.peerTreeWidget->topLevelItemCount();
|
|
for (int nIndex = 0; nIndex < itemCount; ++nIndex)
|
|
{
|
|
QTreeWidgetItem *tmp_item = ui.peerTreeWidget->topLevelItem(nIndex);
|
|
if (tmp_item->data(PTW_COL_PEERID, Qt::DisplayRole).toString() == qpeerid)
|
|
{
|
|
peer_item = tmp_item;
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (!peer_item)
|
|
{
|
|
/* insert */
|
|
peer_item = new QTreeWidgetItem();
|
|
ui.peerTreeWidget->addTopLevelItem(peer_item);
|
|
}
|
|
|
|
/* Set header resize modes and initial section sizes Peer TreeView*/
|
|
QHeaderView * _header = ui.peerTreeWidget->header () ;
|
|
_header->resizeSection ( PTW_COL_RSNAME, 170 );
|
|
|
|
|
|
/* update the data */
|
|
RsDhtNetPeer status;
|
|
rsDht->getNetPeerStatus(*it, status);
|
|
|
|
std::string name = rsPeers->getPeerName(*it);
|
|
|
|
peer_item -> setData(PTW_COL_PEERID, Qt::DisplayRole, QString::fromStdString(status.mDhtId));
|
|
peer_item -> setData(PTW_COL_RSNAME, Qt::DisplayRole, QString::fromUtf8(name.c_str()));
|
|
peer_item -> setData(PTW_COL_RSID, Qt::DisplayRole, QString::fromStdString(status.mRsId.toStdString()));
|
|
|
|
QString dhtstate;
|
|
switch(status.mDhtState)
|
|
{
|
|
default:
|
|
case RSDHT_PEERDHT_NOT_ACTIVE:
|
|
dhtstate = tr("Not Active (Maybe Connected!)");
|
|
break;
|
|
case RSDHT_PEERDHT_SEARCHING:
|
|
dhtstate = tr("Searching");
|
|
break;
|
|
case RSDHT_PEERDHT_FAILURE:
|
|
dhtstate = tr("Failed");
|
|
break;
|
|
case RSDHT_PEERDHT_OFFLINE:
|
|
dhtstate = tr("offline");
|
|
++nOfflinePeers;
|
|
break;
|
|
case RSDHT_PEERDHT_UNREACHABLE:
|
|
dhtstate = tr("Unreachable");
|
|
++nUnreachablePeers;
|
|
break;
|
|
case RSDHT_PEERDHT_ONLINE:
|
|
dhtstate = tr("ONLINE");
|
|
++nOnlinePeers;
|
|
break;
|
|
}
|
|
|
|
peer_item -> setData(PTW_COL_DHT_STATUS, Qt::DisplayRole, dhtstate);
|
|
|
|
// NOW CONNECT STATE
|
|
QString cpmstr;
|
|
switch(status.mPeerConnectMode)
|
|
{
|
|
case RSDHT_TOU_MODE_DIRECT:
|
|
cpmstr = tr("Direct");
|
|
break;
|
|
case RSDHT_TOU_MODE_PROXY:
|
|
cpmstr = tr("Proxy VIA")+" " + QString::fromStdString(status.mPeerConnectProxyId);
|
|
break;
|
|
case RSDHT_TOU_MODE_RELAY:
|
|
cpmstr = tr("Relay VIA")+" " + QString::fromStdString(status.mPeerConnectProxyId);
|
|
break;
|
|
default:
|
|
case RSDHT_TOU_MODE_NONE:
|
|
cpmstr = tr("None");
|
|
break;
|
|
}
|
|
|
|
|
|
QString cpsstr;
|
|
switch(status.mPeerConnectState)
|
|
{
|
|
default:
|
|
case RSDHT_PEERCONN_DISCONNECTED:
|
|
cpsstr = tr("Disconnected");
|
|
++nDisconnPeers;
|
|
break;
|
|
case RSDHT_PEERCONN_UDP_STARTED:
|
|
cpsstr = tr("Udp Started");
|
|
break;
|
|
case RSDHT_PEERCONN_CONNECTED:
|
|
{
|
|
cpsstr = tr("Connected");
|
|
break;
|
|
switch(status.mPeerConnectMode)
|
|
{
|
|
default:
|
|
case RSDHT_TOU_MODE_DIRECT:
|
|
++nDirectPeers;
|
|
break;
|
|
case RSDHT_TOU_MODE_PROXY:
|
|
++nProxyPeers;
|
|
break;
|
|
case RSDHT_TOU_MODE_RELAY:
|
|
++nRelayPeers;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
peer_item -> setData(PTW_COL_PEER_CONNECT_STATUS, Qt::DisplayRole, cpsstr);
|
|
|
|
if (status.mPeerConnectState == RSDHT_PEERCONN_DISCONNECTED)
|
|
{
|
|
peer_item -> setData(PTW_COL_PEER_CONNECT_MODE, Qt::DisplayRole, "");
|
|
}
|
|
else
|
|
{
|
|
peer_item -> setData(PTW_COL_PEER_CONNECT_MODE, Qt::DisplayRole, cpmstr);
|
|
}
|
|
|
|
// NOW REQ STATE.
|
|
QString reqstr;
|
|
if (status.mExclusiveProxyLock)
|
|
{
|
|
reqstr = "(E) ";
|
|
}
|
|
switch(status.mPeerReqState)
|
|
{
|
|
case RSDHT_PEERREQ_RUNNING:
|
|
reqstr += tr("Request Active");
|
|
break;
|
|
case RSDHT_PEERREQ_STOPPED:
|
|
reqstr += tr("No Request");
|
|
break;
|
|
default:
|
|
reqstr += tr("Unknown");
|
|
break;
|
|
}
|
|
peer_item -> setData(PTW_COL_PEER_REQ_STATUS, Qt::DisplayRole, reqstr);
|
|
|
|
peer_item -> setData(PTW_COL_PEER_CB_MSG, Qt::DisplayRole, QString::fromStdString(status.mCbPeerMsg));
|
|
peer_item -> setData(PTW_COL_PEER_CONNECTLOGIC, Qt::DisplayRole,
|
|
QString::fromStdString(status.mConnectState));
|
|
}
|
|
|
|
|
|
/*QString connstr;
|
|
connstr = tr("#Peers: ") + QString::number(nPeers);
|
|
connstr += tr(" DHT: (#off:") + QString::number(nOfflinePeers);
|
|
connstr += tr(",unreach:") + QString::number(nUnreachablePeers);
|
|
connstr += tr(",online:") + QString::number(nOnlinePeers);
|
|
connstr += tr(") Connections: (#dis:") + QString::number(nDisconnPeers);
|
|
connstr += tr(",#dir:") + QString::number(nDirectPeers);
|
|
connstr += tr(",#proxy:") + QString::number(nProxyPeers);
|
|
connstr += tr(",#relay:") + QString::number(nRelayPeers);
|
|
connstr += ")";*/
|
|
|
|
ui.label_peers->setText(QString::number(nPeers));
|
|
ui.label_offline->setText(QString::number(nOfflinePeers));
|
|
ui.label_unreachable->setText(QString::number(nUnreachablePeers));
|
|
ui.label_online->setText(QString::number(nOnlinePeers));
|
|
|
|
ui.label_disconnected->setText(QString::number(nDisconnPeers));
|
|
ui.label_direct->setText(QString::number(nDirectPeers));
|
|
ui.label_proxy->setText(QString::number(nProxyPeers));
|
|
ui.label_relay->setText(QString::number(nRelayPeers));
|
|
|
|
ui.tabWidget_2->setTabText(1, tr("Peers") + " (" + QString::number(ui.peerTreeWidget->topLevelItemCount()) + ")" );
|
|
|
|
|
|
//peerSummaryLabel->setText(connstr);
|
|
}
|
|
|
|
|
|
|
|
void DhtWindow::updateRelays()
|
|
{
|
|
|
|
QTreeWidget *relayTreeWidget = ui.relayTreeWidget;
|
|
|
|
std::list<RsDhtRelayEnd> relayEnds;
|
|
std::list<RsDhtRelayProxy> relayProxies;
|
|
|
|
std::list<RsDhtRelayEnd>::iterator reit;
|
|
std::list<RsDhtRelayProxy>::iterator rpit;
|
|
|
|
rsDht->getRelayEnds(relayEnds);
|
|
rsDht->getRelayProxies(relayProxies);
|
|
|
|
|
|
#define RTW_COL_TYPE 0
|
|
#define RTW_COL_SRC 1
|
|
#define RTW_COL_PROXY 2
|
|
#define RTW_COL_DEST 3
|
|
#define RTW_COL_CLASS 4
|
|
#define RTW_COL_AGE 5
|
|
#define RTW_COL_LASTSEND 6
|
|
#define RTW_COL_BANDWIDTH 7
|
|
|
|
relayTreeWidget->clear();
|
|
time_t now = time(NULL);
|
|
|
|
for(reit = relayEnds.begin(); reit != relayEnds.end(); ++reit)
|
|
{
|
|
/* find the entry */
|
|
QTreeWidgetItem *item = new QTreeWidgetItem();
|
|
ui.relayTreeWidget->addTopLevelItem(item);
|
|
|
|
QString typestr = tr("RELAY END");
|
|
QString srcstr = tr("Yourself");
|
|
QString proxystr = QString::fromStdString(reit->mProxyAddr);
|
|
QString deststr = QString::fromStdString(reit->mRemoteAddr);
|
|
QString agestr = tr("unknown");
|
|
QString lastsendstr = tr("unknown");
|
|
QString bandwidthstr = tr("unlimited");
|
|
QString classstr = tr("Own Relay");
|
|
|
|
//std::ostringstream dhtupdatestr;
|
|
//dhtupdatestr << now - status.mDhtUpdateTS << " secs ago";
|
|
|
|
item -> setData(RTW_COL_TYPE, Qt::DisplayRole, typestr);
|
|
item -> setData(RTW_COL_SRC, Qt::DisplayRole, srcstr);
|
|
item -> setData(RTW_COL_PROXY, Qt::DisplayRole, proxystr);
|
|
item -> setData(RTW_COL_DEST, Qt::DisplayRole, deststr);
|
|
item -> setData(RTW_COL_CLASS, Qt::DisplayRole, classstr);
|
|
item -> setData(RTW_COL_AGE, Qt::DisplayRole, agestr);
|
|
item -> setData(RTW_COL_LASTSEND, Qt::DisplayRole, lastsendstr);
|
|
item -> setData(RTW_COL_BANDWIDTH, Qt::DisplayRole, bandwidthstr);
|
|
|
|
}
|
|
|
|
|
|
for(rpit = relayProxies.begin(); rpit != relayProxies.end(); ++rpit)
|
|
{
|
|
/* find the entry */
|
|
QTreeWidgetItem *item = new QTreeWidgetItem();
|
|
ui.relayTreeWidget->addTopLevelItem(item);
|
|
|
|
QString typestr = tr("RELAY PROXY");
|
|
QString srcstr = QString::fromStdString(rpit->mSrcAddr);
|
|
QString proxystr = tr("Yourself");
|
|
QString deststr = QString::fromStdString(rpit->mDestAddr);
|
|
QString agestr = QString(tr("%1 secs ago")).arg(now - rpit->mCreateTS);
|
|
QString lastsendstr = QString(tr("%1 secs ago")).arg(now - rpit->mLastTS);
|
|
QString bandwidthstr = QString(tr("%1B/s")).arg(QString::number(rpit->mBandwidth));
|
|
QString classstr = QString::number(rpit->mRelayClass);
|
|
|
|
item -> setData(RTW_COL_TYPE, Qt::DisplayRole, typestr);
|
|
item -> setData(RTW_COL_SRC, Qt::DisplayRole, srcstr);
|
|
item -> setData(RTW_COL_PROXY, Qt::DisplayRole, proxystr);
|
|
item -> setData(RTW_COL_DEST, Qt::DisplayRole, deststr);
|
|
item -> setData(RTW_COL_CLASS, Qt::DisplayRole, classstr);
|
|
item -> setData(RTW_COL_AGE, Qt::DisplayRole, agestr);
|
|
item -> setData(RTW_COL_LASTSEND, Qt::DisplayRole, lastsendstr);
|
|
item -> setData(RTW_COL_BANDWIDTH, Qt::DisplayRole, bandwidthstr);
|
|
|
|
}
|
|
|
|
ui.tabWidget_2->setTabText(2, tr("Relays") + " (" + QString::number(ui.relayTreeWidget->topLevelItemCount()) + ")" );
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************/
|
|
|
|
|
|
class DhtTreeWidgetItem : public QTreeWidgetItem
|
|
{
|
|
public:
|
|
virtual bool operator<(const QTreeWidgetItem &other) const
|
|
{
|
|
int column = treeWidget()->sortColumn();
|
|
if (column == DTW_COL_RECV || column == DTW_COL_SEND
|
|
|| column == DTW_COL_BUCKET)
|
|
{
|
|
QString t1 = text(column);
|
|
QString t2 = other.text(column);
|
|
t1 = t1.left(t1.indexOf(' '));
|
|
t2 = t2.left(t2.indexOf(' '));
|
|
return t1.toLong() < t2.toLong();
|
|
}
|
|
return text(column) < other.text(column);
|
|
}
|
|
};
|
|
|
|
void DhtWindow::updateDhtPeers()
|
|
{
|
|
|
|
/* Hackish display of all Dht peers, should be split into buckets (as children) */
|
|
//QString status = QString::fromStdString(mPeerNet->getDhtStatusString());
|
|
//dhtLabel->setText(status);
|
|
|
|
std::list<RsDhtPeer> allpeers;
|
|
std::list<RsDhtPeer>::iterator it;
|
|
int i;
|
|
for(i = 0; i < 160; ++i)
|
|
{
|
|
std::list<RsDhtPeer> peers;
|
|
rsDht->getDhtPeers(i, peers);
|
|
|
|
for(it = peers.begin(); it != peers.end(); ++it)
|
|
{
|
|
allpeers.push_back(*it);
|
|
}
|
|
}
|
|
|
|
//QTreeWidget *dhtTreeWidget = ui.dhtTreeWidget;
|
|
|
|
ui.dhtTreeWidget->clear();
|
|
|
|
time_t now = time(NULL);
|
|
for(it = allpeers.begin(); it != allpeers.end(); ++it)
|
|
{
|
|
/* find the entry */
|
|
QTreeWidgetItem *dht_item = NULL;
|
|
|
|
/* insert */
|
|
dht_item = new DhtTreeWidgetItem();
|
|
|
|
QString buckstr = QString::number(it->mBucket);
|
|
QString ipstr = QString::fromStdString(it->mAddr);
|
|
QString idstr = QString::fromStdString(it->mDhtId);
|
|
QString flagsstr = QString(tr("0x%1 EX:0x%2")).arg(it->mPeerFlags, 0, 16, QChar('0')).arg(it->mExtraFlags, 0, 16, QChar('0'));
|
|
QString foundstr = QString(tr("%1 secs ago")).arg(now - it->mFoundTime);
|
|
|
|
QString lastsendstr;
|
|
if (it->mLastSendTime == 0)
|
|
{
|
|
lastsendstr = tr("never");
|
|
}
|
|
else
|
|
{
|
|
lastsendstr = QString (tr("%1 secs ago")).arg(now - it->mLastSendTime);
|
|
}
|
|
|
|
QString lastrecvstr = QString (tr("%1 secs ago")).arg(now - it->mLastRecvTime);
|
|
|
|
dht_item -> setData(DTW_COL_BUCKET, Qt::DisplayRole, buckstr);
|
|
dht_item -> setData(DTW_COL_IPADDR, Qt::DisplayRole, ipstr);
|
|
dht_item -> setData(DTW_COL_PEERID, Qt::DisplayRole, idstr);
|
|
dht_item -> setData(DTW_COL_FLAGS, Qt::DisplayRole, flagsstr);
|
|
|
|
dht_item -> setData(DTW_COL_FOUND, Qt::DisplayRole, foundstr);
|
|
dht_item -> setData(DTW_COL_SEND, Qt::DisplayRole, lastsendstr);
|
|
dht_item -> setData(DTW_COL_RECV, Qt::DisplayRole, lastrecvstr);
|
|
|
|
ui.dhtTreeWidget->addTopLevelItem(dht_item);
|
|
|
|
if (ui.filterLineEdit->text().isEmpty() == false) {
|
|
filterItems(ui.filterLineEdit->text());
|
|
}
|
|
|
|
ui.tabWidget_2->setTabText(0, tr("DHT") + " (" + QString::number(ui.dhtTreeWidget->topLevelItemCount()) + ")" );
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
void DhtWindow::getDHTStatus()
|
|
{
|
|
|
|
// RsConfigNetStatus config;
|
|
// rsConfig->getConfigNetStatus(config);
|
|
//
|
|
// if (!(config.DHTActive))
|
|
// {
|
|
// // GRAY.
|
|
// }
|
|
// else
|
|
// {
|
|
// if (config.netDhtOk)
|
|
// {
|
|
// #define MIN_RS_NET_SIZE 10
|
|
// // YELLOW or GREEN.
|
|
// if (config.netDhtRsNetSize < MIN_RS_NET_SIZE)
|
|
// {
|
|
// updateGraph(config.netDhtRsNetSize,config.netDhtNetSize);
|
|
// }
|
|
// else
|
|
// {
|
|
// updateGraph(config.netDhtRsNetSize,config.netDhtNetSize);
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// // RED - some issue.
|
|
//
|
|
// }
|
|
// }
|
|
}
|
|
|
|
void DhtWindow::filterColumnChanged(int)
|
|
{
|
|
filterItems(ui.filterLineEdit->text());
|
|
}
|
|
|
|
void DhtWindow::filterItems(const QString &text)
|
|
{
|
|
int filterColumn = ui.filterLineEdit->currentFilter();
|
|
|
|
int count = ui.dhtTreeWidget->topLevelItemCount ();
|
|
for (int index = 0; index < count; ++index) {
|
|
filterItem(ui.dhtTreeWidget->topLevelItem(index), text, filterColumn);
|
|
}
|
|
}
|
|
|
|
bool DhtWindow::filterItem(QTreeWidgetItem *item, const QString &text, int filterColumn)
|
|
{
|
|
bool visible = true;
|
|
|
|
if (text.isEmpty() == false) {
|
|
if (item->text(filterColumn).contains(text, Qt::CaseInsensitive) == false) {
|
|
visible = false;
|
|
}
|
|
}
|
|
|
|
int visibleChildCount = 0;
|
|
int count = item->childCount();
|
|
for (int index = 0; index < count; ++index) {
|
|
if (filterItem(item->child(index), text, filterColumn)) {
|
|
++visibleChildCount;
|
|
}
|
|
}
|
|
|
|
if (visible || visibleChildCount) {
|
|
item->setHidden(false);
|
|
} else {
|
|
item->setHidden(true);
|
|
}
|
|
|
|
return (visible || visibleChildCount);
|
|
}
|
|
|
|
void DhtWindow::copyIP()
|
|
{
|
|
QTreeWidgetItem *item = ui.dhtTreeWidget->currentItem();
|
|
if (!item)
|
|
{
|
|
return;
|
|
}
|
|
|
|
QString Ip = item->text(DTW_COL_IPADDR);
|
|
|
|
QApplication::clipboard()->setText(Ip, QClipboard::Clipboard);
|
|
|
|
}
|
|
|
|
|
|
|