merged with upstream/master

This commit is contained in:
csoler 2016-06-16 20:19:03 -04:00
commit dbd78d2401
77 changed files with 2311 additions and 1333 deletions

View File

@ -2,6 +2,22 @@ RetroShare
==============================
RetroShare is a decentralized, private and secure commmunication and sharing platform. RetroShare provides filesharing, chat, messages, forums and channels.
Build Status
------------
| Platform | Build Status |
| :------------- | :------------- |
| GNU/Linux, MacOS, (via travis-ci) | [![Build Status](https://travis-ci.org/RetroShare/RetroShare.svg?branch=master)](https://travis-ci.org/RetroShare/RetroShare) |
| Windows, `MSys2` (via appveyor) | [![Build status](https://ci.appveyor.com/api/projects/status/axkopdqj9fc48kwe?svg=true)](https://ci.appveyor.com/project/PhenomRetroShare/retroshare) |
Compilation on Windows
----------------------------
Follow this file : [WindowsMSys2_InstallGuide.txt](https://github.com/RetroShare/RetroShare/blob/master/WindowsMSys2_InstallGuide.txt)
Compilation on MacOSX
----------------------------
Follow this file : [MacOS_X_InstallGuide.txt](https://github.com/RetroShare/RetroShare/blob/master/MacOS_X_InstallGuide.txt)
Compilation on Linux
----------------------------

210
appveyor.yml Normal file
View File

@ -0,0 +1,210 @@
# Notes:
# - Minimal appveyor.yml file is an empty file. All sections are optional.
# - Indent each level of configuration with 2 spaces. Do not use tabs!
# - All section names are case-sensitive.
# - Section names should be unique on each level.
# from example:
# https://github.com/Phonations/Joker/blob/master/appveyor.yml
# https://github.com/unicorn-engine/autobuild/blob/master/.appveyor.yml
#---------------------------------#
# general configuration #
#---------------------------------#
# version format
version: RetroShare 6.0.{build}-{branch}
# you can use {branch} name in version format too
# version: 1.0.{build}-{branch}
# branches to build
branches:
# whitelist
#only:
# - master
# blacklist
except:
- /^skipthisbranch$/
# Do not build on tags (GitHub only)
skip_tags: true
# Skipping commits with particular message or from user
skip_commits:
message: /Created.*\.(png|jpg|jpeg|bmp|gif)/ # Regex for matching commit message
#author: Anonymous # Commit author's username, name, email or regexp maching one of these.
#---------------------------------#
# environment configuration #
#---------------------------------#
# Operating system (build VM template)
#os: Windows Server 2012
# scripts that are called at very beginning, before repo cloning
init:
- git config --global core.autocrlf input
#To get RDP while compiling
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
on_finish:
#To get RDP running after compiling
#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
# clone directory
clone_folder: c:\projects\RetroShare
# fetch repository as zip archive
#shallow_clone: true # default is "false"
# set clone depth
clone_depth: 1 # clone entire repository history if not defined
environment:
global:
#Qt: https://www.appveyor.com/docs/installed-software#qt
QTDIR: C:\Qt\5.4\mingw491_32
MSYS2_ARCH: i686
TARGET: i686_32-pc-msys
# build cache to preserve files/folders between builds
cache:
- c:\projects\libs
# - packages -> **\packages.config # preserve "packages" directory in the root of build folder but will reset it if packages.config is modified
# - projectA\libs
# - node_modules # local npm modules
# - %APPDATA%\npm-cache # npm cache
# scripts that run after cloning repository
#install:
# # by default, all script lines are interpreted as batch
# - echo This is batch
# # to run script as a PowerShell command prepend it with ps:
# - ps: Write-Host 'This is PowerShell'
# # batch commands start from cmd:
# - cmd: echo This is batch again
# - cmd: set MY_VAR=12345
install:
# Configuring MSys2
- set PATH=C:\msys64\usr\bin;%PATH%
- set PATH=C:\msys64\mingw32\bin;%PATH%
# Configuring Qt
- set PATH=%QTDIR%\bin;C:\Qt\Tools\mingw491_32\bin;%PATH%
# Install all default programms
#- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sy base-devel git mercurial cvs wget p7zip gcc perl ruby python2" #Already installed
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sy openssl-devel"
# Install toolchain
#- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain" #Already installed
# Install other binutils
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-miniupnpc mingw-w64-x86_64-miniupnpc"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-sqlite3 mingw-w64-x86_64-sqlite3"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-speex mingw-w64-x86_64-speex"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-opencv mingw-w64-x86_64-opencv"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-ffmpeg mingw-w64-x86_64-ffmpeg"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-libmicrohttpd mingw-w64-x86_64-libmicrohttpd"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-libxslt mingw-w64-x86_64-libxslt"
# Hack for new MSys2
- copy C:\msys64\mingw32\i686-w64-mingw32\bin\ar.exe C:\msys64\mingw32\bin\i686-w64-mingw32-ar.exe
- copy C:\msys64\mingw32\i686-w64-mingw32\bin\ranlib.exe C:\msys64\mingw32\bin\i686-w64-mingw32-ranlib.exe
- copy C:\msys64\mingw32\bin\windres.exe C:\msys64\mingw32\bin\i686-w64-mingw32-windres.exe
- copy C:\msys64\mingw64\x86_64-w64-mingw32\bin\ar.exe C:\msys64\mingw64\bin\x86_64-w64-mingw32-ar.exe
- copy C:\msys64\mingw64\x86_64-w64-mingw32\bin\ranlib.exe C:\msys64\mingw64\bin\x86_64-w64-mingw32-ranlib.exe
- copy C:\msys64\mingw64\bin\windres.exe C:\msys64\mingw64\bin\x86_64-w64-mingw32-windres.exe
# Build missing Libs
- C:\msys64\mingw32_shell.bat -lc "cd /c/projects/RetroShare/msys2_build_libs/ && make"
# Clone RetroShare
#- git clone -q --branch={branch} https://github.com/RetroShare/RetroShare.git C:\projects\RetroShare
#---------------------------------#
# build configuration #
#---------------------------------#
# build platform, i.e. x86, x64, Any CPU. This setting is optional.
platform: x86
# to add several platforms to build matrix:
#platform:
# - x86
# - Any CPU
# build Configuration, i.e. Debug, Release, etc.
configuration: Release
# to add several configurations to build matrix:
#configuration:
# - Debug
# - Release
# scripts to run before build
before_build:
# scripts to run *after* solution is built and *before* automatic packaging occurs (web apps, NuGet packages, Azure Cloud Services)
before_package:
# scripts to run after build
after_build:
# to run your custom scripts instead of automatic MSBuild
build_script:
- cd C:\projects\RetroShare
- qmake
- make
# to disable automatic builds
#build: off
#---------------------------------#
# artifacts configuration #
#---------------------------------#
#artifacts:
#
# # pushing a single file
# - path: test.zip
#
# # pushing a single file with environment variable in path and "Deployment name" specified
# - path: MyProject\bin\$(configuration)
# name: myapp
#
# # pushing entire folder as a zip archive
# - path: logs
#---------------------------------#
# deployment configuration #
#---------------------------------#
#No deployment under unknown computer!!!
#---------------------------------#
# global handlers #
#---------------------------------#
# on successful build
#on_success:
# - do something
# on build failure
#on_failure:
# - do something
# after build failure or success
#on_finish:
# - do something
#---------------------------------#
# notifications #
#---------------------------------#
notifications:
# Email
- provider: Email
to:
- retrosharephenom@gmail.com
subject: 'Build {{status}}' # optional
message: "{{message}}, {{commitId}}, ..." # optional
on_build_status_changed: true

View File

@ -7,8 +7,8 @@ Group: Productivity/Networking/Other
URL: http://retroshare.sourceforge.net/
Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
Requires: qt-x11
BuildRequires: gcc-c++ qt-devel desktop-file-utils libgnome-keyring-devel glib2-devel libssh-devel protobuf-devel libcurl-devel libxml2-devel libxslt-devel openssl-devel libXScrnSaver-devel libupnp-devel bzip2-devel libmicrohttpd-devel
Requires: qt5-qtbase-gui qt5-qtmultimedia qt5-qtx11extras qt5-qtbase
BuildRequires: gcc-c++ desktop-file-utils libgnome-keyring-devel glib2-devel libssh-devel protobuf-devel libcurl-devel libxml2-devel libxslt-devel openssl-devel libXScrnSaver-devel libupnp-devel bzip2-devel libmicrohttpd-devel qt5-qtx11extras-devel qt5-qttools-devel qt5-qtmultimedia-devel qt5-qttools-static
# This is because of sqlcipher:
BuildRequires: tcl
@ -56,7 +56,7 @@ cd lib/sqlcipher
make
cd -
cd src
qmake-qt4 "CONFIG-=debug" "CONFIG+=release" PREFIX=%{_prefix} LIB_DIR=%{_libdir} RetroShare.pro
qmake-qt5 "CONFIG-=debug" "CONFIG+=release" PREFIX=%{_prefix} LIB_DIR=%{_libdir} RetroShare.pro
make
cd -

View File

@ -888,7 +888,12 @@ void ChatHandler::handleClearLobby(Request &req, Response &resp)
{
ChatLobbyId id = 0;
req.mStream << makeKeyValueReference("id", id);
notifyChatCleared(ChatId(id));
if (id !=0) {
notifyChatCleared(ChatId(id));
} else {
//Is BroadCast
notifyChatCleared(ChatId("B"));
}
resp.setOk();
}

View File

@ -211,6 +211,26 @@ function lobby(lobbyid){
}
)
]
} else {
if (lobdt.subscribed != undefined
&& lobdt.subscribed
&& lobdt.is_broadcast
) {
//set participants
particips = [
m("div.btn", {
style: {
"text-align":"center"
},
onclick: function (){
rs.request("chat/clear_lobby",{
lobbyid,
});
m.route("/chat?lobby=" + lobbyid);
}
},"clear"),
]
}
}
return [
intro,

View File

@ -1163,8 +1163,10 @@ bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId,
if(mNetService != NULL)
mNetService->subscribeStatusChanged(grpId,subscribe) ;
#ifdef GEN_EXCH_DEBUG
else
std::cerr << "(EE) No mNetService in RsGenExchange for service 0x" << std::hex << mServType << std::dec << std::endl;
#endif
return true;
}

View File

@ -208,6 +208,7 @@
#include "retroshare/rsgxsflags.h"
#include "retroshare/rsgxscircles.h"
#include "pgp/pgpauxutils.h"
#include "util/rsdir.h"
#include "util/rsmemory.h"
#include "util/stacktrace.h"
@ -604,6 +605,21 @@ public:
std::vector<T*>::clear() ;
}
};
RsGxsGroupId RsGxsNetService::hashGrpId(const RsGxsGroupId& gid,const RsPeerId& pid)
{
static const uint32_t SIZE = RsGxsGroupId::SIZE_IN_BYTES + RsPeerId::SIZE_IN_BYTES ;
unsigned char tmpmem[SIZE];
uint32_t offset = 0 ;
pid.serialise(tmpmem,SIZE,offset) ;
gid.serialise(tmpmem,SIZE,offset) ;
assert(RsGxsGroupId::SIZE_IN_BYTES <= Sha1CheckSum::SIZE_IN_BYTES) ;
return RsGxsGroupId( RsDirUtil::sha1sum(tmpmem,SIZE).toByteArray() );
}
void RsGxsNetService::syncWithPeers()
{
#ifdef NXS_NET_DEBUG_0
@ -742,43 +758,24 @@ void RsGxsNetService::syncWithPeers()
RsNxsSyncMsgReqItem* msg = new RsNxsSyncMsgReqItem(mServType);
msg->clear();
msg->PeerId(peerId);
msg->grpId = grpId;
msg->updateTS = updateTS;
if(encrypt_to_this_circle_id.isNull())
{
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_PG(*sit,grpId) << " Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself - in clear " << std::endl;
#endif
sendItem(msg);
}
msg->grpId = grpId;
else
{
msg->grpId = hashGrpId(grpId,mNetMgr->getOwnId()) ;
msg->flag |= RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID ;
}
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_PG(*sit,grpId) << " Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself - encrypted for circle " << encrypt_to_this_circle_id << std::endl;
GXSNETDEBUG_PG(*sit,grpId) << " Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself - in clear " << std::endl;
#endif
RsNxsItem *encrypted_item = NULL ;
uint32_t status ;
if(encryptSingleNxsItem(msg, encrypt_to_this_circle_id, grpId, encrypted_item, status))
sendItem(encrypted_item) ;
else
std::cerr << "(WW) could not encrypt for circle ID " << encrypt_to_this_circle_id << ". Not yet in cache?" << std::endl;
delete msg ;
}
sendItem(msg);
#ifdef NXS_NET_DEBUG_5
GXSNETDEBUG_PG(*sit,grpId) << "Service "<< std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending global message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself" << std::endl;
#endif
//}
//else
//{
// delete msg ;
//#ifdef NXS_NET_DEBUG_0
// GXSNETDEBUG_PG(*sit,grpId) << " cancel RsNxsSyncMsg req (last local update TS for group+peer) for grpId=" << grpId << " to peer " << *sit << ": not enough bandwidth." << std::endl;
//#endif
//}
}
}
@ -3686,7 +3683,9 @@ bool RsGxsNetService::encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId&
if(recipients.empty())
{
std::cerr << " (EE) No recipients found for circle " << destination_circle << ". Circle not in cache, or empty circle?" << std::endl;
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_(item->PeerId()) << " (EE) No recipients found for circle " << destination_circle << ". Circle not in cache, or empty circle?" << std::endl;
#endif
return false ;
}
@ -4342,28 +4341,53 @@ bool RsGxsNetService::checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxs
return true;
}
bool RsGxsNetService::locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem *item)
bool RsGxsNetService::locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item,bool& grp_is_known)
{
// Do we have new updates for this peer?
// Here we compare times in the same clock: the friend's clock, so it should be fine.
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(item->grpId);
grp_is_known = false ;
if(item->flag & RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID)
{
// Item contains the hashed group ID in order to protect is from friends who don't know it. So we de-hash it using bruteforce over known group IDs for this peer.
// We could save the de-hash result. But the cost is quite light, since the number of encrypted groups per service is usually low.
for(ServerMsgMap::const_iterator it(mServerMsgUpdateMap.begin());it!=mServerMsgUpdateMap.end();++it)
if(item->grpId == hashGrpId(it->first,item->PeerId()))
{
item->grpId = it->first ;
item->flag &= ~RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID;
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "(II) de-hashed group ID " << it->first << " from hash " << item->grpId << " and peer id " << item->PeerId() << std::endl;
#endif
grp_is_known = true ;
return item->updateTS < it->second->msgUpdateTS ;
}
return false ;
}
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(item->grpId);
if(cit != mServerMsgUpdateMap.end())
{
const RsGxsServerMsgUpdateItem *msui = cit->second;
const RsGxsServerMsgUpdateItem *msui = cit->second;
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " local time stamp: " << std::dec<< time(NULL) - msui->msgUpdateTS << " secs ago. Update sent: " << (item->updateTS < msui->msgUpdateTS) << std::endl;
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " local time stamp: " << std::dec<< time(NULL) - msui->msgUpdateTS << " secs ago. Update sent: " << (item->updateTS < msui->msgUpdateTS) << std::endl;
#endif
return item->updateTS < msui->msgUpdateTS ;
grp_is_known = true ;
return item->updateTS < msui->msgUpdateTS ;
}
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " no local time stamp for this grp. "<< std::endl;
#endif
return false;
}
void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_was_encrypted)
{
if (!item)
@ -4372,19 +4396,28 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_
RS_STACK_MUTEX(mNxsMutex) ;
const RsPeerId& peer = item->PeerId();
bool grp_is_known = false;
bool was_circle_protected = item_was_encrypted || bool(item->flag & RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID);
bool peer_can_receive_update = locked_CanReceiveUpdate(item, grp_is_known);
if(item_was_encrypted)
std::cerr << "(WW) got an encrypted msg sync req. from " << item->PeerId() << ". This will not send messages updates for group " << item->grpId << std::endl;
// Insert the PeerId in suppliers list for this grpId
#ifdef NXS_NET_DEBUG_6
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "RsGxsNetService::handleRecvSyncMessage(): Inserting PeerId " << item->PeerId() << " in suppliers list for group " << item->grpId << std::endl;
#endif
RsGroupNetworkStatsRecord& rec(mGroupNetworkStats[item->grpId]) ; // this creates it if needed
rec.suppliers.insert(peer) ;
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "handleRecvSyncMsg(): Received last update TS of group " << item->grpId << ", for peer " << peer << ", TS = " << time(NULL) - item->updateTS << " secs ago." ;
#endif
if(!locked_CanReceiveUpdate(item))
if(grp_is_known)
{
RsGroupNetworkStatsRecord& rec(mGroupNetworkStats[item->grpId]) ; // this creates it if needed. When the grp is unknown (and hashed) this will would create a unused entry
rec.suppliers.insert(peer) ;
}
if(!peer_can_receive_update)
{
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " no update will be sent." << std::endl;
@ -4413,10 +4446,10 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_
return ;
}
if( (grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL) != item_was_encrypted )
if( (grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL) != was_circle_protected )
{
std::cerr << "(EE) received a sync Msg request for group " << item->grpId << " from peer " << item->PeerId() ;
if(!item_was_encrypted)
if(!was_circle_protected)
std::cerr << ". The group is tied to an external circle (ID=" << grpMeta->mCircleId << ") but the request wasn't encrypted." << std::endl;
else
std::cerr << ". The group is not tied to an external circle (ID=" << grpMeta->mCircleId << ") but the request was encrypted." << std::endl;

View File

@ -384,8 +384,10 @@ private:
#endif
bool locked_CanReceiveUpdate(const RsNxsSyncGrpReqItem *item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem* item);
bool locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item, bool &grp_is_known);
static RsGxsGroupId hashGrpId(const RsGxsGroupId& gid,const RsPeerId& pid) ;
private:
typedef std::vector<RsNxsGrp*> GrpFragments;

View File

@ -110,10 +110,6 @@ peerConnectState::peerConnectState()
inConnAttempt(0),
wasDeniedConnection(false), deniedTS(false), deniedInConnAttempt(false)
{
//sockaddr_clear(&currentlocaladdr);
//sockaddr_clear(&currentserveraddr);
return;
}
std::string textPeerConnectState(peerConnectState &state)

View File

@ -129,7 +129,6 @@ class peerConnectState
time_t deniedTS;
bool deniedInConnAttempt; /* is below valid */
peerConnectAddress deniedConnectionAttempt;
};
class p3tunnel;
@ -312,7 +311,7 @@ bool addAddressIfUnique(std::list<peerConnectAddress> &addrList, peerConnectAdd
private:
// These should have there own Mutex Protection,
// These should have their own Mutex Protection,
//p3tunnel *mP3tunnel;
DNSResolver *mDNSResolver ;

View File

@ -1999,7 +1999,7 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
item->domain_addr = (it->second).hiddenDomain;
item->domain_port = (it->second).hiddenPort;
saveData.push_back(item);
saveCleanupList.push_back(item);
#ifdef PEER_DEBUG
@ -2009,6 +2009,10 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
#endif
}
RsPeerBandwidthLimitsItem *pblitem = new RsPeerBandwidthLimitsItem ;
pblitem->peers = mPeerBandwidthLimits ;
saveData.push_back(pblitem) ;
RsPeerServicePermissionItem *sitem = new RsPeerServicePermissionItem ;
for(std::map<RsPgpId,ServicePermissionFlags>::const_iterator it(mFriendsPermissionFlags.begin());it!=mFriendsPermissionFlags.end();++it)
@ -2016,7 +2020,7 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
sitem->pgp_ids.push_back(it->first) ;
sitem->service_flags.push_back(it->second) ;
}
saveData.push_back(sitem) ;
saveCleanupList.push_back(sitem);
@ -2072,6 +2076,61 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
return true;
}
bool p3PeerMgrIMPL::getMaxRates(const RsPeerId& pid,uint32_t& maxUp,uint32_t& maxDn)
{
RsPgpId pgp_id ;
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
std::map<RsPeerId, peerState>::const_iterator it = mFriendList.find(pid) ;
if(it == mFriendList.end())
return false ;
pgp_id = it->second.gpg_id ;
}
return getMaxRates(pgp_id,maxUp,maxDn) ;
}
bool p3PeerMgrIMPL::getMaxRates(const RsPgpId& pid,uint32_t& maxUp,uint32_t& maxDn)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
std::map<RsPgpId,PeerBandwidthLimits>::const_iterator it2 = mPeerBandwidthLimits.find(pid) ;
if(it2 != mPeerBandwidthLimits.end())
{
maxUp = it2->second.max_up_rate_kbs ;
maxDn = it2->second.max_dl_rate_kbs ;
return true ;
}
else
{
maxUp = 0;
maxDn = 0;
return false ;
}
}
bool p3PeerMgrIMPL::setMaxRates(const RsPgpId& pid,uint32_t maxUp,uint32_t maxDn)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
PeerBandwidthLimits& p(mPeerBandwidthLimits[pid]) ;
if(maxUp == p.max_up_rate_kbs && maxDn == p.max_dl_rate_kbs)
return true ;
std::cerr << "Updating max rates for peer " << pid << " to " << maxUp << " kB/s (up), " << maxDn << " kB/s (dn)" << std::endl;
p.max_up_rate_kbs = maxUp ;
p.max_dl_rate_kbs = maxDn ;
IndicateConfigChanged();
return true ;
}
void p3PeerMgrIMPL::saveDone()
{
/* clean up the save List */
@ -2090,276 +2149,288 @@ void p3PeerMgrIMPL::saveDone()
bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
{
// DEFAULTS.
bool useExtAddrFinder = true;
std::string proxyIpAddressTor = kConfigDefaultProxyServerIpAddr;
uint16_t proxyPortTor = kConfigDefaultProxyServerPortTor;
std::string proxyIpAddressI2P = kConfigDefaultProxyServerIpAddr;
uint16_t proxyPortI2P = kConfigDefaultProxyServerPortI2P;
// DEFAULTS.
bool useExtAddrFinder = true;
std::string proxyIpAddressTor = kConfigDefaultProxyServerIpAddr;
uint16_t proxyPortTor = kConfigDefaultProxyServerPortTor;
std::string proxyIpAddressI2P = kConfigDefaultProxyServerIpAddr;
uint16_t proxyPortI2P = kConfigDefaultProxyServerPortI2P;
if (load.empty()) {
std::cerr << "p3PeerMgrIMPL::loadList() list is empty, it may be a configuration problem." << std::endl;
return false;
}
if (load.empty()) {
std::cerr << "p3PeerMgrIMPL::loadList() list is empty, it may be a configuration problem." << std::endl;
return false;
}
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() Item Count: " << load.size() << std::endl;
std::cerr << "p3PeerMgrIMPL::loadList() Item Count: " << load.size() << std::endl;
#endif
RsPeerId ownId = getOwnId();
RsPeerId ownId = getOwnId();
/* load the list of peers */
std::list<RsItem *>::iterator it;
for(it = load.begin(); it != load.end(); ++it)
{
RsPeerNetItem *pitem = dynamic_cast<RsPeerNetItem *>(*it);
if (pitem)
{
RsPeerId peer_id = pitem->peerId ;
RsPgpId peer_pgp_id = pitem->pgpId ;
/* load the list of peers */
std::list<RsItem *>::iterator it;
for(it = load.begin(); it != load.end(); ++it)
{
RsPeerNetItem *pitem = dynamic_cast<RsPeerNetItem *>(*it);
if (pitem)
{
RsPeerId peer_id = pitem->peerId ;
RsPgpId peer_pgp_id = pitem->pgpId ;
if (peer_id == ownId)
{
if (peer_id == ownId)
{
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() Own Config Item:" << std::endl;
pitem->print(std::cerr, 10);
std::cerr << std::endl;
std::cerr << "p3PeerMgrIMPL::loadList() Own Config Item:" << std::endl;
pitem->print(std::cerr, 10);
std::cerr << std::endl;
#endif
/* add ownConfig */
setOwnNetworkMode(pitem->netMode);
setOwnVisState(pitem->vs_disc, pitem->vs_dht);
/* add ownConfig */
setOwnNetworkMode(pitem->netMode);
setOwnVisState(pitem->vs_disc, pitem->vs_dht);
mOwnState.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId();
mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation();
}
else
{
mOwnState.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId();
mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation();
}
else
{
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() Peer Config Item:" << std::endl;
pitem->print(std::cerr, 10);
std::cerr << std::endl;
std::cerr << "p3PeerMgrIMPL::loadList() Peer Config Item:" << std::endl;
pitem->print(std::cerr, 10);
std::cerr << std::endl;
#endif
/* ************* */
// permission flags is used as a mask for the existing perms, so we set it to 0xffff
addFriend(peer_id, peer_pgp_id, pitem->netMode, pitem->vs_disc, pitem->vs_dht, pitem->lastContact, RS_NODE_PERM_ALL);
setLocation(pitem->peerId, pitem->location);
}
/* ************* */
// permission flags is used as a mask for the existing perms, so we set it to 0xffff
addFriend(peer_id, peer_pgp_id, pitem->netMode, pitem->vs_disc, pitem->vs_dht, pitem->lastContact, RS_NODE_PERM_ALL);
setLocation(pitem->peerId, pitem->location);
}
if (pitem->netMode == RS_NET_MODE_HIDDEN)
{
/* set only the hidden stuff & localAddress */
setLocalAddress(peer_id, pitem->localAddrV4.addr);
setHiddenDomainPort(peer_id, pitem->domain_addr, pitem->domain_port);
if (pitem->netMode == RS_NET_MODE_HIDDEN)
{
/* set only the hidden stuff & localAddress */
setLocalAddress(peer_id, pitem->localAddrV4.addr);
setHiddenDomainPort(peer_id, pitem->domain_addr, pitem->domain_port);
}
else
{
setLocalAddress(peer_id, pitem->localAddrV4.addr);
setExtAddress(peer_id, pitem->extAddrV4.addr);
setDynDNS (peer_id, pitem->dyndns);
}
else
{
setLocalAddress(peer_id, pitem->localAddrV4.addr);
setExtAddress(peer_id, pitem->extAddrV4.addr);
setDynDNS (peer_id, pitem->dyndns);
/* convert addresses */
pqiIpAddrSet addrs;
addrs.mLocal.extractFromTlv(pitem->localAddrList);
addrs.mExt.extractFromTlv(pitem->extAddrList);
updateAddressList(peer_id, addrs);
}
/* convert addresses */
pqiIpAddrSet addrs;
addrs.mLocal.extractFromTlv(pitem->localAddrList);
addrs.mExt.extractFromTlv(pitem->extAddrList);
delete(*it);
updateAddressList(peer_id, addrs);
}
continue;
}
delete(*it);
RsConfigKeyValueSet *vitem = dynamic_cast<RsConfigKeyValueSet *>(*it) ;
if (vitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
continue;
}
RsConfigKeyValueSet *vitem = dynamic_cast<RsConfigKeyValueSet *>(*it) ;
if (vitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() General Variable Config Item:" << std::endl;
vitem->print(std::cerr, 10);
std::cerr << std::endl;
std::cerr << "p3PeerMgrIMPL::loadList() General Variable Config Item:" << std::endl;
vitem->print(std::cerr, 10);
std::cerr << std::endl;
#endif
std::list<RsTlvKeyValue>::iterator kit;
for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit)
{
if (kit->key == kConfigKeyExtIpFinder)
{
useExtAddrFinder = (kit->value == "TRUE");
std::list<RsTlvKeyValue>::iterator kit;
for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit)
{
if (kit->key == kConfigKeyExtIpFinder)
{
useExtAddrFinder = (kit->value == "TRUE");
#ifdef PEER_DEBUG
std::cerr << "setting use_extr_addr_finder to " << useExtAddrFinder << std::endl ;
std::cerr << "setting use_extr_addr_finder to " << useExtAddrFinder << std::endl ;
#endif
}
// Tor
else if (kit->key == kConfigKeyProxyServerIpAddrTor)
{
proxyIpAddressTor = kit->value;
}
// Tor
else if (kit->key == kConfigKeyProxyServerIpAddrTor)
{
proxyIpAddressTor = kit->value;
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyIpAddress for Tor: " << proxyIpAddressTor;
std::cerr << std::endl ;
std::cerr << "Loaded proxyIpAddress for Tor: " << proxyIpAddressTor;
std::cerr << std::endl ;
#endif
}
else if (kit->key == kConfigKeyProxyServerPortTor)
{
proxyPortTor = atoi(kit->value.c_str());
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyPort for Tor: " << proxyPortTor;
std::cerr << std::endl ;
#endif
}
// I2p
else if (kit->key == kConfigKeyProxyServerIpAddrI2P)
{
proxyIpAddressI2P = kit->value;
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyIpAddress for I2P: " << proxyIpAddressI2P;
std::cerr << std::endl ;
#endif
}
else if (kit->key == kConfigKeyProxyServerPortI2P)
{
proxyPortI2P = atoi(kit->value.c_str());
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyPort for I2P: " << proxyPortI2P;
std::cerr << std::endl ;
#endif
}
}
delete(*it);
}
else if (kit->key == kConfigKeyProxyServerPortTor)
{
proxyPortTor = atoi(kit->value.c_str());
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyPort for Tor: " << proxyPortTor;
std::cerr << std::endl ;
#endif
}
// I2p
else if (kit->key == kConfigKeyProxyServerIpAddrI2P)
{
proxyIpAddressI2P = kit->value;
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyIpAddress for I2P: " << proxyIpAddressI2P;
std::cerr << std::endl ;
#endif
}
else if (kit->key == kConfigKeyProxyServerPortI2P)
{
proxyPortI2P = atoi(kit->value.c_str());
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyPort for I2P: " << proxyPortI2P;
std::cerr << std::endl ;
#endif
}
}
continue;
}
delete(*it);
RsPeerGroupItem *gitem = dynamic_cast<RsPeerGroupItem *>(*it) ;
if (gitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
continue;
}
RsPeerGroupItem *gitem = dynamic_cast<RsPeerGroupItem *>(*it) ;
if (gitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() Peer group item:" << std::endl;
gitem->print(std::cerr, 10);
std::cerr << std::endl;
std::cerr << "p3PeerMgrIMPL::loadList() Peer group item:" << std::endl;
gitem->print(std::cerr, 10);
std::cerr << std::endl;
#endif
groupList.push_back(gitem); // don't delete
groupList.push_back(gitem); // don't delete
if ((gitem->flag & RS_GROUP_FLAG_STANDARD) == 0) {
/* calculate group id */
uint32_t groupId = atoi(gitem->id.c_str());
if (groupId > lastGroupId) {
lastGroupId = groupId;
}
}
if ((gitem->flag & RS_GROUP_FLAG_STANDARD) == 0) {
/* calculate group id */
uint32_t groupId = atoi(gitem->id.c_str());
if (groupId > lastGroupId) {
lastGroupId = groupId;
}
}
continue;
}
RsPeerServicePermissionItem *sitem = dynamic_cast<RsPeerServicePermissionItem*>(*it) ;
continue;
}
RsPeerBandwidthLimitsItem *pblitem = dynamic_cast<RsPeerBandwidthLimitsItem*>(*it) ;
if(sitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
if(pblitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
#ifdef PEER_DEBUG
std::cerr << "Loaded service permission item: " << std::endl;
std::cerr << "Loaded service permission item: " << std::endl;
#endif
mPeerBandwidthLimits = pblitem->peers ;
}
RsPeerServicePermissionItem *sitem = dynamic_cast<RsPeerServicePermissionItem*>(*it) ;
if(sitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
for(uint32_t i=0;i<sitem->pgp_ids.size();++i)
if(AuthGPG::getAuthGPG()->isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthGPG::getAuthGPG()->getGPGOwnId())
{
mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ;
#ifdef PEER_DEBUG
std::cerr << " " << sitem->pgp_ids[i] << " - " << sitem->service_flags[i] << std::endl;
std::cerr << "Loaded service permission item: " << std::endl;
#endif
}
for(uint32_t i=0;i<sitem->pgp_ids.size();++i)
if(AuthGPG::getAuthGPG()->isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthGPG::getAuthGPG()->getGPGOwnId())
{
mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ;
#ifdef PEER_DEBUG
else
std::cerr << " " << sitem->pgp_ids[i] << " - Not a friend!" << std::endl;
std::cerr << " " << sitem->pgp_ids[i] << " - " << sitem->service_flags[i] << std::endl;
#endif
}
}
#ifdef PEER_DEBUG
else
std::cerr << " " << sitem->pgp_ids[i] << " - Not a friend!" << std::endl;
#endif
}
delete (*it);
}
delete (*it);
}
{
/* set missing groupIds */
{
/* set missing groupIds */
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
/* Standard groups */
const int standardGroupCount = 5;
const char *standardGroup[standardGroupCount] = { RS_GROUP_ID_FRIENDS, RS_GROUP_ID_FAMILY, RS_GROUP_ID_COWORKERS, RS_GROUP_ID_OTHERS, RS_GROUP_ID_FAVORITES };
bool foundStandardGroup[standardGroupCount] = { false, false, false, false, false };
/* Standard groups */
const int standardGroupCount = 5;
const char *standardGroup[standardGroupCount] = { RS_GROUP_ID_FRIENDS, RS_GROUP_ID_FAMILY, RS_GROUP_ID_COWORKERS, RS_GROUP_ID_OTHERS, RS_GROUP_ID_FAVORITES };
bool foundStandardGroup[standardGroupCount] = { false, false, false, false, false };
std::list<RsPeerGroupItem *>::iterator groupIt;
for (groupIt = groupList.begin(); groupIt != groupList.end(); ++groupIt) {
if ((*groupIt)->flag & RS_GROUP_FLAG_STANDARD) {
int i;
for (i = 0; i < standardGroupCount; ++i) {
if ((*groupIt)->id == standardGroup[i]) {
foundStandardGroup[i] = true;
break;
}
}
if (i >= standardGroupCount) {
/* No more a standard group, remove the flag standard */
(*groupIt)->flag &= ~RS_GROUP_FLAG_STANDARD;
}
} else {
uint32_t groupId = atoi((*groupIt)->id.c_str());
if (groupId == 0) {
rs_sprintf((*groupIt)->id, "%lu", lastGroupId++);
}
}
}
/* Initialize standard groups */
for (int i = 0; i < standardGroupCount; ++i) {
if (foundStandardGroup[i] == false) {
RsPeerGroupItem *gitem = new RsPeerGroupItem;
gitem->id = standardGroup[i];
gitem->name = standardGroup[i];
gitem->flag |= RS_GROUP_FLAG_STANDARD;
groupList.push_back(gitem);
}
}
}
std::list<RsPeerGroupItem *>::iterator groupIt;
for (groupIt = groupList.begin(); groupIt != groupList.end(); ++groupIt) {
if ((*groupIt)->flag & RS_GROUP_FLAG_STANDARD) {
int i;
for (i = 0; i < standardGroupCount; ++i) {
if ((*groupIt)->id == standardGroup[i]) {
foundStandardGroup[i] = true;
break;
}
}
// If we are hidden - don't want ExtAddrFinder - ever!
if (isHidden())
{
useExtAddrFinder = false;
}
if (i >= standardGroupCount) {
/* No more a standard group, remove the flag standard */
(*groupIt)->flag &= ~RS_GROUP_FLAG_STANDARD;
}
} else {
uint32_t groupId = atoi((*groupIt)->id.c_str());
if (groupId == 0) {
rs_sprintf((*groupIt)->id, "%lu", lastGroupId++);
}
}
}
mNetMgr->setIPServersEnabled(useExtAddrFinder);
/* Initialize standard groups */
for (int i = 0; i < standardGroupCount; ++i) {
if (foundStandardGroup[i] == false) {
RsPeerGroupItem *gitem = new RsPeerGroupItem;
gitem->id = standardGroup[i];
gitem->name = standardGroup[i];
gitem->flag |= RS_GROUP_FLAG_STANDARD;
groupList.push_back(gitem);
}
}
}
// Configure Proxy Server.
struct sockaddr_storage proxy_addr;
// Tor
sockaddr_storage_clear(proxy_addr);
sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressTor.c_str());
sockaddr_storage_ipv4_setport(proxy_addr, proxyPortTor);
// If we are hidden - don't want ExtAddrFinder - ever!
if (isHidden())
{
useExtAddrFinder = false;
}
if (sockaddr_storage_isValidNet(proxy_addr))
{
setProxyServerAddress(RS_HIDDEN_TYPE_TOR, proxy_addr);
}
mNetMgr->setIPServersEnabled(useExtAddrFinder);
// I2P
sockaddr_storage_clear(proxy_addr);
sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressI2P.c_str());
sockaddr_storage_ipv4_setport(proxy_addr, proxyPortI2P);
// Configure Proxy Server.
struct sockaddr_storage proxy_addr;
// Tor
sockaddr_storage_clear(proxy_addr);
sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressTor.c_str());
sockaddr_storage_ipv4_setport(proxy_addr, proxyPortTor);
if (sockaddr_storage_isValidNet(proxy_addr))
{
setProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy_addr);
}
if (sockaddr_storage_isValidNet(proxy_addr))
{
setProxyServerAddress(RS_HIDDEN_TYPE_TOR, proxy_addr);
}
load.clear() ;
return true;
// I2P
sockaddr_storage_clear(proxy_addr);
sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressI2P.c_str());
sockaddr_storage_ipv4_setport(proxy_addr, proxyPortI2P);
if (sockaddr_storage_isValidNet(proxy_addr))
{
setProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy_addr);
}
load.clear() ;
return true;
}

View File

@ -102,6 +102,8 @@ class peerState
std::string location;
std::string name;
uint32_t maxUpRate ;
uint32_t maxDnRate ;
};
class RsPeerGroupItem;
@ -207,6 +209,9 @@ virtual uint32_t getHiddenType(const RsPeerId &ssl_id) = 0;
virtual int getFriendCount(bool ssl, bool online) = 0;
virtual bool setMaxRates(const RsPgpId& pid,uint32_t maxUp,uint32_t maxDn)=0;
virtual bool getMaxRates(const RsPgpId& pid,uint32_t& maxUp,uint32_t& maxDn)=0;
virtual bool getMaxRates(const RsPeerId& pid,uint32_t& maxUp,uint32_t& maxDn)=0;
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
@ -321,6 +326,9 @@ virtual int getFriendCount(bool ssl, bool online);
// Single Use Function... shouldn't be here. used by p3serverconfig.cc
virtual bool haveOnceConnected();
virtual bool setMaxRates(const RsPgpId& pid,uint32_t maxUp,uint32_t maxDn);
virtual bool getMaxRates(const RsPgpId& pid,uint32_t& maxUp,uint32_t& maxDn);
virtual bool getMaxRates(const RsPeerId& pid,uint32_t& maxUp,uint32_t& maxDn);
/************************************************************************************************/
/* Extra IMPL Functions (used by p3LinkMgr, p3NetMgr + Setup) */
@ -392,6 +400,7 @@ private:
std::list<RsItem *> saveCleanupList; /* TEMPORARY LIST WHEN SAVING */
std::map<RsPgpId, ServicePermissionFlags> mFriendsPermissionFlags ; // permission flags for each gpg key
std::map<RsPgpId, PeerBandwidthLimits> mPeerBandwidthLimits ; // bandwidth limits for each gpg key
struct sockaddr_storage mProxyServerAddressTor;
struct sockaddr_storage mProxyServerAddressI2P;

View File

@ -80,103 +80,103 @@ class RateInterface
public:
RateInterface()
:bw_in(0), bw_out(0), bwMax_in(0), bwMax_out(0),
bwCapEnabled(false), bwCap_in(0), bwCap_out(0) { return; }
:bw_in(0), bw_out(0), bwMax_in(0), bwMax_out(0),
bwCapEnabled(false), bwCap_in(0), bwCap_out(0) { return; }
virtual ~RateInterface() { return; }
virtual ~RateInterface() { return; }
virtual void getRates(RsBwRates &rates)
{
rates.mRateIn = bw_in;
rates.mRateOut = bw_out;
rates.mMaxRateIn = bwMax_in;
rates.mMaxRateOut = bwMax_out;
return;
}
virtual int gatherStatistics(std::list<RSTrafficClue>& /* outqueue_lst */,std::list<RSTrafficClue>& /* inqueue_lst */) { return 0;}
virtual int getQueueSize(bool /* in */) { return 0;}
virtual float getRate(bool in)
virtual void getRates(RsBwRates &rates)
{
if (in)
return bw_in;
return bw_out;
rates.mRateIn = bw_in;
rates.mRateOut = bw_out;
rates.mMaxRateIn = bwMax_in;
rates.mMaxRateOut = bwMax_out;
return;
}
virtual float getMaxRate(bool in)
virtual int gatherStatistics(std::list<RSTrafficClue>& /* outqueue_lst */,std::list<RSTrafficClue>& /* inqueue_lst */) { return 0;}
virtual int getQueueSize(bool /* in */) { return 0;}
virtual float getRate(bool in)
{
if (in)
return bwMax_in;
return bwMax_out;
if (in)
return bw_in;
return bw_out;
}
virtual void setMaxRate(bool in, float val)
virtual float getMaxRate(bool in)
{
if (in)
if (in)
return bwMax_in;
return bwMax_out;
}
virtual void setMaxRate(bool in, float val)
{
bwMax_in = val;
if (bwCapEnabled)
if (in)
{
if (bwMax_in > bwCap_in)
bwMax_in = val;
if (bwCapEnabled)
{
bwMax_in = bwCap_in;
if (bwMax_in > bwCap_in)
{
bwMax_in = bwCap_in;
}
}
}
}
else
{
bwMax_out = val;
if (bwCapEnabled)
else
{
if (bwMax_out > bwCap_out)
bwMax_out = val;
if (bwCapEnabled)
{
bwMax_out = bwCap_out;
if (bwMax_out > bwCap_out)
{
bwMax_out = bwCap_out;
}
}
}
}
return;
return;
}
virtual void setRateCap(float val_in, float val_out)
{
if ((val_in == 0) && (val_out == 0))
virtual void setRateCap(float val_in, float val_out)
{
if ((val_in == 0) && (val_out == 0))
{
#ifdef DEBUG_RATECAP
std::cerr << "RateInterface::setRateCap() Now disabled" << std::endl;
std::cerr << "RateInterface::setRateCap() Now disabled" << std::endl;
#endif
bwCapEnabled = false;
}
else
{
bwCapEnabled = false;
}
else
{
#ifdef DEBUG_RATECAP
std::cerr << "RateInterface::setRateCap() Enabled ";
std::cerr << "in: " << bwCap_in << " out: " << bwCap_out << std::endl;
std::cerr << "RateInterface::setRateCap() Enabled ";
std::cerr << "in: " << bwCap_in << " out: " << bwCap_out << std::endl;
#endif
bwCapEnabled = true;
bwCap_in = val_in;
bwCap_out = val_out;
bwCapEnabled = true;
bwCap_in = val_in;
bwCap_out = val_out;
}
return;
}
return;
}
protected:
void setRate(bool in, float val)
virtual void setRate(bool in, float val)
{
if (in)
bw_in = val;
else
bw_out = val;
return;
if (in)
bw_in = val;
else
bw_out = val;
return;
}
private:
float bw_in, bw_out, bwMax_in, bwMax_out;
bool bwCapEnabled;
float bwCap_in, bwCap_out;
private:
float bw_in, bw_out, bwMax_in, bwMax_out;
bool bwCapEnabled;
float bwCap_in, bwCap_out;
};

View File

@ -27,6 +27,7 @@
#include "util/rsdebug.h"
#include "util/rsstring.h"
#include "retroshare/rspeers.h"
#include <stdlib.h>
#include <time.h>
@ -69,18 +70,19 @@ static const float PQI_HANDLER_NB_PRIORITY_RATIO = 2 ;
pqihandler::pqihandler() : coreMtx("pqihandler")
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
// setup minimal total+individual rates.
rateIndiv_out = 0.01;
rateIndiv_in = 0.01;
rateMax_out = 0.01;
// setup minimal total+individual rates.
rateIndiv_out = 0.01;
rateIndiv_in = 0.01;
rateMax_out = 0.01;
rateMax_in = 0.01;
rateTotal_in = 0.0 ;
rateTotal_out = 0.0 ;
last_m = time(NULL) ;
nb_ticks = 0 ;
ticks_per_sec = 5 ; // initial guess
nb_ticks = 0 ;
mLastRateCapUpdate = 0 ;
ticks_per_sec = 5 ; // initial guess
return;
}
@ -113,27 +115,27 @@ int pqihandler::tick()
moreToTick = 1;
}
#endif
}
}
// static time_t last_print_time = 0 ;
// time_t now = time(NULL) ;
// if(now > last_print_time + 3)
// {
// std::map<uint16_t,uint32_t> per_service_count ;
// std::vector<uint32_t> per_priority_count ;
//
// ExtractOutQueueStatistics(per_service_count,per_priority_count) ;
//
// std::cerr << "PQIHandler outqueues: " << std::endl;
//
// for(std::map<uint16_t,uint32_t>::const_iterator it=per_service_count.begin();it!=per_service_count.end();++it)
// std::cerr << " " << std::hex << it->first << std::dec << " " << it->second << std::endl;
//
// for(int i=0;i<per_priority_count.size();++i)
// std::cerr << " " << i << " : " << per_priority_count[i] << std::endl;
//
// last_print_time = now ;
// }
time_t now = time(NULL) ;
if(now > mLastRateCapUpdate + 5)
{
// every 5 secs, update the max rates for all modules
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
for(std::map<RsPeerId, SearchModule *>::iterator it = mods.begin(); it != mods.end(); ++it)
{
// This is rather inelegant, but pqihandler has searchModules that are dynamically allocated, so the max rates
// need to be updated from inside.
uint32_t maxUp,maxDn ;
rsPeers->getPeerMaximumRates(it->first,maxUp,maxDn);
it->second->pqi->setRateCap(maxDn,maxUp);// mind the order! Dn first, than Up.
}
mLastRateCapUpdate = now ;
}
UpdateRates();
return moreToTick;
@ -277,144 +279,6 @@ int pqihandler::SendRsRawItem(RsRawItem *ns)
return queueOutRsItem(ns) ;
}
#ifdef TO_BE_REMOVED
// inputs. This is a very basic
// system that is completely biased and slow...
// someone please fix.
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// THIS CODE SHOULD BE ABLE TO BE REMOVED!
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
int pqihandler::locked_GetItems()
{
std::map<RsPeerId, SearchModule *>::iterator it;
RsItem *item;
int count = 0;
// loop through modules....
for(it = mods.begin(); it != mods.end(); ++it)
{
SearchModule *mod = (it -> second);
// check security... is output allowed.
if(0 < secpolicy_check((it -> second) -> sp,
0, PQI_INCOMING)) // PQI_ITEM_TYPE_ITEM, PQI_INCOMING))
{
// if yes... attempt to read.
while((item = (mod -> pqi) -> GetItem()) != NULL)
{
static int ntimes =0 ;
// if(++ntimes < 20)
{
std::cerr << "pqihandler::locked_GetItems() pqi->GetItem()";
std::cerr << " should never happen anymore!";
std::cerr << std::endl;
}
#ifdef RSITEM_DEBUG
std::string out;
rs_sprintf(out, "pqihandler::GetItems() Incoming Item from: %p\n", mod -> pqi);
item -> print_string(out);
pqioutput(PQL_DEBUG_BASIC,
pqihandlerzone, out);
#endif
if (item->PeerId() != (mod->pqi)->PeerId())
{
/* ERROR */
pqioutput(PQL_ALERT,
pqihandlerzone, "ERROR PeerIds dont match!");
item->PeerId(mod->pqi->PeerId());
}
locked_SortnStoreItem(item);
count++;
}
}
else
{
// not allowed to recieve from here....
while((item = (mod -> pqi) -> GetItem()) != NULL)
{
std::string out;
rs_sprintf(out, "pqihandler::GetItems() Incoming Item from: %p\n", mod -> pqi);
item -> print_string(out);
out += "\nItem Not Allowed (Sec Pol). deleting!";
pqioutput(PQL_DEBUG_BASIC,
pqihandlerzone, out);
delete item;
}
}
}
return count;
}
void pqihandler::locked_SortnStoreItem(RsItem *item)
{
/* get class type / subtype out of the item */
uint8_t vers = item -> PacketVersion();
/* whole Version reserved for SERVICES/CACHES */
if (vers == RS_PKT_VERSION_SERVICE)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Service");
in_service.push_back(item);
item = NULL;
return;
}
std::cerr << "pqihandler::locked_SortnStoreItem() : unhandled item! Will be deleted. This is certainly a bug." << std::endl;
if (vers != RS_PKT_VERSION1)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> Invalid VERSION! Deleting!");
delete item;
item = NULL;
return;
}
if (item)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> Deleting Unsorted Item");
delete item;
}
return;
}
RsRawItem *pqihandler::GetRsRawItem()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in_service.size() != 0)
{
RsRawItem *fi = dynamic_cast<RsRawItem *>(in_service.front());
if (!fi) { delete in_service.front(); }
in_service.pop_front();
return fi;
}
return NULL;
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// ABOVE CODE SHOULD BE ABLE TO BE REMOVED!
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
#endif
static const float MIN_RATE = 0.01; // 10 B/s
int pqihandler::ExtractTrafficInfo(std::list<RSTrafficClue>& out_lst,std::list<RSTrafficClue>& in_lst)
{
in_lst.clear() ;
@ -640,6 +504,7 @@ int pqihandler::UpdateRates()
for(it = mods.begin(); it != mods.end(); ++it)
{
SearchModule *mod = (it -> second);
mod -> pqi -> setMaxRate(true, in_max_bw);
mod -> pqi -> setMaxRate(false, out_max_bw);
}
@ -649,18 +514,10 @@ int pqihandler::UpdateRates()
for(it = mods.begin(); it != mods.end(); ++it)
{
SearchModule *mod = (it -> second);
if (mod -> pqi -> getMaxRate(false) < max_out_effective) {
mod -> pqi -> setMaxRate(false, max_out_effective);
}
if (mod -> pqi -> getMaxRate(false) > avail_out) {
mod -> pqi -> setMaxRate(false, avail_out);
}
if (mod -> pqi -> getMaxRate(true) < max_in_effective) {
mod -> pqi -> setMaxRate(true, max_in_effective);
}
if (mod -> pqi -> getMaxRate(true) > avail_in) {
mod -> pqi -> setMaxRate(true, avail_in);
}
if (mod -> pqi -> getMaxRate(false) < max_out_effective) mod -> pqi -> setMaxRate(false, max_out_effective);
if (mod -> pqi -> getMaxRate(false) > avail_out) mod -> pqi -> setMaxRate(false, avail_out);
if (mod -> pqi -> getMaxRate(true) < max_in_effective) mod -> pqi -> setMaxRate(true, max_in_effective);
if (mod -> pqi -> getMaxRate(true) > avail_in) mod -> pqi -> setMaxRate(true, avail_in);
}
return 1;

View File

@ -39,8 +39,10 @@
class SearchModule
{
public:
RsPeerId peerid;
PQInterface *pqi;
SearchModule() : pqi(NULL) {}
RsPeerId peerid ;
PQInterface *pqi;
};
// Presents a P3 Face to the world!
@ -71,14 +73,18 @@ class pqihandler: public P3Interface, public pqiPublisher
#endif
// rate control.
//void setMaxRate(const RsPeerId& pid,bool in, uint32_t val_kBs);
void setMaxRate(bool in, float val);
float getMaxRate(bool in);
void setMaxRates(const RsPeerId& pid,bool in,float val) ;
float getMaxRates(const RsPeerId& pid,bool in) ;
void getCurrentRates(float &in, float &out);
// TESTING INTERFACE.
int ExtractRates(std::map<RsPeerId, RsBwRates> &ratemap, RsBwRates &totals);
int ExtractTrafficInfo(std::list<RSTrafficClue> &out_lst, std::list<RSTrafficClue> &in_lst);
int ExtractTrafficInfo(std::list<RSTrafficClue> &out_lst, std::list<RSTrafficClue> &in_lst);
protected:
/* check to be overloaded by those that can
@ -115,6 +121,7 @@ protected:
uint32_t nb_ticks ;
time_t last_m ;
time_t mLastRateCapUpdate ;
float ticks_per_sec ;
};

View File

@ -374,11 +374,15 @@ int pqissllistenbase::acceptconnection()
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
std::cerr << "(II) Checking incoming connection address: " << sockaddr_storage_iptostring(remote_addr) ;
if(rsBanList != NULL && !rsBanList->isAddressAccepted(remote_addr, RSBANLIST_CHECKING_FLAGS_BLACKLIST))
{
std::cerr << "(II) pqissllistenner::acceptConnection(): early denying connection attempt from blacklisted IP " << sockaddr_storage_iptostring(remote_addr) << std::endl;
std::cerr << " => early rejected at this point, because of blacklist." << std::endl;
return false ;
}
else
std::cerr << " => Accepted (i.e. whitelisted, or not blacklisted)." << std::endl;
{
std::string out;
out += "Accepted Connection from ";

View File

@ -615,6 +615,9 @@ bool pqissludp::moretoread(uint32_t usec)
reset_locked();
return 0;
}
if(SSL_pending(ssl_connection) > 0)
return 1 ;
/* otherwise - not error - strange! */
rslog(RSL_DEBUG_BASIC, pqissludpzone,

View File

@ -406,7 +406,11 @@ bool pqiSSLstore::encryptedSendItems(const std::list<RsItem*>& rsItemList)
if(rsSerialiser->serialise(*it, &data[offset],&sizeItem))
offset += sizeItem;
else
std::cerr << "(EE) pqiSSLstore::encryptedSendItems(): One item did not serialize. The item is probably unknown from the serializer. Dropping the item. " << std::endl;
{
std::cerr << "(EE) pqiSSLstore::encryptedSendItems(): One item did not serialize. The item is probably unknown from the serializer. Dropping the item. " << std::endl;
std::cerr << "Item content: " << std::endl;
(*it)->print(std::cerr) ;
}
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete *it;

View File

@ -77,37 +77,38 @@ pqistreamer::pqistreamer(RsSerialiser *rss, const RsPeerId& id, BinInterface *bi
mCurrRead(0), mCurrSent(0),
mAvgReadCount(0), mAvgSentCount(0)
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
// 100 B/s (minimal)
setMaxRate(true, 0.1);
setMaxRate(false, 0.1);
setRate(true, 0); // needs to be off-mutex
setRate(false, 0);
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
mAcceptsPacketSlicing = false ; // by default. Will be turned into true when everyone's ready.
mLastSentPacketSlicingProbe = 0 ;
mAvgLastUpdate = mCurrReadTS = mCurrSentTS = time(NULL);
mIncomingSize = 0 ;
mStatisticsTimeStamp = 0 ;
/* allocated once */
/* allocated once */
mPkt_rpend_size = 0;
mPkt_rpending = 0;
mReading_state = reading_state_initial ;
mReading_state = reading_state_initial ;
// 100 B/s (minimal)
setMaxRate(true, 0.1);
setMaxRate(false, 0.1);
setRate(true, 0);
setRate(false, 0);
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::pqistreamer() Initialisation!");
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::pqistreamer() Initialisation!");
if (!bio_in)
{
pqioutput(PQL_ALERT, pqistreamerzone, "pqistreamer::pqistreamer() NULL bio, FATAL ERROR!");
exit(1);
}
if (!bio_in)
{
pqioutput(PQL_ALERT, pqistreamerzone, "pqistreamer::pqistreamer() NULL bio, FATAL ERROR!");
exit(1);
}
mFailed_read_attempts = 0; // reset failed read, as no packet is still read.
mFailed_read_attempts = 0; // reset failed read, as no packet is still read.
return;
return;
}
pqistreamer::~pqistreamer()
@ -195,18 +196,39 @@ RsItem *pqistreamer::GetItem()
return osr;
}
float pqistreamer::getRate(bool b)
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
return RateInterface::getRate(b) ;
}
void pqistreamer::setMaxRate(bool b,float f)
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
RateInterface::setMaxRate(b,f) ;
}
void pqistreamer::setRate(bool b,float f)
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
RateInterface::setRate(b,f) ;
}
void pqistreamer::updateRates()
{
// now update rates both ways.
time_t t = time(NULL); // get current timestep.
int64_t diff ;
if (t > mAvgLastUpdate + PQISTREAM_AVG_PERIOD)
{
int64_t diff = int64_t(t) - int64_t(mAvgLastUpdate) ;
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
float avgReadpSec = getRate(true ) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgReadCount/(1000.0 * float(diff));
float avgSentpSec = getRate(false) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgSentCount/(1000.0 * float(diff));
diff = int64_t(t) - int64_t(mAvgLastUpdate) ;
}
if (diff > PQISTREAM_AVG_PERIOD)
{
float avgReadpSec = getRate(true ) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgReadCount/(1024.0 * float(diff));
float avgSentpSec = getRate(false) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgSentCount/(1024.0 * float(diff));
#ifdef DEBUG_PQISTREAMER
std::cerr << "Peer " << PeerId() << ": Current speed estimates: " << avgReadpSec << " / " << avgSentpSec << std::endl;
@ -226,9 +248,12 @@ void pqistreamer::updateRates()
setRate(false, 0);
}
mAvgLastUpdate = t;
mAvgReadCount = 0;
mAvgSentCount = 0;
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
mAvgLastUpdate = t;
mAvgReadCount = 0;
mAvgSentCount = 0;
}
}
}

View File

@ -67,6 +67,12 @@ class pqistreamer: public PQInterface
virtual void getRates(RsBwRates &rates);
virtual int getQueueSize(bool in); // extracting data.
virtual int gatherStatistics(std::list<RSTrafficClue>& outqueue_stats,std::list<RSTrafficClue>& inqueue_stats); // extracting data.
// mutex protected versions of RateInterface calls.
virtual void setRate(bool b,float f) ;
virtual void setMaxRate(bool b,float f) ;
virtual float getRate(bool b) ;
protected:
int tick_bio();
@ -85,7 +91,7 @@ class pqistreamer: public PQInterface
virtual int locked_gatherStatistics(std::list<RSTrafficClue>& outqueue_stats,std::list<RSTrafficClue>& inqueue_stats); // extracting data.
void updateRates() ;
protected:
RsMutex mStreamerMtx ; // Protects data, fns below, protected so pqiqos can use it too.
@ -148,8 +154,8 @@ class pqistreamer: public PQInterface
time_t mCurrSentTS;
time_t mAvgLastUpdate; // TS from which these are measured.
float mAvgReadCount;
float mAvgSentCount;
uint32_t mAvgReadCount;
uint32_t mAvgSentCount;
time_t mLastIncomingTs;

View File

@ -293,8 +293,8 @@ public:
/* Data Rate Control - to be moved here */
virtual int SetMaxDataRates( int downKb, int upKb ) = 0;
virtual int GetMaxDataRates( int &inKb, int &outKb ) = 0;
virtual int GetCurrentDataRates( float &inKb, float &outKb ) = 0;
};
#endif

View File

@ -61,7 +61,7 @@ template<int n> class t_RsFlags32
#define FLAGS_TAG_TRANSFER_REQS 0x4228af
#define FLAGS_TAG_FILE_STORAGE 0x184738
#define FLAGS_TAG_FILE_SEARCH 0xf29ba5
#define FLAGS_TAG_FILE_SEARCH 0xf29ba5
#define FLAGS_TAG_SERVICE_PERM 0x380912
#define FLAGS_TAG_SERVICE_CHAT 0x839042

View File

@ -112,6 +112,7 @@ class RsGxsCircleDetails
std::string mCircleName;
uint32_t mCircleType;
RsGxsCircleId mRestrictedCircleId;
bool mAmIAllowed ; // true when one of load GXS ids belong to the circle allowed list (admin list & subscribed list).
@ -123,32 +124,29 @@ class RsGxsCircleDetails
class RsGxsCircles: public RsGxsIfaceHelper
{
public:
RsGxsCircles(RsGxsIface *gxs)
:RsGxsIfaceHelper(gxs) { return; }
virtual ~RsGxsCircles() { return; }
public:
RsGxsCircles(RsGxsIface *gxs) :RsGxsIfaceHelper(gxs) { return; }
virtual ~RsGxsCircles() { return; }
/* External Interface (Cached stuff) */
virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details) = 0;
virtual bool getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
virtual bool getCirclePersonalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details) = 0;
virtual bool getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
virtual bool getCirclePersonalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
/* membership management for external circles */
virtual bool requestCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
virtual bool cancelCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
/* membership management for external circles */
virtual bool requestCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
virtual bool cancelCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
/* standard load */
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) = 0;
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) = 0;
/* make new group */
virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group) = 0;
/* update an existing group */
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) = 0;
/* make new group */
virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group) = 0;
/* update an existing group */
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) = 0;
};

View File

@ -428,6 +428,10 @@ public:
virtual ServicePermissionFlags servicePermissionFlags(const RsPgpId& gpg_id) = 0;
virtual ServicePermissionFlags servicePermissionFlags(const RsPeerId& ssl_id) = 0;
virtual void setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermissionFlags& flags) = 0;
virtual bool setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint32_t maxDownloadRate) =0;
virtual bool getPeerMaximumRates(const RsPeerId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate) =0;
virtual bool getPeerMaximumRates(const RsPgpId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate) =0;
};
#endif

View File

@ -118,6 +118,15 @@ class Condition
std::string name;
};
class PeerBandwidthLimits
{
public:
PeerBandwidthLimits() : max_up_rate_kbs(0), max_dl_rate_kbs(0) {}
uint32_t max_up_rate_kbs ;
uint32_t max_dl_rate_kbs ;
};
//class SearchRequest // unused stuff.
//{
// public:

View File

@ -35,6 +35,14 @@
#include <sqlcipher/sqlite3.h>
#endif
#ifndef RS_ENABLE_ZCNATASSIST
#ifdef RS_USE_LIBUPNP
#include "upnp/upnpconfig.h"
#else
#include "miniupnpc/miniupnpc.h"
#endif // RS_USE_LIBUPNP
#endif // RS_ENABLE_ZCNATASSIST
std::string RsServer::getSQLCipherVersion()
{
sqlite3* mDb;
@ -84,5 +92,12 @@ void RsServer::getLibraries(std::list<RsLibraryInfo> &libraries)
#ifndef NO_SQLCIPHER
libraries.push_back(RsLibraryInfo("SQLCipher", getSQLCipherVersion()));
#endif
#ifndef RS_ENABLE_ZCNATASSIST
#ifdef RS_USE_LIBUPNP
libraries.push_back(RsLibraryInfo("UPnP (libupnp)", UPNP_VERSION_STRING));
#else
libraries.push_back(RsLibraryInfo("UPnP (MiniUPnP)", MINIUPNPC_VERSION));
#endif // RS_USE_LIBUPNP
#endif // RS_ENABLE_ZCNATASSIST
libraries.push_back(RsLibraryInfo("Zlib", ZLIB_VERSION));
}

View File

@ -241,6 +241,20 @@ bool p3Peers::isFriend(const RsPeerId &ssl_id)
return mPeerMgr->isFriend(ssl_id);
}
bool p3Peers::getPeerMaximumRates(const RsPeerId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate)
{
return mPeerMgr->getMaxRates(pid,maxUploadRate,maxDownloadRate) ;
}
bool p3Peers::getPeerMaximumRates(const RsPgpId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate)
{
return mPeerMgr->getMaxRates(pid,maxUploadRate,maxDownloadRate) ;
}
bool p3Peers::setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint32_t maxDownloadRate)
{
return mPeerMgr->setMaxRates(pid,maxUploadRate,maxDownloadRate) ;
}
bool p3Peers::haveSecretKey(const RsPgpId& id)
{
return AuthGPG::getAuthGPG()->haveSecretKey(id);
@ -296,17 +310,17 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
d.hiddenNodeAddress = ps.hiddenDomain;
d.hiddenNodePort = ps.hiddenPort;
d.hiddenType = ps.hiddenType;
if(sockaddr_storage_isnull(ps.localaddr)) // that happens if the address is not initialised.
{
{
d.localAddr = "INVALID_IP";
d.localPort = 0 ;
}
else
{
}
else
{
d.localAddr = sockaddr_storage_iptostring(ps.localaddr);
d.localPort = sockaddr_storage_port(ps.localaddr);
}
}
d.extAddr = "hidden";
d.extPort = 0;
d.dyndns = "";
@ -341,10 +355,10 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
}
d.dyndns = ps.dyndns;
std::list<pqiIpAddress>::iterator it;
for(it = ps.ipAddrs.mLocal.mAddrs.begin();
it != ps.ipAddrs.mLocal.mAddrs.end(); ++it)
it != ps.ipAddrs.mLocal.mAddrs.end(); ++it)
{
std::string toto;
toto += "L:";
@ -352,8 +366,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
rs_sprintf_append(toto, " %ld sec", time(NULL) - it->mSeenTime);
d.ipAddressList.push_back(toto);
}
for(it = ps.ipAddrs.mExt.mAddrs.begin();
it != ps.ipAddrs.mExt.mAddrs.end(); ++it)
for(it = ps.ipAddrs.mExt.mAddrs.begin(); it != ps.ipAddrs.mExt.mAddrs.end(); ++it)
{
std::string toto;
toto += "E:";
@ -362,33 +375,32 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
d.ipAddressList.push_back(toto);
}
}
switch(ps.netMode & RS_NET_MODE_ACTUAL)
{
case RS_NET_MODE_EXT:
d.netMode = RS_NETMODE_EXT;
break;
case RS_NET_MODE_UPNP:
d.netMode = RS_NETMODE_UPNP;
break;
case RS_NET_MODE_UDP:
d.netMode = RS_NETMODE_UDP;
break;
case RS_NET_MODE_HIDDEN:
d.netMode = RS_NETMODE_HIDDEN;
break;
case RS_NET_MODE_UNREACHABLE:
case RS_NET_MODE_UNKNOWN:
default:
d.netMode = RS_NETMODE_UNREACHABLE;
break;
case RS_NET_MODE_EXT:
d.netMode = RS_NETMODE_EXT;
break;
case RS_NET_MODE_UPNP:
d.netMode = RS_NETMODE_UPNP;
break;
case RS_NET_MODE_UDP:
d.netMode = RS_NETMODE_UDP;
break;
case RS_NET_MODE_HIDDEN:
d.netMode = RS_NETMODE_HIDDEN;
break;
case RS_NET_MODE_UNREACHABLE:
case RS_NET_MODE_UNKNOWN:
default:
d.netMode = RS_NETMODE_UNREACHABLE;
break;
}
d.vs_disc = ps.vs_disc;
d.vs_dht = ps.vs_dht;
/* Translate */
peerConnectState pcs;
if (!mLinkMgr->getFriendNetStatus(id, pcs))
@ -414,14 +426,10 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
}
d.state = 0;
if (pcs.state & RS_PEER_S_FRIEND)
d.state |= RS_PEER_STATE_FRIEND;
if (pcs.state & RS_PEER_S_ONLINE)
d.state |= RS_PEER_STATE_ONLINE;
if (pcs.state & RS_PEER_S_CONNECTED)
d.state |= RS_PEER_STATE_CONNECTED;
if (pcs.state & RS_PEER_S_UNREACHABLE)
d.state |= RS_PEER_STATE_UNREACHABLE;
if (pcs.state & RS_PEER_S_FRIEND) d.state |= RS_PEER_STATE_FRIEND;
if (pcs.state & RS_PEER_S_ONLINE) d.state |= RS_PEER_STATE_ONLINE;
if (pcs.state & RS_PEER_S_CONNECTED) d.state |= RS_PEER_STATE_CONNECTED;
if (pcs.state & RS_PEER_S_UNREACHABLE) d.state |= RS_PEER_STATE_UNREACHABLE;
d.actAsServer = pcs.actAsServer;
@ -433,7 +441,6 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
d.connectState = RS_PEER_CONNECTSTATE_OFFLINE;
d.connectStateString.clear();
if (pcs.inConnAttempt)
{
if (pcs.currentConnAddrAttempt.type & RS_NET_CONN_TCP_ALL) {
@ -445,7 +452,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
}
}
else if (pcs.state & RS_PEER_S_CONNECTED)
{
{
/* peer is connected - determine how and set proper connectState */
if(mPeerMgr->isHidden())
{
@ -519,8 +526,8 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN;
}
}
}
}
d.wasDeniedConnection = pcs.wasDeniedConnection;
d.deniedTS = pcs.deniedTS;

View File

@ -139,6 +139,9 @@ public:
virtual ServicePermissionFlags servicePermissionFlags(const RsPeerId & ssl_id);
virtual void setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermissionFlags& flags);
virtual bool setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint32_t maxDownloadRate);
virtual bool getPeerMaximumRates(const RsPgpId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate);
virtual bool getPeerMaximumRates(const RsPeerId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate);
private:
p3LinkMgr *mLinkMgr;

View File

@ -503,7 +503,6 @@ bool p3ServerConfig::switchToOperatingMode(uint32_t opMode)
return true;
}
/* handle data rates.
* Mutex must be handled at the lower levels: TODO */

View File

@ -684,6 +684,7 @@ uint32_t RsPeerConfigSerialiser::size(RsItem *i)
RsPeerNetItem *pni;
RsPeerGroupItem *pgi;
RsPeerServicePermissionItem *pri;
RsPeerBandwidthLimitsItem *pblitem;
if (NULL != (pni = dynamic_cast<RsPeerNetItem *>(i)))
{
@ -701,6 +702,10 @@ uint32_t RsPeerConfigSerialiser::size(RsItem *i)
{
return sizePermissions(pri);
}
else if (NULL != (pblitem = dynamic_cast<RsPeerBandwidthLimitsItem *>(i)))
{
return sizePeerBandwidthLimits(pblitem);
}
return 0;
}
@ -712,6 +717,7 @@ bool RsPeerConfigSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsi
RsPeerStunItem *psi;
RsPeerGroupItem *pgi;
RsPeerServicePermissionItem *pri;
RsPeerBandwidthLimitsItem *pblitem;
if (NULL != (pni = dynamic_cast<RsPeerNetItem *>(i)))
{
@ -729,6 +735,10 @@ bool RsPeerConfigSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsi
{
return serialisePermissions(pri, data, pktsize);
}
else if (NULL != (pblitem = dynamic_cast<RsPeerBandwidthLimitsItem *>(i)))
{
return serialisePeerBandwidthLimits(pblitem, data, pktsize);
}
return false;
}
@ -758,6 +768,8 @@ RsItem *RsPeerConfigSerialiser::deserialise(void *data, uint32_t *pktsize)
return deserialiseGroup(data, pktsize);
case RS_PKT_SUBTYPE_PEER_PERMISSIONS:
return deserialisePermissions(data, pktsize);
case RS_PKT_SUBTYPE_PEER_BANDLIMITS:
return deserialisePeerBandwidthLimits(data, pktsize);
default:
return NULL;
}
@ -880,7 +892,6 @@ uint32_t RsPeerConfigSerialiser::sizeNet(RsPeerNetItem *i)
s += 2; /* domain_port */
return s;
}
bool RsPeerConfigSerialiser::serialiseNet(RsPeerNetItem *item, void *data, uint32_t *size)
@ -1028,6 +1039,160 @@ RsPeerNetItem *RsPeerConfigSerialiser::deserialiseNet(void *data, uint32_t *size
return item;
}
/****************************************************************************/
uint32_t RsPeerConfigSerialiser::sizePeerBandwidthLimits(RsPeerBandwidthLimitsItem *i)
{
uint32_t s = 8; /* header */
s += 4; // number of elements
s += i->peers.size() * (4 + 4 + RsPgpId::SIZE_IN_BYTES) ;
return s;
}
bool RsPeerConfigSerialiser::serialisePeerBandwidthLimits(RsPeerBandwidthLimitsItem *item, void *data, uint32_t *size)
{
uint32_t tlvsize = RsPeerConfigSerialiser::sizePeerBandwidthLimits(item);
uint32_t offset = 0;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsPeerConfigSerialiser::serialiseNet() tlvsize: " << tlvsize << std::endl;
#endif
if(*size < tlvsize)
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::serialiseNet() ERROR not enough space" << std::endl;
#endif
return false; /* not enough space */
}
*size = tlvsize;
bool ok = true;
// serialise header
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
#ifdef RSSERIAL_DEBUG
std::cerr << "RsPeerConfigSerialiser::serialiseNet() Header: " << ok << std::endl;
std::cerr << "RsPeerConfigSerialiser::serialiseNet() Header test: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
ok &= setRawUInt32(data, tlvsize, &offset, item->peers.size()); /* Mandatory */
for(std::map<RsPgpId,PeerBandwidthLimits>::const_iterator it(item->peers.begin());it!=item->peers.end();++it)
{
ok &= it->first.serialise(data,tlvsize,offset);
ok &= setRawUInt32(data, tlvsize, &offset, it->second.max_up_rate_kbs); /* Mandatory */
ok &= setRawUInt32(data, tlvsize, &offset, it->second.max_dl_rate_kbs); /* Mandatory */
}
if(offset != tlvsize)
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::serialiseNet() Size Error! " << std::endl;
#endif
ok = false;
}
return ok;
}
RsPeerBandwidthLimitsItem *RsPeerConfigSerialiser::deserialisePeerBandwidthLimits(void *data, uint32_t *size)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsPeerConfigSerialiser::deserialiseNet() rssize: " << rssize << std::endl;
#endif
if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) ||
(RS_PKT_CLASS_CONFIG != getRsItemClass(rstype)) ||
(RS_PKT_TYPE_PEER_CONFIG != getRsItemType(rstype)) ||
(RS_PKT_SUBTYPE_PEER_BANDLIMITS != getRsItemSubType(rstype)))
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::deserialiseNet() ERROR Type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::deserialiseNet() ERROR not enough data" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsPeerBandwidthLimitsItem *item = new RsPeerBandwidthLimitsItem();
/* skip the header */
offset += 8;
/* get mandatory parts first */
uint32_t n ;
ok &= getRawUInt32(data, rssize, &offset, &n) ;
for(uint32_t i=0;i<n;++i)
{
RsPgpId pgpid ;
ok &= pgpid.deserialise(data,rssize,offset) ;
PeerBandwidthLimits p ;
ok &= getRawUInt32(data, rssize, &offset, &(p.max_up_rate_kbs)); /* Mandatory */
ok &= getRawUInt32(data, rssize, &offset, &(p.max_dl_rate_kbs)); /* Mandatory */
item->peers[pgpid] = p ;
}
if (offset != rssize)
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::deserialiseNet() ERROR size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
}
return item;
}
std::ostream &RsPeerBandwidthLimitsItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsPeerBandwidthLimitsItem", indent);
uint16_t int_Indent = indent + 2;
for(std::map<RsPgpId,PeerBandwidthLimits>::const_iterator it(peers.begin());it!=peers.end();++it)
{
printIndent(out, int_Indent);
out << it->first << " : " << it->second.max_up_rate_kbs << " (up) " << it->second.max_dl_rate_kbs << " (dn)" << std::endl;
}
printRsItemEnd(out, "RsPeerStunItem", indent);
return out;
}
/****************************************************************************/
RsPeerStunItem::~RsPeerStunItem()

View File

@ -54,6 +54,7 @@ const uint8_t RS_PKT_SUBTYPE_PEER_STUN = 0x02;
const uint8_t RS_PKT_SUBTYPE_PEER_NET = 0x03;
const uint8_t RS_PKT_SUBTYPE_PEER_GROUP = 0x04;
const uint8_t RS_PKT_SUBTYPE_PEER_PERMISSIONS = 0x05;
const uint8_t RS_PKT_SUBTYPE_PEER_BANDLIMITS = 0x06;
/* FILE CONFIG SUBTYPES */
const uint8_t RS_PKT_SUBTYPE_FILE_TRANSFER = 0x01;
@ -61,6 +62,8 @@ const uint8_t RS_PKT_SUBTYPE_FILE_ITEM = 0x02;
/**************************************************************************/
// We should make these items use a clean serialise code, and all derive from the same item type.
class RsPeerNetItem: public RsItem
{
public:
@ -97,6 +100,7 @@ std::ostream &print(std::ostream &out, uint16_t indent = 0);
uint16_t domain_port;
};
// This item should be merged with the next item, but that is not backward compatible.
class RsPeerServicePermissionItem : public RsItem
{
public:
@ -114,7 +118,21 @@ class RsPeerServicePermissionItem : public RsItem
std::vector<RsPgpId> pgp_ids ;
std::vector<ServicePermissionFlags> service_flags ;
};
class RsPeerBandwidthLimitsItem : public RsItem
{
public:
RsPeerBandwidthLimitsItem() : RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_PEER_CONFIG, RS_PKT_SUBTYPE_PEER_BANDLIMITS) {}
virtual ~RsPeerBandwidthLimitsItem() {}
virtual void clear()
{
peers.clear() ;
}
std::ostream &print(std::ostream &out, uint16_t indent = 0);
/* Mandatory */
std::map<RsPgpId,PeerBandwidthLimits> peers ;
};
class RsPeerGroupItem : public RsItem
{
@ -183,6 +201,10 @@ virtual uint32_t sizeGroup(RsPeerGroupItem *);
virtual bool serialiseGroup (RsPeerGroupItem *item, void *data, uint32_t *size);
virtual RsPeerGroupItem * deserialiseGroup(void *data, uint32_t *size);
virtual uint32_t sizePeerBandwidthLimits(RsPeerBandwidthLimitsItem *);
virtual bool serialisePeerBandwidthLimits (RsPeerBandwidthLimitsItem *item, void *data, uint32_t *size);
virtual RsPeerBandwidthLimitsItem *deserialisePeerBandwidthLimits(void *data, uint32_t *size);
virtual uint32_t sizePermissions(RsPeerServicePermissionItem *);
virtual bool serialisePermissions (RsPeerServicePermissionItem *item, void *data, uint32_t *size);
virtual RsPeerServicePermissionItem * deserialisePermissions(void *data, uint32_t *size);

View File

@ -13,8 +13,10 @@ const uint8_t RsNxsSyncGrpItem::FLAG_RESPONSE = 0x002;
const uint8_t RsNxsSyncMsgItem::FLAG_REQUEST = 0x001;
const uint8_t RsNxsSyncMsgItem::FLAG_RESPONSE = 0x002;
const uint8_t RsNxsSyncGrpItem::FLAG_USE_SYNC_HASH = 0x001;
const uint8_t RsNxsSyncMsgItem::FLAG_USE_SYNC_HASH = 0x001;
const uint8_t RsNxsSyncGrpItem::FLAG_USE_SYNC_HASH = 0x0001;
const uint8_t RsNxsSyncMsgItem::FLAG_USE_SYNC_HASH = 0x0001;
const uint8_t RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID = 0x02;
/** transaction state **/
const uint16_t RsNxsTransacItem::FLAG_BEGIN_P1 = 0x0001;

View File

@ -351,12 +351,12 @@ public:
#ifdef UNUSED_CODE
static const uint8_t FLAG_USE_SYNC_HASH;
#endif
static const uint8_t FLAG_USE_HASHED_GROUP_ID;
RsNxsSyncMsgReqItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM) { clear(); return; }
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);

View File

@ -283,6 +283,7 @@ bool p3GxsCircles:: getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails
details.mCircleName = data.mCircleName;
details.mCircleType = data.mCircleType;
details.mRestrictedCircleId = data.mRestrictedCircleId;
details.mAllowedNodes = data.mAllowedNodes;
details.mSubscriptionFlags.clear();
@ -588,6 +589,7 @@ bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup &circle)
mOriginator = circle.mMeta.mOriginator ;
mAllowedNodes = circle.mLocalFriends ;
mRestrictedCircleId = circle.mMeta.mCircleId ;
mMembershipStatus.clear() ;

View File

@ -152,6 +152,7 @@ class RsGxsCircleCache
uint32_t mCircleType;
bool mIsExternal;
RsGxsCircleId mRestrictedCircleId ; // circle ID that circle is restricted to.
uint32_t mGroupStatus;
uint32_t mGroupSubscribeFlags;

View File

@ -58,9 +58,14 @@
#define GXSID_MAX_CACHE_SIZE 5000
static const uint32_t MAX_KEEP_UNUSED_KEYS = 30*86400 ; // remove unused keys after 30 days
static const uint32_t MAX_KEEP_BANNED_KEYS = 30*86400 ; // remove banned keys after 5 days
static const uint32_t MAX_DELAY_BEFORE_CLEANING = 601 ; // clean old keys every 10 mins
// unused keys are deleted according to some heuristic that should favor known keys, signed keys etc.
static const time_t MAX_KEEP_KEYS_BANNED = 2 * 86400 ; // get rid of banned ids after 2 days. That gives a chance to un-ban someone before he gets kicked out
static const time_t MAX_KEEP_KEYS_DEFAULT = 5 * 86400 ; // default for unsigned identities: 5 days
static const time_t MAX_KEEP_KEYS_SIGNED = 8 * 86400 ; // signed identities by unknown key
static const time_t MAX_KEEP_KEYS_SIGNED_KNOWN = 30 * 86400 ; // signed identities by known node keys
static const uint32_t MAX_DELAY_BEFORE_CLEANING= 1800 ; // clean old keys every 30 mins
RsIdentity *rsIdentity = NULL;
@ -153,7 +158,7 @@ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *ne
{
mBgSchedule_Mode = 0;
mBgSchedule_Active = false;
mLastKeyCleaningTime = 0 ;
mLastKeyCleaningTime = time(NULL) - int(MAX_DELAY_BEFORE_CLEANING * 0.9) ;
mLastConfigUpdate = 0 ;
mOwnIdsLoaded = false ;
@ -262,11 +267,16 @@ time_t p3IdService::locked_getLastUsageTS(const RsGxsId& gxs_id)
}
void p3IdService::timeStampKey(const RsGxsId& gxs_id)
{
RS_STACK_MUTEX(mIdMtx) ;
if(rsReputations->isIdentityBanned(gxs_id))
{
std::cerr << "(II) p3IdService:timeStampKey(): refusing to time stamp key " << gxs_id << " because it is banned." << std::endl;
return;
}
RS_STACK_MUTEX(mIdMtx) ;
mKeysTS[gxs_id] = time(NULL) ;
slowIndicateConfigChanged() ;
slowIndicateConfigChanged() ;
}
bool p3IdService::loadList(std::list<RsItem*>& items)
@ -306,49 +316,114 @@ bool p3IdService::saveList(bool& cleanup,std::list<RsItem*>& items)
items.push_back(item) ;
return true ;
}
class IdCacheEntryCleaner
{
public:
IdCacheEntryCleaner(const std::map<RsGxsId,time_t>& last_usage_TSs) : mLastUsageTS(last_usage_TSs) {}
bool processEntry(RsGxsIdCache& entry)
{
time_t now = time(NULL);
const RsGxsId& gxs_id = entry.details.mId ;
bool is_id_banned = rsReputations->isIdentityBanned(gxs_id) ;
bool is_own_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID) ;
bool is_known_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_PGP_KNOWN) ;
bool is_signed_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED) ;
bool is_a_contact = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_IS_A_CONTACT) ;
std::cerr << "Identity: " << gxs_id << ": banned: " << is_id_banned << ", own: " << is_own_id << ", contact: " << is_a_contact << ", signed: " << is_signed_id << ", known: " << is_known_id;
if(is_own_id || is_a_contact)
{
std::cerr << " => kept" << std::endl;
return true ;
}
std::map<RsGxsId,time_t>::const_iterator it = mLastUsageTS.find(gxs_id) ;
if(it == mLastUsageTS.end())
{
std::cerr << "No Ts for this ID" << std::endl;
return true ;
}
time_t last_usage_ts = it->second;
time_t max_keep_time ;
if(is_id_banned)
max_keep_time = MAX_KEEP_KEYS_BANNED ;
else if(is_known_id)
max_keep_time = MAX_KEEP_KEYS_SIGNED_KNOWN ;
else if(is_signed_id)
max_keep_time = MAX_KEEP_KEYS_SIGNED ;
else
max_keep_time = MAX_KEEP_KEYS_DEFAULT ;
std::cerr << ". Max keep = " << max_keep_time/86400 << " days. Unused for " << (now - last_usage_ts + 86399)/86400 << " days " ;
if(now > last_usage_ts + max_keep_time)
{
std::cerr << " => delete " << std::endl;
ids_to_delete.push_back(gxs_id) ;
}
else
std::cerr << " => keep " << std::endl;
return true;
}
std::list<RsGxsId> ids_to_delete ;
const std::map<RsGxsId,time_t>& mLastUsageTS;
};
void p3IdService::cleanUnusedKeys()
{
std::list<RsGxsId> ids_to_delete ;
std::list<RsGxsId> ids_to_delete ;
// we need to stash all ids to delete into an off-mutex structure since deleteIdentity() will trigger the lock
{
RS_STACK_MUTEX(mIdMtx) ;
std::cerr << "Cleaning unused keys:" << std::endl;
// we need to stash all ids to delete into an off-mutex structure since deleteIdentity() will trigger the lock
{
RS_STACK_MUTEX(mIdMtx) ;
if(!mOwnIdsLoaded)
{
std::cerr << "(EE) Own ids not loaded. Cannot clean unused keys." << std::endl;
return ;
}
if(!mOwnIdsLoaded)
{
std::cerr << "(EE) Own ids not loaded. Cannot clean unused keys." << std::endl;
return ;
}
// grab at most 10 identities to delete. No need to send too many requests to the token queue at once.
time_t now = time(NULL) ;
int n=0 ;
// grab at most 10 identities to delete. No need to send too many requests to the token queue at once.
time_t now = time(NULL) ;
int n=0 ;
IdCacheEntryCleaner idcec(mKeysTS) ;
for(std::map<RsGxsId,time_t>::iterator it(mKeysTS.begin());it!=mKeysTS.end() && n < 10;++it)
{
if(it->second + MAX_KEEP_UNUSED_KEYS < now && std::find(mOwnIds.begin(),mOwnIds.end(),it->first) == mOwnIds.end())
ids_to_delete.push_back(it->first),++n ;
else if(it->second + MAX_KEEP_BANNED_KEYS < now && rsReputations->isIdentityBanned(it->first))
ids_to_delete.push_back(it->first),++n ;
}
}
mKeyCache.applyToAllCachedEntries(idcec,&IdCacheEntryCleaner::processEntry);
ids_to_delete = idcec.ids_to_delete ;
}
std::cerr << "Collected " << ids_to_delete.size() << " keys to delete among " << mKeyCache.size() << std::endl;
for(std::list<RsGxsId>::const_iterator it(ids_to_delete.begin());it!=ids_to_delete.end();++it)
{
std::cerr << "Deleting identity " << *it << " which is too old." << std::endl;
uint32_t token ;
RsGxsIdGroup group;
group.mMeta.mGroupId=RsGxsGroupId(*it);
rsIdentity->deleteIdentity(token, group);
for(std::list<RsGxsId>::const_iterator it(ids_to_delete.begin());it!=ids_to_delete.end();++it)
{
std::cerr << "Deleting identity " << *it << " which is too old." << std::endl;
uint32_t token ;
RsGxsIdGroup group;
group.mMeta.mGroupId=RsGxsGroupId(*it);
rsIdentity->deleteIdentity(token, group);
{
RS_STACK_MUTEX(mIdMtx) ;
std::map<RsGxsId,time_t>::iterator tmp = mKeysTS.find(*it) ;
{
RS_STACK_MUTEX(mIdMtx) ;
std::map<RsGxsId,time_t>::iterator tmp = mKeysTS.find(*it) ;
if(mKeysTS.end() != tmp)
mKeysTS.erase(tmp) ;
}
}
if(mKeysTS.end() != tmp)
mKeysTS.erase(tmp) ;
// mPublicKeyCache.erase(*it) ; no need to do it now. It's done in p3IdService::deleteGroup()
}
}
}
void p3IdService::service_tick()
@ -454,9 +529,6 @@ bool p3IdService:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details)
details = data.details;
details.mLastUsageTS = locked_getLastUsageTS(id) ;
if(mContacts.find(id) != mContacts.end())
details.mFlags |= RS_IDENTITY_FLAGS_IS_A_CONTACT ;
// one utf8 symbol can be at most 4 bytes long - would be better to measure real unicode length !!!
if(details.mNickname.length() > RSID_MAXIMUM_NICKNAME_SIZE*4)
details.mNickname = "[too long a name]" ;
@ -1914,6 +1986,9 @@ bool p3IdService::cache_store(const RsGxsIdGroupItem *item)
// Create Cache Data.
RsGxsIdCache keycache(item, pubkey, fullkey,tagList);
if(mContacts.find(id) != mContacts.end())
keycache.details.mFlags |= RS_IDENTITY_FLAGS_IS_A_CONTACT;
mKeyCache.store(id, keycache);
mKeyCache.resize();

View File

@ -381,14 +381,14 @@ bool upnphandler::start_upnp()
if (!SetRedirectAndTest(&(config -> urls), &(config->data),
in_addr, in_port1, eport1, eprot1,
NULL /*leaseDuration*/, NULL /*description*/,
NULL /*leaseDuration*/, "RetroShare_TCP" /*description*/,
0))
{
upnpState = RS_UPNP_S_TCP_FAILED;
}
else if (!SetRedirectAndTest(&(config -> urls), &(config->data),
in_addr, in_port2, eport2, eprot2,
NULL /*leaseDuration*/, NULL /*description*/,
NULL /*leaseDuration*/, "RetroShare_UDP" /*description*/,
0))
{
upnpState = RS_UPNP_S_UDP_FAILED;

View File

@ -298,7 +298,7 @@ int SetRedirectAndTest(struct UPNPUrls * urls,
// const char * remoteHost,
// const char * leaseDuration);
r = UPNP_AddPortMapping(urls->controlURL, servicetype,
eport, iport, iaddr, NULL, proto, NULL, NULL);
eport, iport, iaddr, description, proto, NULL, NULL);
#else
#if MINIUPNPC_API_VERSION >= -3 //1.0 2009/04/17
/* $Id: upnpcommands.h,v 1.18 2010/06/09 10:59:09 nanard Exp $ */
@ -311,7 +311,7 @@ int SetRedirectAndTest(struct UPNPUrls * urls,
// const char * proto,
// const char * remoteHost);
r = UPNP_AddPortMapping(urls->controlURL, servicetype,
eport, iport, iaddr, NULL, proto, NULL);
eport, iport, iaddr, description, proto, NULL);
#else
#if MINIUPNPC_API_VERSION >= -7//Before 1.0
/* $Id: upnpcommands.h,v 1.14 2008/09/25 18:02:50 nanard Exp $ */
@ -323,7 +323,7 @@ int SetRedirectAndTest(struct UPNPUrls * urls,
// const char * desc,
// const char * proto);
r = UPNP_AddPortMapping(urls->controlURL, servicetype,
eport, iport, iaddr, NULL, proto);
eport, iport, iaddr, description, proto);
#else
#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version
#endif//>=-7

View File

@ -73,6 +73,7 @@ public:
template<class ClientClass> bool applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(Value&));
uint32_t size() const { return mDataMap.size() ; }
private:
bool update_lrumap(const Key &key, time_t old_ts, time_t new_ts);

View File

@ -279,11 +279,22 @@ void *SmallObject::operator new(size_t size)
#endif
RsStackMutex m(_mtx) ;
void *p = _allocator.allocate(size) ;
// This should normally not happen. But that prevents a crash when quitting, since we cannot prevent the constructor
// of an object to call operator new(), nor to handle the case where it returns NULL.
// The memory will therefore not be deleted if that happens. We thus print a warning.
if(_allocator._active)
return _allocator.allocate(size) ;
else
{
std::cerr << "(EE) allocating " << size << " bytes of memory that cannot be deleted. This is a bug, except if it happens when closing Retroshare" << std::endl;
return malloc(size) ;
}
#ifdef DEBUG_MEMORY
std::cerr << "new RsItem: " << p << ", size=" << size << std::endl;
#endif
return p ;
}
void SmallObject::operator delete(void *p,size_t size)

View File

@ -3,6 +3,12 @@
#don't exit even if a command fails
set +e
SCRIPT_PATH=$(dirname "`readlink -f "${0}"`")
OLDLANG=${LANG}
export LANG=C
if ( git log -n 1 &> /dev/null); then
#retrieve git information
version="$(git log --pretty=format:"%H" | head -1 | cut -c1-8)"
@ -22,7 +28,9 @@ fi
if [[ ${version} != '' ]]; then
echo "Writing version to retroshare/rsversion.h : ${version}"
sed -e "s%RS_REVISION_NUMBER.*%RS_REVISION_NUMBER 0x${version}%" retroshare/rsversion.in >retroshare/rsversion.h
sed -e "s%RS_REVISION_NUMBER.*%RS_REVISION_NUMBER 0x${version}%" ${SCRIPT_PATH}/retroshare/rsversion.in >${SCRIPT_PATH}/retroshare/rsversion.h
fi
export LANG=${OLDLANG}
echo "script version_detail.sh finished normally"
exit 0

View File

@ -1,41 +1,28 @@
TCL_VERSION=8.6.2
SQLCIPHER_VERSION=2.2.1
SQLCIPHER_VERSION=3.3.1
MSYS2AUTOMAKE=/c/msys64/usr/share/automake-1.15
all: dirs sqlcipher copylibs
BLD=../build-libs
DLD=../downloads
all: dirs sqlcipher
dirs:
mkdir -p libs/include
mkdir -p libs/lib
mkdir -p libs/bin
mkdir -p ../../libs/include
mkdir -p ../../libs/lib
mkdir -p ../../libs/bin
mkdir -p $(DLD)
mkdir -p $(BLD)
tcl$(TCL_VERSION)-src.tar.gz:
curl.exe -L http://prdownloads.sourceforge.net/tcl/tcl$(TCL_VERSION)-src.tar.gz -o tcl$(TCL_VERSION)-src.tar.gz
sqlcipher: | ../../libs/lib/libsqlcipher.a
sqlcipher-$(SQLCIPHER_VERSION).tar.gz:
curl.exe -L -k https://github.com/sqlcipher/sqlcipher/archive/v$(SQLCIPHER_VERSION).tar.gz -o sqlcipher-$(SQLCIPHER_VERSION).tar.gz
sqlcipher: tcl$(TCL_VERSION)-src.tar.gz sqlcipher-$(SQLCIPHER_VERSION).tar.gz
# tcl
tar xvf tcl$(TCL_VERSION)-src.tar.gz
mkdir -p tcl$(TCL_VERSION)/build
cd tcl$(TCL_VERSION)/build && ../win/configure
cd tcl$(TCL_VERSION)/build && make
#sqlcipher
tar xvf sqlcipher-$(SQLCIPHER_VERSION).tar.gz
cd sqlcipher-$(SQLCIPHER_VERSION) && ln -s ../tcl$(TCL_VERSION)/build/tclsh86.exe tclsh
mkdir -p tcl$(TCL_VERSION)/lib
ln -s `pwd`/tcl$(TCL_VERSION)/library `pwd`/tcl$(TCL_VERSION)/lib/tcl8.6
cd sqlcipher-$(SQLCIPHER_VERSION) && PATH=$$PATH:`pwd`/../tcl$(TCL_VERSION)/build && LIBS="-L`pwd`/../libs/lib -lgdi32 $$LIBS" && export LIBS && ./configure --disable-shared --enable-static --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC -I`pwd`/../libs/include -I`pwd`/../tcl$(TCL_VERSION)/generic" LDFLAGS="-L`pwd`/../libs/lib -lcrypto -lgdi32" --with-tcl="`pwd`/../tcl$(TCL_VERSION)/build" && make install prefix="`pwd`/install"
cp -r sqlcipher-$(SQLCIPHER_VERSION)/install/include/* libs/include/
cp sqlcipher-$(SQLCIPHER_VERSION)/install/lib/libsqlcipher.a libs/lib/
cp sqlcipher-$(SQLCIPHER_VERSION)/install/bin/sqlcipher.exe libs/bin/
rm -r -f sqlcipher-$(SQLCIPHER_VERSION)
rm -r -f tcl$(TCL_VERSION)
touch sqlcipher
copylibs:
read -p "Do you want to copy libs to retroshare? (yes|no)" answer; \
if [ "$$answer" = "yes" ] ; then \
cp -r libs ../../ ; \
fi
$(DLD)/sqlcipher-$(SQLCIPHER_VERSION).tar.gz:
curl.exe -L -k https://github.com/sqlcipher/sqlcipher/archive/v$(SQLCIPHER_VERSION).tar.gz -o $(DLD)/sqlcipher-$(SQLCIPHER_VERSION).tar.gz
../../libs/lib/libsqlcipher.a: $(DLD)/sqlcipher-$(SQLCIPHER_VERSION).tar.gz
tar xvf $(DLD)/sqlcipher-$(SQLCIPHER_VERSION).tar.gz -C $(BLD)
cp $(MSYS2AUTOMAKE)/config.guess $(BLD)/sqlcipher-$(SQLCIPHER_VERSION)/config.guess
cp $(MSYS2AUTOMAKE)/config.sub $(BLD)/sqlcipher-$(SQLCIPHER_VERSION)/config.sub
cd $(BLD)/sqlcipher-$(SQLCIPHER_VERSION) && LIBS="-L`pwd`/../../libs/lib -lgdi32 $$LIBS" && export LIBS && ./configure --disable-shared --enable-static --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC -I`pwd`/../../libs/include" LDFLAGS="-L`pwd`/../../libs/lib -lcrypto -lgdi32" && make install prefix="`pwd`/install"
cp -r $(BLD)/sqlcipher-$(SQLCIPHER_VERSION)/install/include/* ../../libs/include/
cp $(BLD)/sqlcipher-$(SQLCIPHER_VERSION)/install/lib/libsqlcipher.a ../../libs/lib/
cp $(BLD)/sqlcipher-$(SQLCIPHER_VERSION)/install/bin/sqlcipher.exe ../../libs/bin/

View File

@ -72,7 +72,7 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
QObject::connect( ui.filterLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(filterItems(QString)));
QObject::connect( ui.filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int)));
QObject::connect( ui.createlobbytoolButton, SIGNAL(clicked()), this, SLOT(createChatLobby()));
QObject::connect( ui.createLobbyToolButton, SIGNAL(clicked()), this, SLOT(createChatLobby()));
compareRole = new RSTreeWidgetItemCompareRole;
compareRole->setRole(COLUMN_NAME, ROLE_SORT);

View File

@ -10,8 +10,17 @@
<height>517</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="margin">
<layout class="QVBoxLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -28,8 +37,17 @@
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="margin">
<layout class="QHBoxLayout" name="titleBarFrameLayout">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
@ -53,7 +71,7 @@
</widget>
</item>
<item>
<spacer>
<spacer name="titleBarVSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@ -91,7 +109,7 @@
<enum>Qt::Horizontal</enum>
</property>
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout_3">
<layout class="QVBoxLayout" name="lobbyTreeVLayout">
<item>
<widget class="QFrame" name="toolBarFrame">
<property name="styleSheet">
@ -103,7 +121,7 @@
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<layout class="QGridLayout" name="toolBarFrameGLayout">
<property name="leftMargin">
<number>2</number>
</property>
@ -130,7 +148,7 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="createlobbytoolButton">
<widget class="QToolButton" name="createLobbyToolButton">
<property name="toolTip">
<string>Create chat lobby</string>
</property>
@ -183,8 +201,17 @@
<number>0</number>
</property>
<widget class="QWidget" name="_lobby_blank_page">
<layout class="QGridLayout" name="gridLayout_4">
<property name="margin">
<layout class="QGridLayout" name="_lobby_blank_pageGLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
@ -195,13 +222,13 @@
<property name="title">
<string>Selected lobby info</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<layout class="QVBoxLayout" name="lobbyinfo_groupBoxVLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<layout class="QHBoxLayout" name="lobbyInfoHLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="lobbyInfoNameVLayout">
<item>
<widget class="QLabel" name="label">
<widget class="QLabel" name="lobbyname_label">
<property name="font">
<font>
<weight>75</weight>
@ -214,7 +241,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<widget class="QLabel" name="lobbyid_label">
<property name="font">
<font>
<weight>75</weight>
@ -227,7 +254,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<widget class="QLabel" name="lobbytopic_label">
<property name="font">
<font>
<weight>75</weight>
@ -240,7 +267,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<widget class="QLabel" name="lobbytype_label">
<property name="font">
<font>
<weight>75</weight>
@ -253,7 +280,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<widget class="QLabel" name="lobbysec_label">
<property name="font">
<font>
<weight>75</weight>
@ -266,7 +293,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<widget class="QLabel" name="lobbypeers_label">
<property name="font">
<font>
<weight>75</weight>
@ -281,7 +308,7 @@
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QVBoxLayout" name="lobbyInfoValueVLayout">
<item>
<widget class="QLabel" name="lobbyname_lineEdit">
<property name="sizePolicy">
@ -372,7 +399,7 @@
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<spacer name="lobbyInfoVSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>

View File

@ -138,6 +138,7 @@ void CreateCircleDialog::editExistingId(const RsGxsGroupId &circleId, const bool
else
{
ui.circleAdminLabel->setVisible(false) ;
ui.circleAdminLabel->hide();
ui.idChooser->setVisible(true) ;
}
@ -297,6 +298,8 @@ void CreateCircleDialog::addMember(const QString& keyId, const QString& idtype,
//member->setIcon(RSCIRCLEID_COL_NICKNAME, pixmap);
tree->addTopLevelItem(member);
ui.members_groupBox->setTitle( tr("Invited Members") + " (" + QString::number(ui.treeWidget_membership->topLevelItemCount()) + ")" );
}
/** Maybe we can use RsGxsCircleGroup instead of RsGxsCircleDetails ??? (TODO)**/
@ -634,6 +637,7 @@ void CreateCircleDialog::updateCircleGUI()
//ui.idChooser->setIdConstraintSet(ids) ;
ui.idChooser->setFlags(IDCHOOSER_NO_CREATE) ;
ui.circleAdminLabel->setVisible(false) ;
ui.circleAdminLabel->hide();
}
}

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>924</width>
<width>951</width>
<height>578</height>
</rect>
</property>
@ -51,7 +51,7 @@
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox_2">
<widget class="QGroupBox" name="members_groupBox">
<property name="title">
<string>Invited Members</string>
</property>
@ -61,6 +61,9 @@
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Members of this list will be automatically proposed to join the circle (by accepting membership). They will&lt;/p&gt;&lt;p&gt;not receive data that is restricted to this circle until they do so.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
@ -143,6 +146,31 @@
<string>Known People</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="RSTreeWidget" name="treeWidget_IdList">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>Nickname</string>
</property>
</column>
<column>
<property name="text">
<string>ID</string>
</property>
</column>
<column>
<property name="text">
<string>Type</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_PgpTypes">
<property name="frameShape">
@ -205,31 +233,6 @@
</item>
</layout>
</item>
<item>
<widget class="RSTreeWidget" name="treeWidget_IdList">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>Nickname</string>
</property>
</column>
<column>
<property name="text">
<string>ID</string>
</property>
</column>
<column>
<property name="text">
<string>Type</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
@ -258,13 +261,23 @@
<bold>true</bold>
</font>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>Name</string>
<string>Name:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QLineEdit" name="circleName"/>
<widget class="QLineEdit" name="circleName">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The circle name, contact author and invted member list will be visible to all invited members. If the circle is not private, it will also be visible to neighbor nodes of the nodes who host the invited members.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="idChooserLabel">
@ -275,7 +288,7 @@
</font>
</property>
<property name="text">
<string>Creator:</string>
<string>Contact author:</string>
</property>
</widget>
</item>
@ -288,7 +301,7 @@
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The creator of a circle does not need to be known. It is however useful for public circles so that people know to whom to send a request for membership.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The creator of a circle ia purely optional. It is however useful for public circles so that people know with whom to discuss membership aspects.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
@ -324,7 +337,10 @@
</font>
</property>
<property name="text">
<string>Distribution</string>
<string>Distribution:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
@ -362,10 +378,10 @@
<item row="0" column="1">
<widget class="QRadioButton" name="radioButton_Self">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Self-restricted circles (the very existance of the circle, and its actual content) are only visible to the members of these circles. In practice the circle uses itself to limit its own distribution. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Private (a.k.a. self-restricted) circles are only visible to the invited members of these circles. In practice the circle uses its own list of invited members to limit its own distribution. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Self-Restricted</string>
<string>Private</string>
</property>
</widget>
</item>
@ -375,7 +391,7 @@
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Circles can be restricted to the members of another circle. Only the members of that second circle will be allowed to see the new circle and its content (list of members, etc).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Restricted to:</string>
<string>Only visible to members of:</string>
</property>
</widget>
</item>

View File

@ -71,8 +71,9 @@
#define RED_BACKGROUND 3
#define GRAY_BACKGROUND 4
#define CIRCLESDIALOG_GROUPMETA 1
#define CIRCLESDIALOG_GROUPDATA 2
#define CIRCLESDIALOG_GROUPMETA 1
#define CIRCLESDIALOG_GROUPDATA 2
#define CIRCLESDIALOG_GROUPUPDATE 3
/****************************************************************
*/
@ -98,6 +99,9 @@
#define IMAGE_CREATE ":/icons/circle_new_128.png"
#define IMAGE_INVITED ":/icons/bullet_yellow_128.png"
#define IMAGE_MEMBER ":/icons/bullet_green_128.png"
#define IMAGE_UNKNOWN ":/icons/bullet_grey_128.png"
#define IMAGE_ADMIN ":/icons/bullet_blue_128.png"
#define IMAGE_INFO ":/images/info16.png"
// comment this out in order to remove the sorting of circles into "belong to" and "other visible circles"
#define CIRCLE_MEMBERSHIP_CATEGORIES 1
@ -238,6 +242,7 @@ IdDialog::IdDialog(QWidget *parent) :
/* Set initial section sizes */
QHeaderView * circlesheader = ui->treeWidget_membership->header () ;
circlesheader->resizeSection (CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QFontMetricsF(ui->idTreeWidget->font()).width("Circle name")*1.5) ;
ui->treeWidget_membership->setColumnWidth(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, 270);
ui->filterLineEdit->addFilter(QIcon(), tr("ID"), RSID_COL_KEYID, tr("Search ID"));
@ -341,6 +346,8 @@ void IdDialog::requestCircleGroupMeta()
mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, CIRCLESDIALOG_GROUPMETA);
}
// should update this code to be called and modify the tree widget accordingly
#ifdef SUSPENDED
void IdDialog::requestCircleGroupData(const RsGxsCircleId& circle_id)
{
mStateHelper->setLoading(CIRCLESDIALOG_GROUPDATA, true);
@ -355,12 +362,13 @@ void IdDialog::requestCircleGroupData(const RsGxsCircleId& circle_id)
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
std::list<RsGxsGroupId> grps ;
grps.push_back(RsGxsGroupId(circle_id));
std::list<RsGxsGroupId> grps ;
grps.push_back(RsGxsGroupId(circle_id));
uint32_t token;
mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grps, CIRCLESDIALOG_GROUPDATA);
}
#endif
void IdDialog::loadCircleGroupMeta(const uint32_t &token)
{
@ -393,7 +401,7 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
if(!mExternalOtherCircleItem)
{
mExternalOtherCircleItem = new QTreeWidgetItem();
mExternalOtherCircleItem->setText(0, tr("Other visible external circles"));
mExternalOtherCircleItem->setText(0, tr("Other circles"));
ui->treeWidget_membership->addTopLevelItem(mExternalOtherCircleItem);
}
@ -401,7 +409,7 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
if(!mExternalBelongingCircleItem )
{
mExternalBelongingCircleItem = new QTreeWidgetItem();
mExternalBelongingCircleItem->setText(0, tr("External circles my identities belong to"));
mExternalBelongingCircleItem->setText(0, tr("Circles I belong to"));
ui->treeWidget_membership->addTopLevelItem(mExternalBelongingCircleItem);
}
#endif
@ -429,13 +437,13 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
// find already existing items for this circle
// implement the search manually, because there's no find based on user role.
// implement the search manually, because there's no find based on user role.
//QList<QTreeWidgetItem*> clist = ui->treeWidget_membership->findItems( QString::fromStdString(vit->mGroupId.toStdString()), Qt::MatchExactly|Qt::MatchRecursive, CIRCLEGROUP_CIRCLE_COL_GROUPID);
QList<QTreeWidgetItem*> clist ;
QString test_str = QString::fromStdString(vit->mGroupId.toStdString()) ;
for(QTreeWidgetItemIterator itt(ui->treeWidget_membership);*itt;++itt)
if( (*itt)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString() == test_str)
clist.push_back(*itt) ;
QString test_str = QString::fromStdString(vit->mGroupId.toStdString()) ;
for(QTreeWidgetItemIterator itt(ui->treeWidget_membership);*itt;++itt)
if( (*itt)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString() == test_str)
clist.push_back(*itt) ;
if(!clist.empty())
{
@ -499,7 +507,7 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
mExternalOtherCircleItem->addChild(item);
}
#else
ui->treeWidget_membership->addTopLevelItem(item) ;
ui->treeWidget_membership->addTopLevelItem(item) ;
#endif
}
else if(item->text(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) != QString::fromUtf8(vit->mGroupName.c_str()))
@ -512,11 +520,20 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
// just in case.
item->setData(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole, QVariant(vit->mSubscribeFlags));
QString tooltip ;
tooltip += tr("Circle ID: ")+QString::fromStdString(vit->mGroupId.toStdString()) ;
tooltip += "\n"+tr("Role: ");
tooltip += "\n"+tr("Visibility: ");
if(details.mRestrictedCircleId == details.mCircleId)
tooltip += tr("Private (only visible to invited members)") ;
else if(!details.mRestrictedCircleId.isNull())
tooltip += tr("Only visible to full members of circle ")+QString::fromStdString(details.mRestrictedCircleId.toStdString()) ;
else
tooltip += tr("Public") ;
tooltip += "\n"+tr("Your role: ");
if(am_I_admin)
tooltip += tr("Administrator (Can edit invite list, and request membership).") ;
@ -529,10 +546,10 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
else
tooltip += tr("unsubscribed (Only receive invite list).") ;
tooltip += "\n"+tr("Permissions: ") ;
tooltip += "\n"+tr("Your status: ") ;
if(am_I_in_circle)
tooltip += tr("Full member (have access to data limited to this circle)") ;
tooltip += tr("Full member (you have access to data limited to this circle)") ;
else
tooltip += tr("Not a member (do not have access to data limited to this circle)") ;
@ -553,21 +570,21 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
// - own GXS id is is admin and subscribed
// - own GXS id is is subscribed
bool am_I_invited = false ;
bool am_I_pending = false ;
bool am_I_invited = false ;
bool am_I_pending = false ;
#ifdef ID_DEBUG
std::cerr << " updating status of all identities for this circle:" << std::endl;
#endif
// remove any identity that has an item, but no subscription flag entry
// remove any identity that has an item, but no subscription flag entry
std::vector<QTreeWidgetItem*> to_delete ;
for(int k=0;k<item->childCount();++k)
for(uint32_t k=0;k<item->childCount();++k)
if(details.mSubscriptionFlags.find(RsGxsId(item->child(k)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString())) == details.mSubscriptionFlags.end())
to_delete.push_back(item->child(k));
for(uint32_t k=0;k<to_delete.size();++k)
delete to_delete[k] ;
for(uint32_t k=0;k<to_delete.size();++k)
delete to_delete[k] ;
for(std::map<RsGxsId,uint32_t>::const_iterator it(details.mSubscriptionFlags.begin());it!=details.mSubscriptionFlags.end();++it)
{
#ifdef ID_DEBUG
@ -580,35 +597,35 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
#ifdef ID_DEBUG
std::cerr << "invited: " << invited << ", subscription: " << subscrb ;
#endif
QTreeWidgetItem *subitem = NULL ;
// see if the item already exists
for(uint32_t k=0;k<item->childCount();++k)
QTreeWidgetItem *subitem = NULL ;
// see if the item already exists
for(uint32_t k=0;k<item->childCount();++k)
if(item->child(k)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString() == it->first.toStdString())
{
subitem = item->child(k);
{
subitem = item->child(k);
#ifdef ID_DEBUG
std::cerr << " found existing sub item." << std::endl;
std::cerr << " found existing sub item." << std::endl;
#endif
break ;
}
break ;
}
if(!(invited || subscrb))
{
if(subitem != NULL)
delete subitem ;
{
if(subitem != NULL)
delete subitem ;
#ifdef ID_DEBUG
std::cerr << ". not relevant. Skipping." << std::endl;
#endif
continue ;
}
// remove item if flags are not ok.
if(subitem && subitem->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt() != it->second)
{
delete subitem ;
subitem = NULL ;
}
}
// remove item if flags are not ok.
if(subitem && subitem->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt() != it->second)
{
delete subitem ;
subitem = NULL ;
}
if(!subitem)
{
@ -625,14 +642,14 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
if(idd.mAvatar.mSize == 0 || !pixmap.loadFromData(idd.mAvatar.mData, idd.mAvatar.mSize, "PNG"))
pixmap = QPixmap::fromImage(GxsIdDetails::makeDefaultIcon(it->first)) ;
if(has_id)
if(has_id)
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(idd.mNickname.c_str())) ;
else
else
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Unknown ID :")+QString::fromStdString(it->first.toStdString())) ;
QString tooltip ;
tooltip += tr("Identity ID: ")+QString::fromStdString(it->first.toStdString()) ;
tooltip += "\n"+tr("Status: ") ;
QString tooltip ;
tooltip += tr("Identity ID: ")+QString::fromStdString(it->first.toStdString()) ;
tooltip += "\n"+tr("Status: ") ;
if(invited)
if(subscrb)
tooltip += tr("Full member") ;
@ -643,9 +660,9 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
tooltip += tr("Subscription request pending") ;
else
tooltip += tr("unknown") ;
subitem->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tooltip) ;
subitem->setData(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole, QVariant(it->second)) ;
subitem->setData(CIRCLEGROUP_CIRCLE_COL_GROUPID, Qt::UserRole, QString::fromStdString(it->first.toStdString())) ;
@ -655,23 +672,23 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
}
if(invited && !subscrb)
{
{
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, tr("Invited")) ;
if(is_own_id)
if(is_own_id)
am_I_invited = true ;
}
}
if(!invited && subscrb)
{
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, tr("Subscription pending")) ;
if(is_own_id)
if(is_own_id)
am_I_pending = true ;
}
}
if(invited && subscrb)
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, tr("Member")) ;
if (is_own_id)
if (is_own_id)
{
QFont font = subitem->font(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) ;
font.setBold(true) ;
@ -680,13 +697,15 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS,font) ;
}
}
if(am_I_in_circle)
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(IMAGE_MEMBER)) ;
else if(am_I_invited || am_I_pending)
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(IMAGE_INVITED)) ;
else
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon()) ;
if(am_I_in_circle)
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(IMAGE_MEMBER)) ;
else if(am_I_admin)
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(IMAGE_ADMIN)) ;
else if(am_I_invited || am_I_pending)
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(IMAGE_INVITED)) ;
else
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(IMAGE_UNKNOWN)) ;
}
}
@ -748,6 +767,58 @@ void IdDialog::loadCircleGroupData(const uint32_t& token)
mStateHelper->setLoading(CIRCLESDIALOG_GROUPDATA, false);
}
void IdDialog::updateCircleGroup(const uint32_t& token)
{
#ifdef ID_DEBUG
std::cerr << "Loading circle info" << std::endl;
#endif
std::vector<RsGxsCircleGroup> circle_grp_v ;
rsGxsCircles->getGroupData(token, circle_grp_v);
if (circle_grp_v.empty())
{
std::cerr << "(EE) unexpected empty result from getGroupData. Cannot process circle now!" << std::endl;
return ;
}
if (circle_grp_v.size() != 1)
{
std::cerr << "(EE) very weird result from getGroupData. Should get exactly one circle" << std::endl;
return ;
}
RsGxsCircleGroup cg = circle_grp_v.front();
/* now mark all the members */
std::set<RsGxsId> members = cg.mInvitedMembers;
std::map<uint32_t,CircleUpdateOrder>::iterator it = mCircleUpdates.find(token) ;
if(it == mCircleUpdates.end())
{
std::cerr << "(EE) Cannot find token " << token << " to perform group update!" << std::endl;
return ;
}
if(it->second.action == CircleUpdateOrder::GRANT_MEMBERSHIP)
cg.mInvitedMembers.insert(it->second.gxs_id) ;
else if(it->second.action == CircleUpdateOrder::REVOKE_MEMBERSHIP)
cg.mInvitedMembers.erase(it->second.gxs_id) ;
else
{
std::cerr << "(EE) unrecognised membership action to perform: " << it->second.action << "!" << std::endl;
return ;
}
uint32_t token2 ;
rsGxsCircles->updateGroup(token2,cg) ;
mCircleUpdates.erase(it) ;
requestCircleGroupMeta();
}
bool IdDialog::getItemCircleId(QTreeWidgetItem *item,RsGxsCircleId& id)
{
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES
@ -791,6 +862,58 @@ void IdDialog::showEditExistingCircle()
requestCircleGroupMeta(); // update GUI
}
void IdDialog::grantCircleMembership()
{
RsGxsCircleId circle_id ;
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
return;
RsGxsId gxs_id_to_revoke(qobject_cast<QAction*>(sender())->data().toString().toStdString());
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
std::list<RsGxsGroupId> grps ;
grps.push_back(RsGxsGroupId(circle_id));
uint32_t token;
mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grps, CIRCLESDIALOG_GROUPUPDATE);
CircleUpdateOrder c ;
c.token = token ;
c.gxs_id = gxs_id_to_revoke ;
c.action = CircleUpdateOrder::GRANT_MEMBERSHIP ;
mCircleUpdates[token] = c ;
}
void IdDialog::revokeCircleMembership()
{
RsGxsCircleId circle_id ;
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
return;
RsGxsId gxs_id_to_revoke(qobject_cast<QAction*>(sender())->data().toString().toStdString());
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
std::list<RsGxsGroupId> grps ;
grps.push_back(RsGxsGroupId(circle_id));
uint32_t token;
mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grps, CIRCLESDIALOG_GROUPUPDATE);
CircleUpdateOrder c ;
c.token = token ;
c.gxs_id = gxs_id_to_revoke ;
c.action = CircleUpdateOrder::REVOKE_MEMBERSHIP ;
mCircleUpdates[token] = c ;
}
void IdDialog::acceptCircleSubscription()
{
RsGxsCircleId circle_id ;
@ -828,6 +951,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
RsGxsId current_gxs_id ;
RsGxsId item_id(item->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString());
bool is_circle ;
bool am_I_circle_admin = false ;
if(item_id == RsGxsId(circle_id)) // is it a circle?
{
@ -838,11 +962,14 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
{
#endif
if(group_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)
{
contextMnu.addAction(QIcon(IMAGE_EDIT), tr("Edit Circle"), this, SLOT(showEditExistingCircle()));
am_I_circle_admin = true ;
}
else
contextMnu.addAction(QIcon(IMAGE_EDIT), tr("See details"), this, SLOT(showEditExistingCircle()));
contextMnu.addAction(QIcon(IMAGE_INFO), tr("See details"), this, SLOT(showEditExistingCircle()));
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES
}
}
#endif
std::cerr << " Item is a circle item. Adding Edit/Details menu entry." << std::endl;
@ -850,10 +977,16 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
contextMnu.addSeparator() ;
}
else if(rsIdentity->isOwnId(item_id)) // is it one of our GXS ids?
else
{
current_gxs_id = RsGxsId(item_id);
is_circle =false ;
is_circle =false ;
if(item->parent() != NULL)
{
uint32_t group_flags = item->parent()->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt();
am_I_circle_admin = bool(group_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) ;
}
std::cerr << " Item is a GxsId item. Requesting flags/group id from parent: " << circle_id << std::endl;
}
@ -872,7 +1005,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
static const int CANCEL = 3 ; // Admin list: no Subscription request: yes
const QString menu_titles[4] = { tr("Request subscription"), tr("Accept circle invitation"), tr("Quit this circle"),tr("Cancel subscribe request")} ;
const QString image_names[4] = { ":/images/edit_16.png",":/images/edit_16.png",":/images/edit_16.png",":/images/edit_16.png" } ;
const QString image_names[4] = { ":/images/edit_add24.png",":/images/accepted16.png",":/images/door_in.png",":/images/cancel.png" } ;
std::vector< std::vector<RsGxsId> > ids(4) ;
@ -911,7 +1044,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
RsIdentityDetails det ;
QString id_name ;
if(rsIdentity->getIdDetails(ids[i][0],det))
id_name = tr("for identity ")+QString::fromUtf8(det.mNickname.c_str()) + "(ID=" + QString::fromStdString(ids[i][0].toStdString()) + ")" ;
id_name = tr("for identity ")+QString::fromUtf8(det.mNickname.c_str()) + " (ID=" + QString::fromStdString(ids[i][0].toStdString()) + ")" ;
else
id_name = tr("for identity ")+QString::fromStdString(ids[i][0].toStdString()) ;
@ -939,7 +1072,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
RsIdentityDetails det ;
QString id_name ;
if(rsIdentity->getIdDetails(ids[i][j],det))
id_name = tr("for identity ")+QString::fromUtf8(det.mNickname.c_str()) + "(ID=" + QString::fromStdString(ids[i][j].toStdString()) + ")" ;
id_name = tr("for identity ")+QString::fromUtf8(det.mNickname.c_str()) + " (ID=" + QString::fromStdString(ids[i][j].toStdString()) + ")" ;
else
id_name = tr("for identity ")+QString::fromStdString(ids[i][j].toStdString()) ;
@ -957,6 +1090,32 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
contextMnu.addMenu(menu) ;
}
}
if(!is_circle && am_I_circle_admin) // I am circle admin. I can therefore revoke/accept membership
{
std::map<RsGxsId,uint32_t>::const_iterator it = details.mSubscriptionFlags.find(current_gxs_id) ;
if(!current_gxs_id.isNull() && it != details.mSubscriptionFlags.end())
{
contextMnu.addSeparator() ;
if(it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST)
{
QAction *action = new QAction(tr("Revoke this member"),this) ;
action->setData(QString::fromStdString(current_gxs_id.toStdString()));
QObject::connect(action,SIGNAL(triggered()), this, SLOT(revokeCircleMembership()));
contextMnu.addAction(action) ;
}
else
{
QAction *action = new QAction(tr("Grant membership"),this) ;
action->setData(QString::fromStdString(current_gxs_id.toStdString()));
QObject::connect(action,SIGNAL(triggered()), this, SLOT(grantCircleMembership()));
contextMnu.addAction(action) ;
}
}
}
contextMnu.exec(QCursor::pos());
}
@ -1796,6 +1955,10 @@ void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req)
loadCircleGroupData(req.mToken);
break;
case CIRCLESDIALOG_GROUPUPDATE:
updateCircleGroup(req.mToken);
break;
default:
std::cerr << "CirclesDialog::loadRequest() ERROR: INVALID TYPE";
std::cerr << std::endl;
@ -1914,13 +2077,13 @@ void IdDialog::IdListCustomPopupMenu( QPoint )
contextMnu.addSeparator();
if(n_positive_reputations == 0) // only unban when all items are banned
contextMnu.addAction(QIcon(), tr("Set positive opinion"), this, SLOT(positivePerson()));
contextMnu.addAction(QIcon(":/images/vote_up.png"), tr("Set positive opinion"), this, SLOT(positivePerson()));
if(n_neutral_reputations == 0) // only unban when all items are banned
contextMnu.addAction(QIcon(), tr("Set neutral opinion"), this, SLOT(neutralPerson()));
contextMnu.addAction(QIcon(":/images/vote_neutral.png"), tr("Set neutral opinion"), this, SLOT(neutralPerson()));
if(n_negative_reputations == 0)
contextMnu.addAction(QIcon(":/images/denied16.png"), tr("Set negative opinion"), this, SLOT(negativePerson()));
contextMnu.addAction(QIcon(":/images/vote_down.png"), tr("Set negative opinion"), this, SLOT(negativePerson()));
}
if(one_item_owned_by_you && n_selected_items==1)

View File

@ -39,6 +39,15 @@ class IdDialog;
class UIStateHelper;
class QTreeWidgetItem;
struct CircleUpdateOrder
{
enum { UNKNOWN_ACTION=0x00, GRANT_MEMBERSHIP=0x01, REVOKE_MEMBERSHIP=0x02 };
uint32_t token ;
RsGxsId gxs_id ;
uint32_t action ;
};
class IdDialog : public RsGxsUpdateBroadcastPage, public TokenResponse
{
Q_OBJECT
@ -55,21 +64,24 @@ public:
protected:
virtual void updateDisplay(bool complete);
void loadCircleGroupMeta(const uint32_t &token);
void loadCircleGroupData(const uint32_t &token);
void requestCircleGroupMeta();
void requestCircleGroupData(const RsGxsCircleId& circle_id);
bool getItemCircleId(QTreeWidgetItem *item,RsGxsCircleId& id) ;
void loadCircleGroupMeta(const uint32_t &token);
void loadCircleGroupData(const uint32_t &token);
void updateCircleGroup(const uint32_t& token);
void requestCircleGroupMeta();
//void requestCircleGroupData(const RsGxsCircleId& circle_id);
bool getItemCircleId(QTreeWidgetItem *item,RsGxsCircleId& id) ;
private slots:
void createExternalCircle();
void showEditExistingCircle();
void createExternalCircle();
void showEditExistingCircle();
void updateCirclesDisplay();
void acceptCircleSubscription() ;
void cancelCircleSubscription() ;
void acceptCircleSubscription() ;
void cancelCircleSubscription() ;
void grantCircleMembership() ;
void revokeCircleMembership() ;
void filterComboBoxChanged();
void filterChanged(const QString &text);
@ -94,12 +106,12 @@ private slots:
#endif
void addtoContacts();
void removefromContacts();
void removefromContacts();
void negativePerson();
void positivePerson();
void neutralPerson();
static QString inviteMessage();
void sendInvite();
@ -132,7 +144,9 @@ private:
QTreeWidgetItem *ownItem;
QTreeWidgetItem *mExternalBelongingCircleItem;
QTreeWidgetItem *mExternalOtherCircleItem;
RsGxsUpdateBroadcastBase *mCirclesBroadcastBase ;
RsGxsUpdateBroadcastBase *mCirclesBroadcastBase ;
std::map<uint32_t, CircleUpdateOrder> mCircleUpdates ;
RsGxsGroupId mId;

View File

@ -123,14 +123,14 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
{
QIcon icon ;
icon.addPixmap(QPixmap(":/images/edit_add24.png")) ;
icon.addPixmap(QPixmap(":/images/user/add_user24.png")) ;
inviteFriendsButton->setIcon(icon) ;
inviteFriendsButton->setIconSize(QSize(2*S,2*S)) ;
}
connect(inviteFriendsButton, SIGNAL(clicked()), this , SLOT(inviteFriends()));
getChatWidget()->addChatBarWidget(inviteFriendsButton) ;
getChatWidget()->addTitleBarWidget(inviteFriendsButton) ;
RsGxsId current_id;
rsMsgs->getIdentityForChatLobby(lobbyId, current_id);
@ -159,7 +159,7 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
QIcon icon ;
icon.addPixmap(QPixmap(":/images/door_in.png")) ;
unsubscribeButton->setIcon(icon) ;
unsubscribeButton->setIconSize(QSize(1.5*S,1.5*S)) ;
unsubscribeButton->setIconSize(QSize(2*S,2*S)) ;
}
/* Initialize splitter */
@ -168,7 +168,7 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
connect(unsubscribeButton, SIGNAL(clicked()), this , SLOT(leaveLobby()));
getChatWidget()->addChatBarWidget(unsubscribeButton) ;
getChatWidget()->addTitleBarWidget(unsubscribeButton) ;
}
void ChatLobbyDialog::leaveLobby()

View File

@ -13,7 +13,7 @@
<property name="windowTitle">
<string notr="true">MainWindow</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QHBoxLayout" name="ChatLobbyDialogHLayout">
<property name="margin">
<number>0</number>
</property>
@ -52,7 +52,7 @@
<height>0</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QVBoxLayout" name="participantsFrameVLayout">
<property name="leftMargin">
<number>0</number>
</property>

View File

@ -121,6 +121,7 @@ ChatWidget::ChatWidget(QWidget *parent) :
ui->actionSearchWithoutLimit->setText(tr("Don't stop to color after")+" "+QString::number(uiMaxSearchLimitColor)+" "+tr("items found (need more CPU)"));
ui->markButton->setVisible(false);
ui->leSearch->setVisible(false);
ui->searchBefore->setVisible(false);
ui->searchBefore->setToolTip(tr("<b>Find Previous </b><br/><i>Ctrl+Shift+G</i>"));
@ -183,6 +184,8 @@ ChatWidget::ChatWidget(QWidget *parent) :
menu->addAction(ui->actionChooseFont);
menu->addAction(ui->actionChooseColor);
menu->addAction(ui->actionResetFont);
menu->addAction(ui->actionNoEmbed);
menu->addAction(ui->actionSendAsPlainText);
ui->fontButton->setMenu(menu);
menu = new QMenu();
@ -191,7 +194,8 @@ ChatWidget::ChatWidget(QWidget *parent) :
menu->addAction(ui->actionSaveChatHistory);
menu->addAction(ui->actionMessageHistory);
ui->pushtoolsButton->setMenu(menu);
ui->actionSendAsPlainText->setChecked(Settings->getChatSendAsPlainTextByDef());
ui->textBrowser->installEventFilter(this);
ui->textBrowser->viewport()->installEventFilter(this);
ui->chatTextEdit->installEventFilter(this);
@ -899,7 +903,8 @@ void ChatWidget::addChatMsg(bool incoming, const QString &name, const RsGxsId gx
// embed smileys ?
if (Settings->valueFromGroup(QString("Chat"), QString::fromUtf8("Emoteicons_PrivatChat"), true).toBool()) {
formatTextFlag |= RSHTML_FORMATTEXT_EMBED_SMILEYS;
if (!message.contains("NoEmbed=\"true\""))
formatTextFlag |= RSHTML_FORMATTEXT_EMBED_SMILEYS;
}
// Always fix colors
@ -1134,7 +1139,12 @@ void ChatWidget::sendChat()
}
QString text;
RsHtml::optimizeHtml(chatWidget, text);
if (ui->actionSendAsPlainText->isChecked()){
text = chatWidget->toPlainText();
text.replace(QChar(-4),"");//Char used when image on text.
} else {
RsHtml::optimizeHtml(chatWidget, text, (ui->actionNoEmbed->isChecked() ? RSHTML_FORMATTEXT_NO_EMBED : 0));
}
std::string msg = text.toUtf8().constData();
if (msg.empty()) {
@ -1188,7 +1198,7 @@ void ChatWidget::on_searchButton_clicked(bool bValue)
qtcCurrent=QTextCursor(qtdDocument);
}
ui->leSearch->setVisible(bValue);
ui->markButton->setVisible(bValue);
}
void ChatWidget::on_searchBefore_clicked()
{

View File

@ -1034,6 +1034,36 @@ border-image: url(:/images/closepressed.png)
<string>Save image</string>
</property>
</action>
<action name="actionSendAsPlainText">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/SimpleText.png</normaloff>:/images/SimpleText.png</iconset>
</property>
<property name="text">
<string>Send as PlainText</string>
</property>
<property name="toolTip">
<string>Send as plain text without font.</string>
</property>
</action>
<action name="actionNoEmbed">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/SmileyText.png</normaloff>:/images/SmileyText.png</iconset>
</property>
<property name="text">
<string>Don't replace tag with Emote Icon.</string>
</property>
<property name="toolTip">
<string>Don't replace tag with Emote Icon.</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@ -103,9 +103,6 @@ ConfCertDialog::ConfCertDialog(const RsPeerId& id, const RsPgpId &pgp_id, QWidge
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(close()));
connect(ui._shouldAddSignatures_CB, SIGNAL(toggled(bool)), this, SLOT(loadInvitePage()));
//connect(ui.denyFriendButton, SIGNAL(clicked()), this, SLOT(denyFriend()));
//connect(ui._shouldAddSignatures_CB_2, SIGNAL(toggled(bool)), this, SLOT(loadInvitePage()));
ui.avatar->setFrameType(AvatarWidget::NORMAL_FRAME);
MainWindow *w = MainWindow::getInstance();
@ -116,32 +113,16 @@ ConfCertDialog::ConfCertDialog(const RsPeerId& id, const RsPgpId &pgp_id, QWidge
ConfCertDialog::~ConfCertDialog()
{
// if(peerId.isNull())
{
QMap<RsPeerId, ConfCertDialog*>::iterator it = instances_ssl.find(peerId);
if (it != instances_ssl.end())
instances_ssl.erase(it);
}
// else
{
QMap<RsPgpId, ConfCertDialog*>::iterator it = instances_pgp.find(pgpId);
if (it != instances_pgp.end())
instances_pgp.erase(it);
}
QMap<RsPeerId, ConfCertDialog*>::iterator it = instances_ssl.find(peerId);
if (it != instances_ssl.end())
instances_ssl.erase(it);
QMap<RsPgpId, ConfCertDialog*>::iterator it2 = instances_pgp.find(pgpId);
if (it2 != instances_pgp.end())
instances_pgp.erase(it2);
}
void ConfCertDialog::setServiceFlags()
{
ServicePermissionFlags flags(0) ;
if( ui._direct_transfer_CB->isChecked()) flags = flags | RS_NODE_PERM_DIRECT_DL ;
if( ui._allow_push_CB->isChecked()) flags = flags | RS_NODE_PERM_ALLOW_PUSH ;
if( ui._require_WL_CB->isChecked()) flags = flags | RS_NODE_PERM_REQUIRE_WL ;
rsPeers->setServicePermissionFlags(pgpId,flags) ;
}
void ConfCertDialog::loadAll()
{
for(QMap<RsPeerId, ConfCertDialog*>::iterator it = instances_ssl.begin(); it != instances_ssl.end(); ++it) it.value()->load();
@ -161,10 +142,6 @@ void ConfCertDialog::load()
return;
}
ui._direct_transfer_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_DIRECT_DL ) ;
ui._allow_push_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_ALLOW_PUSH) ;
ui._require_WL_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_REQUIRE_WL) ;
//ui.pgpfingerprint->setText(QString::fromUtf8(detail.name.c_str()));
ui.peerid->setText(QString::fromStdString(detail.id.toStdString()));
@ -349,55 +326,53 @@ void ConfCertDialog::applyDialog()
RsPeerDetails detail;
if (!rsPeers->getPeerDetails(peerId, detail))
{
if (!rsPeers->getGPGDetails(pgpId, detail)) {
QMessageBox::information(this,
tr("RetroShare"),
tr("Error : cannot get peer details."));
close();
return;
}
if (!rsPeers->getGPGDetails(pgpId, detail)) {
QMessageBox::information(this,
tr("RetroShare"),
tr("Error : cannot get peer details."));
close();
return;
}
}
if(!detail.isHiddenNode)
{
/* check if the data is the same */
bool localChanged = false;
bool extChanged = false;
bool dnsChanged = false;
if(!detail.isHiddenNode)
{
/* check if the data is the same */
bool localChanged = false;
bool extChanged = false;
bool dnsChanged = false;
/* set local address */
if ((detail.localAddr != ui.localAddress->text().toStdString()) || (detail.localPort != ui.localPort -> value()))
localChanged = true;
/* set local address */
if ((detail.localAddr != ui.localAddress->text().toStdString()) || (detail.localPort != ui.localPort -> value()))
localChanged = true;
if ((detail.extAddr != ui.extAddress->text().toStdString()) || (detail.extPort != ui.extPort -> value()))
extChanged = true;
if ((detail.extAddr != ui.extAddress->text().toStdString()) || (detail.extPort != ui.extPort -> value()))
extChanged = true;
if ((detail.dyndns != ui.dynDNS->text().toStdString()))
dnsChanged = true;
if ((detail.dyndns != ui.dynDNS->text().toStdString()))
dnsChanged = true;
/* now we can action the changes */
if (localChanged)
rsPeers->setLocalAddress(peerId, ui.localAddress->text().toStdString(), ui.localPort->value());
/* now we can action the changes */
if (localChanged)
rsPeers->setLocalAddress(peerId, ui.localAddress->text().toStdString(), ui.localPort->value());
if (extChanged)
rsPeers->setExtAddress(peerId,ui.extAddress->text().toStdString(), ui.extPort->value());
if (extChanged)
rsPeers->setExtAddress(peerId,ui.extAddress->text().toStdString(), ui.extPort->value());
if (dnsChanged)
rsPeers->setDynDNS(peerId, ui.dynDNS->text().toStdString());
if (dnsChanged)
rsPeers->setDynDNS(peerId, ui.dynDNS->text().toStdString());
if(localChanged || extChanged || dnsChanged)
emit configChanged();
}
else
{
if((detail.hiddenNodeAddress != ui.localAddress->text().toStdString()) || (detail.hiddenNodePort != ui.localPort->value()))
{
rsPeers->setHiddenNode(peerId,ui.localAddress->text().toStdString(), ui.localPort->value());
emit configChanged();
}
}
setServiceFlags() ;
if(localChanged || extChanged || dnsChanged)
emit configChanged();
}
else
{
if((detail.hiddenNodeAddress != ui.localAddress->text().toStdString()) || (detail.hiddenNodePort != ui.localPort->value()))
{
rsPeers->setHiddenNode(peerId,ui.localAddress->text().toStdString(), ui.localPort->value());
emit configChanged();
}
}
loadAll();
close();

View File

@ -76,11 +76,7 @@ private:
private slots:
void applyDialog();
//void makeFriend();
//void denyFriend();
//void signGPGKey();
void loadInvitePage();
void setServiceFlags();
void showHelpDialog();
/** Called when a child window requests the given help <b>topic</b>. */

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>678</width>
<height>727</height>
<width>742</width>
<height>915</height>
</rect>
</property>
<property name="windowTitle">
@ -35,6 +35,7 @@
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<zorder>stabWidget</zorder>
</widget>
</item>
<item row="1" column="0">
@ -60,7 +61,7 @@
<item row="0" column="0">
<widget class="QTabWidget" name="stabWidget">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="icon">
@ -407,6 +408,13 @@
<string>Retroshare Certificate</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Use this certificate to make friends:</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="userCertificateText"/>
</item>
@ -436,60 +444,6 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/admin-16.png</normaloff>:/images/admin-16.png</iconset>
</attribute>
<attribute name="title">
<string>Options</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0" colspan="2">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>196</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="_direct_transfer_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Retroshare periodically checks your friend lists for browsable files matching your transfers, to establish a direct transfer. In this case, your friend knows you're downloading the file.&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;To prevent this behavior for this friend only, uncheck this box. You can still perform a direct transfer if you explicitly ask for it, by e.g. downloading from your friend's file list. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Use as direct source, when available</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="_allow_push_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option allows you to automatically download a file that is recommended in an message coming from this node. This can be used for instance to send files between your own nodes.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Auto-download recommended files from this node</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="_require_WL_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Peers that have this option cannot connect if their connection address is not in the whitelist. This protects you from traffic forwarding attacks. When used, rejected peers will be reported by &amp;quot;security feed items&amp;quot; in the News Feed section. From there, you can whitelist/blacklist their IP.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Require white list clearance</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@ -145,45 +145,24 @@ void PGPKeyDialog::load()
ui.make_friend_button->setToolTip("") ;
}
//ui._direct_transfer_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_DIRECT_DL ) ;
//ui._allow_push_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_ALLOW_PUSH) ;
ui.name->setText(QString::fromUtf8(detail.name.c_str()));
//ui.peerid->setText(QString::fromStdString(detail.id.toStdString()));
//RetroShareLink link;
//link.createPerson(detail.gpg_id);
//ui.rsid->setText(QString::fromStdString(detail.gpg_id.toStdString())) ;
ui.pgpfingerprint->setText(misc::fingerPrintStyleSplit(QString::fromStdString(detail.fpr.toStdString())));
//ui.rsid->setToolTip(link.title());
//ui.avatar->setId(pgpId.toStdString(), true);
// ui.rsid->show();
// ui.peerid->hide();
// ui.label_id->hide();
// ui.label_rsid->show();
ui.pgpfingerprint->show();
ui.pgpfingerprint_label->show();
// ui.loc->hide();
// ui.label_loc->hide();
// ui.statusline->hide();
// ui.label_status->hide();
// ui.lastcontact->hide();
// ui.label_last_contact->hide();
// ui.version->hide();
// ui.label_version->hide();
// ui.groupBox_4->hide();
// ui.crypto_info->hide();
// ui.crypto_label->hide();
// ui.groupBox->hide();
// ui.tabWidget->hide();
ui._direct_transfer_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_DIRECT_DL ) ;
ui._allow_push_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_ALLOW_PUSH) ;
ui._require_WL_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_REQUIRE_WL) ;
uint32_t max_upload_speed = 0 ;
uint32_t max_download_speed = 0 ;
rsPeers->getPeerMaximumRates(pgpId,max_upload_speed,max_download_speed);
ui.maxUploadSpeed_SB->setValue(max_upload_speed) ;
ui.maxDownloadSpeed_SB->setValue(max_download_speed) ;
if (detail.gpg_id == rsPeers->getGPGOwnId())
{
ui.make_friend_button->hide();
@ -323,7 +302,6 @@ void PGPKeyDialog::loadKeyPage()
ui.userCertificateText_2->setToolTip(helptext) ;
}
void PGPKeyDialog::applyDialog()
{
std::cerr << "PGPKeyDialog::applyDialog() called" << std::endl ;
@ -343,6 +321,19 @@ void PGPKeyDialog::applyDialog()
if(ui.trustlevel_CB->currentIndex() != (int)detail.trustLvl)
rsPeers->trustGPGCertificate(pgpId, ui.trustlevel_CB->currentIndex());
uint32_t max_upload_speed = ui.maxUploadSpeed_SB->value() ;
uint32_t max_download_speed = ui.maxDownloadSpeed_SB->value();
rsPeers->setPeerMaximumRates(pgpId,max_upload_speed,max_download_speed);
ServicePermissionFlags flags(0) ;
if( ui._direct_transfer_CB->isChecked()) flags = flags | RS_NODE_PERM_DIRECT_DL ;
if( ui._allow_push_CB->isChecked()) flags = flags | RS_NODE_PERM_ALLOW_PUSH ;
if( ui._require_WL_CB->isChecked()) flags = flags | RS_NODE_PERM_REQUIRE_WL ;
rsPeers->setServicePermissionFlags(pgpId,flags) ;
//setServiceFlags() ;
loadAll();

View File

@ -27,7 +27,7 @@
<item>
<widget class="QTabWidget" name="stabWidget">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@ -175,7 +175,16 @@
</item>
<item>
<layout class="QHBoxLayout" name="friendAndSignLayout">
<property name="margin">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
@ -295,6 +304,16 @@ p, li { white-space: pre-wrap; }
<string>ASCII format</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Below is the node's PGP key. It identifies the node and all its locations. A &quot;Retroshare certificate&quot; that you can exchange in order to make friends, is in the the &quot;details&quot; of each separate location.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="userCertificateText_2">
<property name="sizePolicy">
@ -321,6 +340,115 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Options</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>These options apply to all locations of the same node:</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="_direct_transfer_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Retroshare periodically checks your friend lists for browsable files matching your transfers, to establish a direct transfer. In this case, your friend knows you're downloading the file.&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;To prevent this behavior for this friend only, uncheck this box. You can still perform a direct transfer if you explicitly ask for it, by e.g. downloading from your friend's file list. This setting is applied to all locations of the same node.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Use as direct source, when available</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="_allow_push_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option allows you to automatically download a file that is recommended in an message coming from this node. This can be used for instance to send files between your own nodes. Applied to all locations of the same node.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Auto-download recommended files from this node</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="_require_WL_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Peers that have this option cannot connect if their connection address is not in the whitelist. This protects you from traffic forwarding attacks. When used, rejected peers will be reported by &amp;quot;security feed items&amp;quot; in the News Feed section. From there, you can whitelist/blacklist their IP. Applies to all locations of the same node.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Require white list clearance</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Max upload speed (0=unlimited)</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Max download speed (0=unlimited)</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QSpinBox" name="maxUploadSpeed_SB">
<property name="suffix">
<string> kB/s</string>
</property>
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="maxDownloadSpeed_SB">
<property name="suffix">
<string> kB/s</string>
</property>
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>274</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
<item>
@ -334,6 +462,9 @@ p, li { white-space: pre-wrap; }
</widget>
</item>
</layout>
<zorder>stabWidget</zorder>
<zorder>headerFrame</zorder>
<zorder>buttonBox</zorder>
</widget>
<customwidgets>
<customwidget>

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>928</width>
<height>769</height>
<width>828</width>
<height>612</height>
</rect>
</property>
<property name="windowTitle">
@ -208,222 +208,6 @@
</layout>
</widget>
</item>
<item row="4" column="0">
<widget class="QGroupBox" name="publishGroupBox">
<property name="title">
<string>Publish Signatures</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QRadioButton" name="publish_open">
<property name="text">
<string>Open</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="publish_threads">
<property name="text">
<string>New Thread</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="publish_required">
<property name="text">
<string>Required</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="publish_encrypt">
<property name="text">
<string>Encrypted Msgs</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="5" column="0">
<widget class="QGroupBox" name="personalGroupBox">
<property name="title">
<string>Personal Signatures</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QRadioButton" name="personal_pgp">
<property name="text">
<string>PGP Required</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="personal_required">
<property name="text">
<string>Signature Required</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="personal_ifnopub">
<property name="text">
<string>If No Publish Signature</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="6" column="0">
<widget class="QGroupBox" name="commentGroupBox">
<property name="title">
<string>Comments</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QRadioButton" name="comments_allowed">
<property name="text">
<string>Allow Comments</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="comments_no">
<property name="text">
<string>No Comments</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="7" column="0">
<widget class="QGroupBox" name="spamProtection_GB">
<property name="title">
<string>Spam-protection</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QCheckBox" name="antiSpam_signedIds">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This makes the media increase the reputation threshold to 0.4 for anonymous ids, while keeping it to 0.0 for PGP-linked ids. Therefore, anonymous ids can still post, if their local reputation score is above that threshold.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Favor PGP-signed ids</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="antiSpam_trackMessages">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;This feature allows Retroshare to locally keep a record of who forwarded each message to you, for the last 10 days. Although useless if alone (and already available whatsoever) this information can be used by a group of collaborative friends to easily locate the source of spams. To be used with care, since it significantly decreases the anonymity of message posts.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Keep track of posts</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="8" column="0" colspan="2">
<widget class="QFrame" name="extraFrame">
<property name="frameShape">
@ -631,6 +415,222 @@
</layout>
</widget>
</item>
<item row="3" column="0">
<widget class="QGroupBox" name="publishGroupBox">
<property name="title">
<string>Publish Signatures</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QRadioButton" name="publish_open">
<property name="text">
<string>Open</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="publish_threads">
<property name="text">
<string>New Thread</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="publish_required">
<property name="text">
<string>Required</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="publish_encrypt">
<property name="text">
<string>Encrypted Msgs</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="4" column="0">
<widget class="QGroupBox" name="personalGroupBox">
<property name="title">
<string>Personal Signatures</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QRadioButton" name="personal_pgp">
<property name="text">
<string>PGP Required</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="personal_required">
<property name="text">
<string>Signature Required</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="personal_ifnopub">
<property name="text">
<string>If No Publish Signature</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="5" column="0">
<widget class="QGroupBox" name="commentGroupBox">
<property name="title">
<string>Comments</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QRadioButton" name="comments_allowed">
<property name="text">
<string>Allow Comments</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="comments_no">
<property name="text">
<string>No Comments</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="6" column="0">
<widget class="QGroupBox" name="spamProtection_GB">
<property name="title">
<string>Spam-protection</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QCheckBox" name="antiSpam_signedIds">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This makes the media increase the reputation threshold to 0.4 for anonymous ids, while keeping it to 0.0 for PGP-linked ids. Therefore, anonymous ids can still post, if their local reputation score is above that threshold.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Favor PGP-signed ids</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="antiSpam_trackMessages">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;This feature allows Retroshare to locally keep a record of who forwarded each message to you, for the last 10 days. Although useless if alone (and already available whatsoever) this information can be used by a group of collaborative friends to easily locate the source of spams. To be used with care, since it significantly decreases the anonymity of message posts.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Keep track of posts</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="showmode">

View File

@ -14,6 +14,18 @@
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="threadSplitter">
<property name="orientation">
@ -36,7 +48,16 @@
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="margin">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
@ -449,7 +470,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="">
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="RSImageBlockWidget" name="imageBlockWidget" native="true">

View File

@ -554,6 +554,7 @@
<file>images/view_split_top_bottom.png</file>
<file>images/vote_up.png</file>
<file>images/vote_down.png</file>
<file>images/vote_neutral.png</file>
<file>images/window_fullscreen.png</file>
<file>images/window_nofullscreen.png</file>
<file>images/identity/identities_32.png</file>
@ -657,5 +658,8 @@
<file>images/rsmessenger16.png</file>
<file>images/rsmessenger32.png</file>
<file>images/rsmessenger48.png</file>
<file>images/SmileyText.png</file>
<file>images/SimpleText.png</file>
<file>images/ColoredText.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -521,6 +521,7 @@ SubFileItem QProgressBar#progressBar::chunk {
border-top-left-radius: 7px;
border-bottom-left-radius: 7px;
border: 1px solid black;
width: 15px;
}
PluginItem QLabel#infoLabel {

View File

@ -100,7 +100,7 @@ ChatPage::ChatPage(QWidget * parent, Qt::WindowFlags flags)
/* Invoke the Qt Designer generated object setup routine */
ui.setupUi(this);
connect(ui.distantChatcomboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(distantChatComboBoxChanged(int)));
connect(ui.distantChatComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(distantChatComboBoxChanged(int)));
#if QT_VERSION < 0x040600
ui.minimumContrastLabel->hide();
@ -123,12 +123,13 @@ ChatPage::save(QString &/*errmsg*/)
Settings->setValue("MinimumContrast", ui.minimumContrast->value());
Settings->endGroup();
// state of distant Chat combobox
Settings->setValue("DistantChat", ui.distantChatcomboBox->currentIndex());
Settings->setValue("DistantChat", ui.distantChatComboBox->currentIndex());
Settings->setChatScreenFont(fontTempChat.toString());
NotifyQt::getInstance()->notifyChatFontChanged();
Settings->setChatSendMessageWithCtrlReturn(ui.sendMessageWithCtrlReturn->isChecked());
Settings->setChatSendAsPlainTextByDef(ui.sendAsPlainTextByDef->isChecked());
Settings->setChatSearchCharToStartSearch(ui.sbSearch_CharToStart->value());
Settings->setChatSearchCaseSensitively(ui.cbSearch_CaseSensitively->isChecked());
@ -231,11 +232,12 @@ ChatPage::load()
// state of distant Chat combobox
int index = Settings->value("DistantChat", 0).toInt();
ui.distantChatcomboBox->setCurrentIndex(index);
ui.distantChatComboBox->setCurrentIndex(index);
fontTempChat.fromString(Settings->getChatScreenFont());
ui.sendMessageWithCtrlReturn->setChecked(Settings->getChatSendMessageWithCtrlReturn());
ui.sendAsPlainTextByDef->setChecked(Settings->getChatSendAsPlainTextByDef());
ui.sbSearch_CharToStart->setValue(Settings->getChatSearchCharToStartSearch());
ui.cbSearch_CaseSensitively->setChecked(Settings->getChatSearchCaseSensitively());

View File

@ -6,11 +6,11 @@
<rect>
<x>0</x>
<y>0</y>
<width>705</width>
<height>517</height>
<width>635</width>
<height>600</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<layout class="QGridLayout">
<item row="3" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
@ -20,15 +20,15 @@
<attribute name="title">
<string>General</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<layout class="QGridLayout" name="generalGLayout">
<item row="0" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_3">
<widget class="QGroupBox" name="distantGBox">
<property name="title">
<string>Distant Chat</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<layout class="QGridLayout" name="distantGBoxGLayout">
<item row="0" column="2">
<widget class="QComboBox" name="distantChatcomboBox">
<widget class="QComboBox" name="distantChatComboBox">
<item>
<property name="text">
<string>Everyone</string>
@ -47,7 +47,7 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="distantchatlabel">
<widget class="QLabel" name="distantChatLabel">
<property name="text">
<string>Accept encrypted distant chat from</string>
</property>
@ -57,9 +57,9 @@
</widget>
</item>
<item row="1" column="0">
<layout class="QVBoxLayout" name="verticalLayout_5">
<layout class="QVBoxLayout" name="leftVLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<widget class="QGroupBox" name="chatSettingsGBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
@ -69,7 +69,7 @@
<property name="title">
<string>Chat Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<layout class="QVBoxLayout" name="chatSettingsGBoxVLayout">
<item>
<widget class="QCheckBox" name="checkBox_emoteprivchat">
<property name="text">
@ -111,7 +111,7 @@
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="hl_minimumFontSize">
<layout class="QHBoxLayout" name="minimumFontSizeHLayout">
<property name="topMargin">
<number>0</number>
</property>
@ -123,7 +123,7 @@
</widget>
</item>
<item>
<spacer name="hs_minimumFontSize">
<spacer name="minimumFontSizeHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@ -168,7 +168,7 @@
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_40">
<layout class="QHBoxLayout" name="minimumContrastHLayout">
<item>
<widget class="QLabel" name="minimumContrastLabel">
<property name="text">
@ -177,7 +177,7 @@
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<spacer name="minimumContrastHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@ -211,15 +211,22 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="sendAsPlainTextByDef">
<property name="text">
<string>Send as plain text by default</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="chatLobbyGroupBox">
<widget class="QGroupBox" name="chatLobbyGBox">
<property name="title">
<string>Chat Lobby</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<layout class="QVBoxLayout" name="chatLobbyGBoxVLayout">
<item>
<widget class="QCheckBox" name="chatLobby_Blink">
<property name="text">
@ -228,7 +235,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<widget class="QLabel" name="defIDLabel">
<property name="text">
<string>Default identity for chat lobbies:</string>
</property>
@ -237,7 +244,7 @@
<item>
<layout class="QHBoxLayout" name="nickNameLayout">
<item>
<spacer name="horizontalSpacer">
<spacer name="chatLobbyIdentity_HSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@ -261,7 +268,7 @@
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<spacer name="leftVSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
@ -276,13 +283,13 @@
</layout>
</item>
<item row="1" column="1">
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QVBoxLayout" name="rightVLayout">
<item>
<widget class="QGroupBox" name="groupBox_2">
<widget class="QGroupBox" name="privateChatGBox">
<property name="title">
<string>Private Chat</string>
</property>
<layout class="QVBoxLayout" name="_2">
<layout class="QVBoxLayout" name="privateChatGBoxVLayout">
<item>
<widget class="QCheckBox" name="chat_NewWindow">
<property name="text">
@ -315,11 +322,11 @@
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxIRCColors">
<widget class="QGroupBox" name="chatFontGBox">
<property name="title">
<string>Chat Font</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<layout class="QVBoxLayout" name="chatFontGBoxVLayout">
<property name="spacing">
<number>2</number>
</property>
@ -366,7 +373,7 @@
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxSearch">
<widget class="QGroupBox" name="searchGBox">
<property name="title">
<string>Search by default</string>
</property>
@ -530,7 +537,7 @@
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<spacer name="rightVSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
@ -550,9 +557,9 @@
<attribute name="title">
<string>History</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="historyVLayout">
<item>
<widget class="QLabel" name="label_8">
<widget class="QLabel" name="histHeaderLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
@ -574,11 +581,11 @@
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<layout class="QHBoxLayout" name="histSetupVLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<layout class="QGridLayout" name="histSetupGLayout">
<item row="0" column="1">
<widget class="QLabel" name="label_4">
<widget class="QLabel" name="publicHeaderLabel">
<property name="font">
<font>
<weight>75</weight>
@ -591,7 +598,7 @@
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_5">
<widget class="QLabel" name="privateHeaderLabel">
<property name="font">
<font>
<weight>75</weight>
@ -604,7 +611,7 @@
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_6">
<widget class="QLabel" name="lobbyHeaderLabel">
<property name="font">
<font>
<weight>75</weight>
@ -617,7 +624,7 @@
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<widget class="QLabel" name="labelChatEnable">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
@ -651,7 +658,7 @@
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label1">
<widget class="QLabel" name="labelChatSaveCount">
<property name="text">
<string>Saved messages (0 = unlimited):</string>
</property>
@ -718,7 +725,7 @@
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label2">
<widget class="QLabel" name="labelChatLoadCount">
<property name="text">
<string>Number of messages restored (0 = off):</string>
</property>
@ -769,7 +776,7 @@
</layout>
</item>
<item>
<spacer name="horizontalSpacer_4">
<spacer name="histSetupHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@ -784,15 +791,15 @@
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_5">
<widget class="QGroupBox" name="histGenGBox">
<property name="title">
<string>General</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
<layout class="QVBoxLayout" name="histGenGBoxVLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<layout class="QHBoxLayout" name="max_storage_period_HLayout">
<item>
<widget class="QLabel" name="label_3">
<widget class="QLabel" name="max_storage_period_Label">
<property name="text">
<string>Maximum storage period, in days (0=keep all):</string>
</property>
@ -802,7 +809,7 @@
<widget class="QSpinBox" name="max_storage_period"/>
</item>
<item>
<spacer name="horizontalSpacer_3">
<spacer name="max_storage_period_HSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@ -820,7 +827,7 @@
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<spacer name="histVSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
@ -838,7 +845,7 @@
<attribute name="title">
<string>Style</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QHBoxLayout" name="styleHLayout">
<item>
<widget class="QTabWidget" name="styleTabWidget">
<property name="tabPosition">
@ -851,11 +858,11 @@
<attribute name="title">
<string>Group chat</string>
</attribute>
<layout class="QVBoxLayout" name="publicLayout_1">
<layout class="QVBoxLayout" name="publicTabVLayout">
<item>
<layout class="QHBoxLayout" name="publiclLayout_2">
<layout class="QHBoxLayout" name="publicStyleHLayout">
<item>
<layout class="QVBoxLayout" name="publicLayout_3">
<layout class="QVBoxLayout" name="publicStyleListVLayout">
<item>
<widget class="QListWidget" name="publicList">
<property name="sizePolicy">
@ -873,7 +880,7 @@
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="publicLayout_4">
<layout class="QHBoxLayout" name="publicStyleVarHLayout">
<item>
<widget class="QLabel" name="publicLabelVariant">
<property name="sizePolicy">
@ -921,7 +928,7 @@
<enum>QLayout::SetFixedSize</enum>
</property>
<item>
<widget class="QLabel" name="labelPublicAuthor">
<widget class="QLabel" name="publicLabelAuthor">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -934,7 +941,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="labelPublicDescription">
<widget class="QLabel" name="publicLabelDescription">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -986,11 +993,11 @@
<attribute name="title">
<string>Private chat</string>
</attribute>
<layout class="QVBoxLayout" name="privateLayout_1">
<layout class="QVBoxLayout" name="privateTabVLayout">
<item>
<layout class="QHBoxLayout" name="privatelLayout_2">
<layout class="QHBoxLayout" name="privateStyleHLayout">
<item>
<layout class="QVBoxLayout" name="privateLayout_3">
<layout class="QVBoxLayout" name="privateStyleListVLayout">
<item>
<widget class="QListWidget" name="privateList">
<property name="sizePolicy">
@ -1008,7 +1015,7 @@
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="privateLayout_4">
<layout class="QHBoxLayout" name="privateStyleVarHLayout">
<item>
<widget class="QLabel" name="privateLabelVariant">
<property name="sizePolicy">
@ -1056,7 +1063,7 @@
<enum>QLayout::SetFixedSize</enum>
</property>
<item>
<widget class="QLabel" name="labelPrivateAuthor">
<widget class="QLabel" name="privateLabelAuthor">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -1069,7 +1076,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="labelPrivateDescription">
<widget class="QLabel" name="privateLabelDescription">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -1121,11 +1128,11 @@
<attribute name="title">
<string>History</string>
</attribute>
<layout class="QVBoxLayout" name="historyLayout_1">
<layout class="QVBoxLayout" name="historyTabVLayout">
<item>
<layout class="QHBoxLayout" name="historylLayout_2">
<layout class="QHBoxLayout" name="historyStyleHLayout">
<item>
<layout class="QVBoxLayout" name="historyLayout_3">
<layout class="QVBoxLayout" name="historyStyleListVLayout">
<item>
<widget class="QListWidget" name="historyList">
<property name="sizePolicy">
@ -1143,7 +1150,7 @@
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="historyLayout_4">
<layout class="QHBoxLayout" name="historyStyleVarHLayout">
<item>
<widget class="QLabel" name="historyLabelVariant">
<property name="sizePolicy">
@ -1191,7 +1198,7 @@
<enum>QLayout::SetFixedSize</enum>
</property>
<item>
<widget class="QLabel" name="labelHistoryAuthor">
<widget class="QLabel" name="historyLabelAuthor">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -1204,7 +1211,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="labelHistoryDescription">
<widget class="QLabel" name="historyLabelDescription">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>

View File

@ -48,6 +48,7 @@ GeneralPage::GeneralPage(QWidget * parent, Qt::WindowFlags flags)
ui.chkRunRetroshareAtSystemStartup->setEnabled(false);
ui.chkRunRetroshareAtSystemStartupMinimized->setEnabled(false);
#endif
ui.desktopFileMissingLabel->setVisible(false);
#else
ui.chkRunRetroshareAtSystemStartup->setVisible(false);

View File

@ -512,6 +512,26 @@ void RshareSettings::setChatSendMessageWithCtrlReturn(bool bValue)
setValueToGroup("Chat", "SendMessageWithCtrlReturn", bValue);
}
bool RshareSettings::getChatSendAsPlainTextByDef()
{
return valueFromGroup("Chat", "SendAsPlainTextByDef", false).toBool();
}
void RshareSettings::setChatSendAsPlainTextByDef(bool bValue)
{
setValueToGroup("Chat", "SendAsPlainTextByDef", bValue);
}
bool RshareSettings::getChatSearchShowBarByDefault()
{
return valueFromGroup("Chat", "SearchShowBarByDefault", false).toBool();
}
void RshareSettings::setChatSearchShowBarByDefault(bool bValue)
{
setValueToGroup("Chat", "SearchShowBarByDefault", bValue);
}
void RshareSettings::setChatSearchCharToStartSearch(int iValue)
{
setValueToGroup("Chat", "SearchCharToStartSearch", iValue);

View File

@ -209,6 +209,12 @@ public:
bool getChatSendMessageWithCtrlReturn();
void setChatSendMessageWithCtrlReturn(bool bValue);
bool getChatSendAsPlainTextByDef();
void setChatSendAsPlainTextByDef(bool bValue);
bool getChatSearchShowBarByDefault();
void setChatSearchShowBarByDefault(bool bValue);
void setChatSearchCharToStartSearch(int iValue);
int getChatSearchCharToStartSearch();

View File

@ -46,6 +46,10 @@
#include "util/RsGxsUpdateBroadcast.h"
#include "gui/settings/WebuiPage.h"
#ifdef SIGFPE_DEBUG
#include <fenv.h>
#endif
#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0)
#ifdef WINDOWS_SYS
#include <QFileDialog>
@ -155,6 +159,9 @@ int main(int argc, char *argv[])
QApplication app(argc, argv);
QDir::setCurrent(QCoreApplication::applicationDirPath());
}
#endif
#ifdef SIGFPE_DEBUG
feenableexcept(FE_INVALID | FE_DIVBYZERO);
#endif
QStringList args = char_array_to_stringlist(argv+1, argc-1);

View File

@ -27,9 +27,11 @@ QProgressBar:horizontal {
text-align: center;
padding: 1px;
background: #201F1F;
width: 15px;
}
QProgressBar::chunk:horizontal {
background-color: qlineargradient(spread:reflect, x1:1, y1:0.545, x2:1, y2:0, stop:0 rgba(28, 66, 111, 255), stop:1 rgba(37, 87, 146, 255));
width: 15px;
}
QFrame#titleBarFrame, QFrame#toolBarFrame

View File

@ -12,6 +12,7 @@ DEFINES += TARGET=\\\"$TARGET\\\"
#
#CONFIG += unfinished
#CONFIG += debug
#DEFINES *= SIGFPE_DEBUG
#QMAKE_CFLAGS += -fmudflap
#LIBS *= /usr/lib/gcc/x86_64-linux-gnu/4.4/libmudflap.a /usr/lib/gcc/x86_64-linux-gnu/4.4/libmudflapth.a
@ -196,7 +197,7 @@ win32 {
LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a
# create lib directory
QMAKE_PRE_LINK = $(CHK_DIR_EXISTS) lib $(MKDIR) lib
QMAKE_PRE_LINK = $(CHK_DIR_EXISTS) lib || $(MKDIR) lib
DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T

View File

@ -167,6 +167,9 @@ Rshare::Rshare(QStringList args, int &argc, char **argv, const QString &dir)
std::cerr << "Rshare::Rshare Connection etablished. Waiting for disconnection." << std::endl;
localSocket.waitForDisconnected(1000);
newArgs.detach();
std::cerr << "Rshare::Rshare Arguments was sended." << std::endl
<< " To disable it, in Options - General - Misc," << std::endl
<< " uncheck \"Use Local Server to get new Arguments\"." << std::endl;
::exit(EXIT_SUCCESS); // Terminate the program using STDLib's exit function
}
newArgs.detach();

View File

@ -874,6 +874,12 @@ static void styleCreate(QDomDocument& doc
optAttr = doc.createAttribute("RSOptimized");
optAttr.setValue("v2");
styleElem.attributes().setNamedItem(optAttr);
if (flag & RSHTML_FORMATTEXT_NO_EMBED) {
QDomAttr noEmbedAttr;
noEmbedAttr = doc.createAttribute("NoEmbed");
noEmbedAttr.setValue("true");
styleElem.attributes().setNamedItem(noEmbedAttr);
}
}
while(styleElem.childNodes().count()>0) {

View File

@ -31,19 +31,19 @@
#define HANDLE_RICH_TEXT_H_
/* Flags for RsHtml::formatText */
#define RSHTML_FORMATTEXT_EMBED_SMILEYS 1
#define RSHTML_FORMATTEXT_EMBED_LINKS 2
#define RSHTML_FORMATTEXT_OPTIMIZE 4
#define RSHTML_FORMATTEXT_REPLACE_LINKS 8
#define RSHTML_FORMATTEXT_REMOVE_COLOR 16
#define RSHTML_FORMATTEXT_FIX_COLORS 32 /* Make text readable */
#define RSHTML_FORMATTEXT_REMOVE_FONT_WEIGHT 64 /* Remove bold */
#define RSHTML_FORMATTEXT_REMOVE_FONT_STYLE 128 /* Remove italics */
#define RSHTML_FORMATTEXT_REMOVE_FONT_FAMILY 256
#define RSHTML_FORMATTEXT_REMOVE_FONT_SIZE 512
#define RSHTML_FORMATTEXT_EMBED_SMILEYS 0x0001//1
#define RSHTML_FORMATTEXT_EMBED_LINKS 0x0002//2
#define RSHTML_FORMATTEXT_OPTIMIZE 0x0004//4
#define RSHTML_FORMATTEXT_REPLACE_LINKS 0x0008//8
#define RSHTML_FORMATTEXT_REMOVE_COLOR 0x0010//16
#define RSHTML_FORMATTEXT_FIX_COLORS 0x0020//32 /* Make text readable */
#define RSHTML_FORMATTEXT_REMOVE_FONT_WEIGHT 0x0040//64 /* Remove bold */
#define RSHTML_FORMATTEXT_REMOVE_FONT_STYLE 0x0080//128 /* Remove italics */
#define RSHTML_FORMATTEXT_REMOVE_FONT_FAMILY 0x0100//256
#define RSHTML_FORMATTEXT_REMOVE_FONT_SIZE 0x0200//512
#define RSHTML_FORMATTEXT_REMOVE_FONT (RSHTML_FORMATTEXT_REMOVE_FONT_WEIGHT | RSHTML_FORMATTEXT_REMOVE_FONT_STYLE | RSHTML_FORMATTEXT_REMOVE_FONT_FAMILY | RSHTML_FORMATTEXT_REMOVE_FONT_SIZE)
#define RSHTML_FORMATTEXT_CLEANSTYLE (RSHTML_FORMATTEXT_REMOVE_FONT | RSHTML_FORMATTEXT_REMOVE_COLOR)
#define RSHTML_FORMATTEXT_NO_EMBED 0x0400//1024
/* Flags for RsHtml::optimizeHtml */
#define RSHTML_OPTIMIZEHTML_MASK (RSHTML_FORMATTEXT_CLEANSTYLE | RSHTML_FORMATTEXT_FIX_COLORS | RSHTML_FORMATTEXT_OPTIMIZE)

View File

@ -5,26 +5,34 @@
#don't exit even if a command fails
set +e
OLDLANG=${LANG}
export LANG=C
SCRIPT_PATH=$(dirname "`readlink -f "${0}"`")
if (ls &> /dev/null); then
echo "Retroshare Gui version : " > gui/help/version.html
echo "Retroshare Gui version : " > ${SCRIPT_PATH}/gui/help/version.html
if ( /usr/bin/git log -n 1 &> /dev/null); then
#retrieve git information
echo "Git version : $(git status | grep branch | cut -c 3-) $(git log -n 1 | grep commit)" >> gui/help/version.html
echo "Git version : $(git status | grep branch | head -n 1 | cut -c 4-) $(git log -n 1 | grep commit)" >> ${SCRIPT_PATH}/gui/help/version.html
fi
if ( /usr/bin/git log -n 1 | grep svn &> /dev/null); then
#retrieve git svn information
echo "Svn version : $(git log -n 1 | awk '/svn/ {print $2}' | head -1)" >> gui/help/version.html
echo "Svn version : $(git log -n 1 | awk '/svn/ {print $2}' | head -1)" >> ${SCRIPT_PATH}/gui/help/version.html
elif ( /usr/bin/git log -n 10 | grep svn &> /dev/null); then
#retrieve git svn information
echo "Svn closest version : $(git log -n 10 | awk '/svn/ {print $2}' | head -1)" >> gui/help/version.html
echo "Svn closest version : $(git log -n 10 | awk '/svn/ {print $2}' | head -1)" >> ${SCRIPT_PATH}/gui/help/version.html
fi
if ( /usr/bin/svn info &> /dev/null); then
echo "Svn version : $(svn info | awk '/^Revision:/ {print $NF}')" >> gui/help/version.html
echo "Svn version : $(svn info | awk '/^Revision:/ {print $NF}')" >> ${SCRIPT_PATH}/gui/help/version.html
fi
date >> gui/help/version.html
echo "" >> gui/help/version.html
echo "" >> gui/help/version.html
date >> ${SCRIPT_PATH}/gui/help/version.html
echo "" >> ${SCRIPT_PATH}/gui/help/version.html
echo "" >> ${SCRIPT_PATH}/gui/help/version.html
fi
export LANG=${OLDLANG}
echo "version_detail.sh scripts finished"
exit 0