merged with latest trunk

This commit is contained in:
csoler 2016-01-01 15:15:19 -05:00
commit 6ecd2991e7
2342 changed files with 29868 additions and 19573 deletions

View file

@ -7,7 +7,7 @@ before_install:
- echo $LANG
- echo $LC_ALL
- sudo apt-get update
- sudo apt-get install build-essential checkinstall cmake g++ git libavcodec-dev libavformat-dev libbz2-dev libcurl4-openssl-dev libdc1394-22-dev libglib2.0-dev libcv-dev libopencv-highgui-dev libhighgui-dev
- sudo apt-get install build-essential checkinstall cmake g++ git libavutil-dev libavcodec-dev libavformat-dev libbz2-dev libcurl4-openssl-dev libdc1394-22-dev libglib2.0-dev libcv-dev libopencv-highgui-dev libhighgui-dev
- sudo apt-get install libgnome-keyring-dev libgstreamer-plugins-base0.10-dev libgstreamer0.10-dev libjasper-dev libjpeg-dev libmicrohttpd-dev libopencv-dev libprotobuf-dev libqt4-dev
- sudo apt-get install libspeex-dev libspeexdsp-dev libsqlite3-dev libssl-dev libswscale-dev
- sudo apt-get install libtbb-dev libtiff4-dev libupnp-dev libv4l-dev libxine-dev libxslt1-dev libxss-dev make pkg-config protobuf-compiler python-dev python-numpy subversion git yasm qtmobility-dev

66
MacOS_X_InstallGuide.txt Normal file
View file

@ -0,0 +1,66 @@
#############################
###--- QT INSTALLATION ---###
#############################
###Install Qt via:
http://www.qt.io/download/
###Use default options.
###Add to the PATH environment variable with this temporary solution.
export PATH=/users/$USER/Qt/5.5/clang_64/bin:$PATH
###Depends on wich version of Qt you use.
##################################
###--- MACPORT INSTALLATION ---###
##################################
###Install MacPort and XCode following this guide:
http://guide.macports.org/#installing.xcode
###Start XCode to get it updated and to able C compiler to create executables.
###Install libraries
$sudo port -v selfupdate
$sudo port install openssl
$sudo port install miniupnpc
###For VOIP Plugin:
$sudo port install speex-devel
$sudo port install opencv
###Get Your OSX SDK if missing:
https://github.com/phracker/MacOSX-SDKs
###########################
###--- LAST SETTINGS ---###
###########################
###In QtCreator Option Git add its path:
C:\Program Files\Git\bin
### and select "Pull" with "Rebase"
###Compil missing libraries
###SQLCipher
cd <your development directory>
git clone https://github.com/sqlcipher/sqlcipher.git
cd sqlcipher
./configure --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="-lcrypto"
make
sudo make install
#NOTE, might be necessary to chmod 000 /usr/local/ssl temporarily during ./configure if
#homebrew uses newer, non-stock ssl dependencies found there. configure might get confused.
### libMicroHTTPD: The one with port don't have good support.
cd <your development directory>
wget http://ftpmirror.gnu.org/libmicrohttpd/libmicrohttpd-0.9.46.tar.gz
tar zxvf libmicrohttpd-0.9.46.tar.gz
cd libmicrohttpd-0.9.46
bash ./configure
sudo make install
###You can now compile RS into Qt Creator or with terminal
cd <your development directory>
git clone https://github.com/RetroShare/RetroShare.git retroshare
cd retroshare
qmake;make
###You can find compiled application on ./retroshare/retroshare-gui/src/RetroShare06.app

View file

@ -10,7 +10,7 @@ Compilation on Linux
```bash
sudo apt-get install libglib2.0-dev libupnp-dev qt4-dev-tools \
libqt4-dev libssl-dev libxss-dev libgnome-keyring-dev libbz2-dev \
libqt4-opengl-dev libqtmultimediakit1 qtmobility-dev \
libqt4-opengl-dev libqtmultimediakit1 qtmobility-dev libsqlcipher-dev \
libspeex-dev libspeexdsp-dev libxslt1-dev libcurl4-openssl-dev \
libopencv-dev tcl8.5 libmicrohttpd-dev
```

View file

@ -7,7 +7,6 @@ SUBDIRS += \
libbitdht \
libretroshare \
libresapi \
pegmarkdown \
retroshare_gui \
retroshare_nogui \
plugins
@ -22,10 +21,8 @@ libretroshare.depends = openpgpsdk libbitdht
libresapi.file = libresapi/src/libresapi.pro
libresapi.depends = libretroshare
pegmarkdown.file = supportlibs/pegmarkdown/pegmarkdown.pro
retroshare_gui.file = retroshare-gui/src/retroshare-gui.pro
retroshare_gui.depends = libretroshare libresapi pegmarkdown
retroshare_gui.depends = libretroshare libresapi
retroshare_gui.target = retroshare-gui
retroshare_nogui.file = retroshare-nogui/src/retroshare-nogui.pro
@ -35,3 +32,9 @@ retroshare_nogui.target = retroshare-nogui
plugins.file = plugins/plugins.pro
plugins.depends = retroshare_gui
plugins.target = plugins
wikipoos {
SUBDIRS += pegmarkdown
pegmarkdown.file = supportlibs/pegmarkdown/pegmarkdown.pro
retroshare_gui.depends += pegmarkdown
}

11
Start_RetroShare-Gui_Debug.bat Executable file
View file

@ -0,0 +1,11 @@
set QTDIR=C:\Qt\5.5\mingw492_32
set LIBS=..\libs
set RSPATH=.\retroshare-gui\src\debug
set PATH=%QTDIR%\bin;%LIBS%\bin;%PATH%
If not exist %RSPATH%\RetroShare06.exe (
build-all-mingw32make.bat
)
%RSPATH%\RetroShare06.exe

400
TODO.txt
View file

@ -1,301 +1,85 @@
List of pending non backward compatible changes
===============================================
* RsGxsGrpMetaData::deserialis should use a proper TLV_STR_TYPE_NAME instead of 0 for mGroupName and mMsgName, in rsgxsdata.cc
* p3IdService::service_CreateGroup() should convert the mPgpSign member to radix64!! For now it is hard-coded in binary in a string.
List of fixes/improvements before 0.6
=====================================
Legend:
E: easy. Just GUI stuff, no algorithmics involved
M: medium. Needs some care.
H: hard. Needs digging into libretroshare.
E: easy. Just GUI stuff, no algorithmics involved. That does not mean it's easy to come up with.
M: medium, either because it's a big task, or because it needs to understand a lot of code.
H: hard. Needs digging deep into libretroshare, possibly involving some crypto.
---------------------------------------- GUI TWEAKS FOR 0.6 RELEASE -------------------------------------------------
[ ] pending
[/] half-done, someone's on it
[-] cancelled
[X] done
To be done
PS: no tabs in this file,thx ;-)
----------------------------------------- TODO list ----------------------------------------------
GUI
[X] http://www.cjoint.com/c/EFlhWgeLg4F. Strings too long in Add Friends Wizard on the conclusion page.
[X] RS crashes when right clicking on the People tabs when there's nobody yet
[X] Network tab cannot shrink the avatar column
[X] newsfeed default:
Options -- Notify -- Feed
Security <-- Make as Default Enabled
Connect attempt <-- Make as Default Enabled
[X] make the "Wrong IP reported" security item less dramatic. We should add text saying that this can be due to a friend
connecting before your own RS has realized that its IP has changed.
[ ] it should be possible to completely disable IP change security items using a checkbox in options->notify->Feeds
These security items should be enabled by default
[X] "Wrong IP" security items shouldn't show up when the IP reported by friend is whitelisted.
[X] at login, when cancel is pressed, the system keeps asking for the passwd. It shouldn't, and directly go back to the list of locations.
0000 [ ] merge the various help systems. there's 3 of them: (1) help buttons on most tabs that pop a flat panel with some
info; (2) help wizard accessible from the "!" button in friends details->Trust; (3) 'getting started tab'
0001 [X] forums - middle horisontal bar - always shows *by anonymous* (from noname) [fixed, also removed useless thread line]
0002 [X] remove useless column in forums "signed by" (last column) (from electron)
0003 [ ] main window must close on ESC (from noname)
0004 [X] show storage time of forums/channels/posted in gui (from cave)
0005 [X] if keysigning is not working -> hide or remove it (from cave) cyril: keep it, but add more info about how to use/interpret it.
0006 [ ] implement default gxs id (from cave) cyril: you mean system-wide default gxs id? That would be a good thing to have.
0007 [ ] *getting started* - need to say about chatservers (from noname)
comment: chatservers are inofficial and may go down at any time. which one should we mention?
cyril: we could add a link to a search for RS chat servers in duckduck go
0008 [X] forum livetime too short (from noname) cyril: expand it to 1 year
0009 [ ] Settings -> Server -> show discovery information in statusbar. I've never seen any discovery info since the switch to
disc v2 - so i guess this option can be removed (from sehraf) cyril: that can be fixed. The link between GUI and discovery2 can
be restored. Also we should get rid of the code for discovery(1)
0010 [ ] window and tab sizes not saved on exit or closing (from noname)
0011 [X] in add friend dialog: include signatures seems to do nothing there. cyril: it does if you have signatures. Show
the checkbox only when the key as signatures => less confusion. (from noname)
0012 [ ] from time to time the location images and the location message is not updated or gets lost, or the location name. (from cave)
0013 [ ] new design, new icons, minimal UI (from purplehaze420) comment: use webui as base for minimal ui
cyril: we cannot change everything now. But purplehaze420 said he would provide a consistent set of icons. That would be great.
0014 [X] go to Settings -> Permissions: wait for scrollbars to appear go back to any other setting (e.g. Notify): the page now
needs the same space as the permission matrix (happens on windows + linux; can be "fixed" by closing and reopen the setting window)
(from sehraf)
0015 [X] The new statistics windows is really nice and everybody should see it -> add a link to it somewhere in settings
(or wherever suitable) (from sehraf) cyril: there's a menu in the bottom right corner ofthe main window to get it.
Otherwise, we could merge it as tabs in options->server, but I don't really like this option.
0016 [ ] many things are deeply hidden - config wizard, share manager, permissions, statistics (from noname)
comment: either the gui is overloaded with buttons or stuff is hidden. choose one
cyril: this is true. Config wizard and share manager could be made more obvious.
Config wizard could be integrated in "getting started" which means
to be improved anyway.
0017 [X] no tab configuraion for uploads section. no cache transfer disable option comment: cachetransfers will be removed (from noname)
cyril: rename "show cache transfers" into "show file lists transfers"
0018 [X] add friend dialog - add button for pasting from clipboard.
// some ppl dumb to use rightclich or keyboard)) and on the upper window some buttons exist, the lower one feels lonely.(from noname)
comment: teach to use the context menu, else they are lost in RS
0019 [X] no identity on first start makes impossible to start chat or post forums.
maybe config wizard should propose to create one, just asking a name desired. (from noname)
cyril: integrating in config wizard is a good idea: check if one identity is present, if not allow to create one.
Note that all ID choosers allow to create a new identity
0020 [ ] double click on completed download must open the file. or folder, configurable in options (from noname)
0028 [X] RTT statistics shouldn't show curves for offline peers
0029 [X] In options, rename "server"->"network", "transfer"->"file transfer".
0030 [X] forums - middle horisontal bar - post time is duplicate to the one in the list. also thread name.
forum name (the line with view mode) is duplicate to tab header.
button for new thread must have text, *reply to selected post* button must be placed next to it
the big subscribe button on the top, but never used.
generally,we have 2 panels here, both semi-empty. need to compact all the stuff
0031 [X] chats - participant list can't be extended in wide.
show/hide button is almost invisible. make it more big. but it takes space in width, so move it to bar with lobby name.
however, the lobby name bar also seems redundant. so maybe the button's final place must domewhere in the lower button bar.
0031a[ ] ... the lobby name bar also seems redundant ....
0032 [X] In Network->friend list. Remove "[Connected]" to location names. Takes room and isn't useful since the text is in bold
when connected. Also put the avatar column first. Remove the "Busy" and "Idle" text since they are shown as icon already and
set them as tooltip => lots of saved space.
0033 [ ] Selecting different options in messages composer -> contact list then come back, shows disappearing / re-appearing people.
What causes this???
0034 [X] Show forum/channel/posted admin name in details window
**Not sure**
0021 [ ] too many option tabs. may be some must be hidden when advanced mode is not selected
some may be grouped, like styles -for messages, chats and forums appearance must be somewhere on top, in general (from noname)
comment: hiding stuff makes it even more complicated. before we hide it we can remove it
cyril: we could group them somehow.
0022 [ ] some time ago we had separate chat window for messaging (in 0.5.5 it still exists). may be it must be resurrected. (from noname)
// UNSORTED
//
// 23 [too hard for v0.6] chats are missing quote feature, any text formatting.
// picture attachment is ajoke, with the size limits given.
// need ability to save picture attaches in forums and chats
// (from noname)
//
// 24 [do nothing] people tab - is not much useful, may be hide it somewhere from main window. like options-node-my idents.
// (from noname)
// comment: we don't have somethign better, live with it
//
// 25 [low priority] network - peer filter - not showing locations, not useful because many options are location specific.
// (from noname)
// comment: not sure what correct behaviour would be
//
// 26 [low priority] friend file browser - need options to hide offline peers, hide empy shares
// size column should count contents for directories
// (from noname)
// comment: will people complain about missing peers?
//
// 27 [] notify for channels and forums - need option to show only new forums, not for every post in them.
// some might not like flooding there, and it is not a big problem to go to needed tab when it becomes red.
// (from noname)
// long post from noname. Many things go to deep and are out of scope for v0.6
//
// compaction the line below the buttonbar is useless, it just duplicates the
// button. except the mail tab, there is some buttons and they need to be
// relocated the help icon on each tab can be placed in window title or
// somwhere else
//
// IM window - the whole bar with name and a/v buttons is excess. name is on
// the window title, and in the chat. buttons must be on the lower panel with
// the others. 3x set... and dock buttons also must be relocated and the
// panel removed. away/offline informer bar must be more compact and nice
//
// modularity some peopl may not use specific rs features like forums or chats
// or mail. create the ability to hide the tabs from interface and disable the
// network services for them in an ultimate configuration people for example
// may want only chats, so the compact interface with only peer list is good
// for them, skype-like.
------------------------------------------ GENERAL BACKEND STUFF ----------------------------------------------------
Posted:
E [X] it's not possible to create a Posted thread without a Owner.
Bug? If not, then remove "No signature" from selection box
E [ ] Show an info page for unsubscribed posted threads (same as forums)
E [X] Links in Posted cannot be clicked.
M [ ] Fix the counting of unread messages in Posted. Now it's wrong.
E [X] Make the GUI of Posted more sexy: more compact items, remove unecessary text, use consistent icons,...
Forums
E [X] it's not possible to create a Forum thread without a Owner.
Bug? If not, then remove "No signature" from selection box
[X] the tooltip over GXS ids should show the avatar on the left side.
[X] fix data race between GXS ID default icons
[X] Share of key shows "Not implemented". Since forums are public, share key should be hidden.
[X] switching between forums might cause a crash. Seems to be due to GxsIdDetails::instance not always initialised when used.
GUI General
E [ ] do we keep "Getting Started" ? the look needs to be improved. Any help doing this is welcome!
E [X] Recommendation messages do not show complete links. Links show up in some buttons and the text is truncated
E [X] Recommendation messages should not be signed by the retroshare team!!
E [X] when adding a friend through clicking on cert links, the add friend wizard is shown twice!
M [X] add a flag in friends option to allow auto-download of recommended files
M [ ] sound is not working for some users on linux. We also need a "test sound" button in config->sound.
E [ ] some widgets in the GUI do not follow the system style => GUI looks bad on these systems
[X] display version ID in windows version
E [X] recommended friends messages have embedded buttons of wrong size. Use RSLinks instead!
E [X] "Friends details" should show both PGP key and RS certs in different tabs with appropriate names.
It should specify clearly which one should be used to make friends.
E [X] addFriend does not work when the cert contains signatures.
E [X] PGP signatures are not transmited by discovery2.
[X] Default appearance style on Ubuntu should be GTK (to allow correct tooltips)
[X] Default layout should use toolbars. The "menu" look is inneficient
[X] replace sound tooltip "sound off" by "sound is on, click to turn off"
[X] rtt statistic is duplicated in statistics provided by VOIP, so remove it from file transfers
[ ] add tooltips in in permission matrix when hovering over the top most button/service name
E [X] add a "Contact" list to help selecting peers in People/FriendChooser/messages/etc.
E [ ] Implement creation of a default (signed) gxs id in startup wizard. Needs to show to the
user a proper separation between nodes (network layer) and GXS ids (service layer).
E [ ] fix posted GUI. Needs to be more handy and more appealing.
E [ ] add RS links for GXS identities, so that they can be transferred easily between nodes in forums, etc
E [ ] enable people dialog
M [ ] Personal Page (Profile Page for GXS ID Users,view latest Posts, public forum/channels,posted posts, comments in all areas, Reputation Infos, Popularity and more)
E [ ] fix RSButtonOnText::eventFilter, and fix all places where RSButtonOnText gets deleted
E [ ] find all places where the deprecated(in Qt5) Q_WS_WIN and other Q_WS* macros are
used, and replace with something else
E [ ] add tooltips in in permission matrix when hovering over the top most button/service name
explain what the service does and the dependencies
E [ ] Make RS fully compatible with High DPI screens.
M [ ] improve comments in channels. Comments should be more available, more visible, and easier to handle.
M [ ] Merge the various help systems. there's 3 of them now. Lots of duplicate code, etc.
M [ ] New and consistent icon set (Purplehaze420 said he would provide a consistent set of icons. Is that still alive?)
M [ ] add in options->Network a way to select which network interface is used to talk (choice between "auto" or selected from a list)
M [ ] add a RS link for encrypted messages (encrypt for multiple GXS ids at once). Messages will appear as a link when encrypted and
be automatically decrypted when a suitable GXS id is available for it. Could be a way to securely post something in a public place.
Messages
H [X] distant messages should be made async-ed
* [ ] increase sigma of activity events to allow a more generous routing matrix
* [ ] collect routing events from chat lobbies? (maybe not a good idea)
M [X] distant messages are not re-sent when the peer is offline the first time
M [X] sent messages to direct peers in the Sent box have inconsistent To field.
Raises an error if you click on it.
M [X] icons for GxsTreeWidgetItem are too small in distant messages list widget
E [X] "from" should be disabled until we actually use a GXS id in the destination list.
E [X] "show all" and "show everyone" in destination list are duplicate names for different things.
Either remove one of them, or use appropriate names.
File transfer (all 3 tasks are related)
E [ ] Add a limit of the total number of files simultaneously asked to the same peer using direct transfer.
H [ ] implement a new file list management, with new info such as access time,total upload, popularity, etc
H [ ] implement a new file list sharing service based on auto-sync system
M [ ] get rid of the old cache system (remove CacheStrapper, CacheSource,etc)
Channels
[X] Unsubscribed channels should show an info page when selected, like forums
H [X] marking all as read in channels takes time. The channel icon should show a waiting clock
during the operation to avoid the user to re-click many times in the hope to get the posts marked as read.
[X] channels items show a 0 left to the up/Dn buttons. What is it??
[X] allow to post on channels when attachment is not in shared files. Just display a warning.
M [X] popularity calculation seems wrong. To reproduce: create a new channel and subscribe to it from
another location with many friends => popularity is too big at that location (should be 1)
the problem seems to be in RsGxsNetService::handleRecvSyncMessage
peers send RsNxsSyncMsg for unsubscribed groups (they are not suppliers then)
nor sure what role RsGxsNetService::loadList plays here
[X] show group owner in channel/forum/posted's details tab
DHT
H [ ] improve DHT lookups to find masquerading peers using fake peers. First experiments (by cyril) do not prove very efficient.
Chat lobbies
H [X] Chat lobbies should use Identities. That's a significant change, probably not backward compatible.
[X] Remove deprecated code in rschatitems.
[X] remove "change nickname" from drop menu
[X] there's no way to remove auto-subscribe when connected to a lobby. Show auto-subscribe status in tooltip, add menu entries.
GXS
M [X] create a tunnel service from distant chat code to make it (1) more generic (2) resistant to packet loss.
M [X] optimise GXS sync BW. For the moment too much is sent between nodes.
H [/] add the ability to use anonymous identities into circles. Needs new distribution model using items encrypted for multiple GXS keys.
H [ ] use different and incompatible classes for public and private keys in GxsSecurity
Profile creation wizard
[X] "Hidden node" should be an option at start. Apparently it becomes mandatory when one sets the advanced mode.
[X] the blue button "Generate new node" does not have a clear state. It should be grey while disabled, then
not grey. Or maybe use an icon?
VOIP
H [ ] use proper video encoding. What we have now is decent for video, but sound should be prioritized. Experiments
with QtAV seem to work nicely. Finish and integrate!
M [ ] Video Quality/Resolution Settings (High, Medium, Low) HD, HQ, SD )
M [ ] Video Device: WebCam(s) or Desktop Selection
M [ ] Audio Input Device Selection (Microphone)
M [ ] Audio Output Device Selection (Speaker)
M [ ] Video Snapshots https://support.skype.com/en/faq/FA1222/what-is-video-snapshot
M [ ] Voice Messaging (record and send a voice message)
M [ ] Video Messages (send a video greeting to multiple friends/coworkers/developers at once.)
H [ ] Audio Conference
H [ ] Video Conference
Settings
[X] remove HiddenNode fom config->server netWork mode drop menu, or disable it in non hidden mode.
[X] Default max upload should be a large number. Not 50KB/s!!
Settings > Sounds -> enable default sounds for
[ ] Friend go online
[ ] New Chat Message
[ ] Message arrived
[ ] Download complete
Messages
H [ ] make the mail system re-send failed emails notified by the global router. This is hard because it needs a proper
management of duplicate messages
E [X] add flags to allow distant messaging from contact list only / everyone / noone / only signed ids.
Chat
[X] Distant chat window should show GXS avatars
H [ ] Distant chat should work with shared identities
[X] Distant chat fails (tunnel bullet never gets green) when re-openning a distant chat window after closing a tunnel
[X] Distant chat fails (chat window never appears) when re-openning a distant chat window after closing a tunnel
[X] You should not be enabled to distant-chat yourself!
[X] Nickname completion is broken. It only works with @
Chat
E [X] add flags to allow distant chat from contact list only / everyone / noone / only signed ids.
Identities:
[X] "Owned by you" => "Owned by node [nodename]"
[X] Bold face should only be used for keys with admin credentials
E [X] reputations are not used yet. We should hide them.
H [X] Add timeout to Identities that are unused. Need to keep a time stamp list, updated whenever the identity is used for checking signatures.
[X] Fix avatar loading for identities. When loaded for the first time by forums, the avatar does not show up.
M [ ] allow to share identities between locations.
Network
E [X] Friends => Friend nodes
E [X] remove TCP, TOR, UDP from the status column, and move it in front of IP
File transfer
H [X] There's a bug sometimes causing re-hash of shared files at start. Find it, kill it.
[ ] Bug: when sorting files in friends file list, RS goes into a crazy loop and crashes
News feed
[X] remove the Ghost news feed items
[X] remove the double feed publication
libretroshare
[ ] make sure at least one location is kept when removing old locations as it avoids lots of connection problems.
[ ] some users can be declared as connected although they are not. Check Heart-Beat system.
H [X] fix the data race in pqissl
H [ ] valgrind pass for data races
H [ ] valgrind pass for memory leaks
H [ ] valgrind pass for memory errors
H [ ] valgrind pass for performance
E [-] remove mktemp => use mkstemp
note: mkstemp is not available on Windows
H [ ] RsGxsDataAccess::processRequests locks mDataMutex until all requests are processed.
Adding a new request or poll for the request status are freezing until the mutex is available.
[ ] crash at shutdown
Libretroshare
E [X] groups small packets in pqistreamer::handleoutgoing_locked(), and see if that removes some padding overhead
E [ ] make sure at least one location is kept when removing old locations as it avoids lots of connection problems.
M [ ] improve serialisation system. Lots of serialisation tasks (header, verifications, serialiser=>template, can be factored)
M [ ] separate chat stuff from rsmsgs.h into rschat.h
M [ ] crash at shutdown due to memory management already cleared while new objects keep being requested.
#0 0x0000000000da52eb in RsMemoryManagement:¿mallObject:¿mallObject() ()
#1 0x0000000000da3694 in RsItem::RsItem(unsigned int) ()
#2 0x0000000000dcb365 in RsRawItem::RsRawItem (this=0x0, t=33559555, size=38) at ./serialiser/rsserial.h:182
#2 0x0000000000dcb365 in RsRawItem::RsRawItem (this=0x0, t=33559555, size=38) at ./serialiser/rsserial.h
#3 0x0000000000fc1643 in RsServiceSerialiser::deserialise(void*, unsigned int*) ()
#4 0x0000000000da4451 in RsSerialiser::deserialise(void*, unsigned int*) ()
#5 0x0000000000fb5b4b in pqistreamer::handleincoming_locked() ()
@ -306,40 +90,38 @@ H [ ] RsGxsDataAccess::processRequests locks mDataMutex until all request
#10 0x00007ffff4006f6b in start_thread () from /lib64/libpthread.so.0
#11 0x00007ffff351c7ed in clone () from /lib64/libc.so.6
Packaging
[X] check compilation on debian
[X] check compilation on ARM
[ ] Sound files should be part of the install package at least on ubuntu (put them in /usr/share)
Channels
E [ ] allow to set a download directory per channel
M [ ] Thumbnail View for Channels
M [ ] Count commments on Comments Button
M [ ] Notify Channel comments/replies
Post v0.6 release changes
=========================
Posted
E [ ] Show an info page for unsubscribed posted threads (same as forums)
E [ ] Make the GUI of Posted more sexy: more compact items, remove unecessary text, use consistent icons,...
File transfer
H [ ] implement a new file list management, with new info such as access time, total upload, popularity, etc
H [ ] implement a new file list sharing service based on auto-sync system
H [ ] get rid of the old cache system (remove CacheStrapper, CacheSource,etc)
Forums
E [ ] do we keep "Getting Started" ? the look needs to be improved. Any help doing this is welcome!
E [ ] some widgets in the GUI do not follow the system style => GUI looks bad on these systems
GUI
H [ ] enable circles for channels/posted/forums
E [ ] enable people dialog
E [ ] fix RSButtonOnText::eventFilter, and fix all places where RSButtonOnText gets deleted
E [ ] find all places where the deprecated(in Qt5) Q_WS_WIN and other Q_WS* macros are used, and replace with something else
Bugs
E [ ] find the bug that shows some peers online in Network although they are not.
M [X] Selecting different options in messages composer -> contact list then come back,
shows disappearing / re-appearing people. What causes this???
GXS
H [ ] add the ability to use anonymous identities into circles. Needs new distribution model using items encrypted for multiple GXS keys.
H [ ] use different and incompatible classes for public and private keys in GxsSecurity
Sounds
E [ ] add default sounds for Friend go online, New Chat Message, Message arrived, Download complete
M [ ] make sure sound is working for users on linux. We also need a "test sound" button in config->sound.
Libretroshare
M [ ] improve serialisation system. Lots of serialisation tasks (header, verifications, serialiser=>template, can be factored)
M [ ] separate chat stuff from rsmsgs.h into rschat.h
Packaging
E [ ] Sound files should be part of the install package at least on ubuntu (put them in /usr/share)
Chat
H [ ] add "chat with this peer" from lobbies to start a private distant conversation with the GXS id of the peer
List of pending non backward compatible changes
===============================================
Msgs
H [ ] Merge the new messaging format
Channels
M [ ] allow to set a download directory per channel
* RsGxsGrpMetaData::deserialis should use a proper TLV_STR_TYPE_NAME instead of 0 for
mGroupName and mMsgName, in rsgxsdata.cc
* p3IdService::service_CreateGroup() should convert the mPgpSign member to radix64!! For now
it is hard-coded in binary in a string.

View file

@ -0,0 +1,89 @@
#############################
###--- QT INSTALLATION ---###
#############################
###Install Qt via:
http://www.qt.io/download/
###Use default options.
###Add to the PATH environment variable.
;C:\Qt\5.5\mingw492_32\bin;C:\Qt\Tools\mingw492_32\bin;C:\Qt\Tools\mingw492_32\opt\bin
###Depends on wich version of Qt you use.
###Change build-all-mingw32make.bat with these values too if you don't use MSys2.
###############################
###---MSYS2 INSTALLATION ---###
###############################
###Choose your MSYS2 installer here:
http://msys2.github.io/
###Follow install procedure.
###Don't forget to sync & Update pacman.
pacman --needed -Sy bash pacman pacman-mirrors msys2-runtime
###Restart console
pacman -Su
###Install all default programms
pacman -S base-devel git mercurial cvs wget p7zip gcc perl ruby python2
###Choose only w64-i686 if you want only compilation in 32b architecture.
pacman -S mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain
###Install other binutils:
pacman -S mingw-w64-i686-miniupnpc mingw-w64-x86_64-miniupnpc
pacman -S mingw-w64-i686-sqlite3 mingw-w64-x86_64-sqlite3
pacman -S mingw-w64-i686-speex mingw-w64-x86_64-speex
pacman -S mingw-w64-i686-opencv mingw-w64-x86_64-opencv
pacman -S mingw-w64-i686-ffmpeg mingw-w64-x86_64-ffmpeg
pacman -S mingw-w64-i686-libmicrohttpd mingw-w64-x86_64-libmicrohttpd
pacman -S mingw-w64-i686-libxslt mingw-w64-x86_64-libxslt
### Add MSYS2 to PATH environment variable depends your windows
;C:\msys64\mingw32\bin
;C:\msys32\mingw32\bin
##############################
###--- GIT INSTALLATION ---###
##############################
###Install Git Gui or other client:
https://git-scm.com/download/win
###Create a new directory named:
C:\Development\GIT
###Right-click on it and choose:
Git Bash Here
###Paste this text on git console:
git clone https://github.com/RetroShare/RetroShare.git
###########################
###--- LAST SETTINGS ---###
###########################
###In QtCreator Option Git add its path:
C:\Program Files\Git\bin
### and select "Pull" with "Rebase"
###Open an MSys2 32|64 shell
###Move to build_scripts:
cd /c/Development/GIT/RetroShare/msys2_build_libs/
###Compil missing library
make
###You can now compile RS into Qt Creator
###For using, and debugging Plugins, you can use SymLinker (http://amd989.github.io/Symlinker/) to link
### the files in \build-RetroShare-Desktop_Qt_X_Y_Z_MinGW_32bit-Debug\plugins\PluginName\debug\*.dll
### to %appdata%\RetroShare\extensions6

131
build-all-mingw32make.bat Normal file → Executable file
View file

@ -1,14 +1,14 @@
set QTDIR=C:\Qt\4.8.6
set MINGW=C:\MinGW
set GIT=C:\Program Files\Git
set PATH=%QTDIR%\bin;%MINGW%\bin;%GIT%\bin;%PATH%
set QTDIR=C:\Qt\5.5\mingw492_32\
set MINGW=C:\Qt\Tools\mingw492_32
set PATH=%QTDIR%\bin;%MINGW%\bin;%PATH%
set DEBUG=1
@echo off
rem emptying used variables in case the script was aborted and tempfile
set pack=
set clean=
set errorlevel=
if exist tmp.txt del tmp.txt
@ -44,77 +44,174 @@ if not exist tmp.txt (
)
for /f %%a in (tmp.txt) do (
@echo on
if ECHO==1 @echo on
rem TODO: Remove these lines
rem GOTO :retroshare-gui
:libbitdht
rem ###################################
rem ### libbitdht #####################
rem ###################################
cd libbitdht\src
if not %clean%x==x mingw32-make clean
qmake libbitdht.pro
CALL :TEST_ERROR
mingw32-make %%a
CALL :TEST_ERROR
echo ###################################
echo ### libbitdht done ################
echo ###################################
cd ..\..
cd ..\..\openpgpsdk\src
:openpgpsdk
rem ###################################
rem ### openpgpsdk ####################
rem ###################################
cd openpgpsdk\src
if not %clean%x==x mingw32-make clean
qmake openpgpsdk.pro
CALL :TEST_ERROR
mingw32-make
CALL :TEST_ERROR
echo ###################################
echo ### openpgpsdk done ###############
echo ###################################
cd ..\..
cd ..\..\libresapi\src
:libresapi
rem ###################################
rem ### libresapi #####################
rem ###################################
cd libresapi\src
if not %clean%x==x mingw32-make clean
qmake libresapi.pro
CALL :TEST_ERROR
mingw32-make %%a
CALL :TEST_ERROR
echo ###################################
echo ### libresapi done ################
echo ###################################
cd ..\..
cd ..\..\libretroshare\src
:libretroshare
rem ###################################
rem ### libretroshare #################
rem ###################################
cd libretroshare\src
if not %clean%x==x mingw32-make clean
qmake libretroshare.pro "CONFIG+=version_detail_bash_script"
CALL :TEST_ERROR
mingw32-make %%a
CALL :TEST_ERROR
echo ###################################
echo ### libretroshare done ############
echo ###################################
cd ..\..
cd ..\..\supportlibs\pegmarkdown
:pegmarkdown
rem ###################################
rem ### pegmarkdown ###################
rem ###################################
cd supportlibs\pegmarkdown
if not %clean%x==x mingw32-make clean
qmake pegmarkdown.pro
CALL :TEST_ERROR
mingw32-make %%a
CALL :TEST_ERROR
echo ###################################
echo ### pegmarkdown done ##############
echo ###################################
cd ..\..
cd ..\..\retroshare-nogui\src
:retroshare-nogui
rem ###################################
rem ### retroshare-nogui ##############
rem ###################################
cd retroshare-nogui\src
if not %clean%x==x mingw32-make clean
qmake retroshare-nogui.pro
CALL :TEST_ERROR
mingw32-make %%a
CALL :TEST_ERROR
echo ###################################
echo ### retroshare-nogui done #########
echo ###################################
cd ..\..
cd ..\..\retroshare-gui\src
:retroshare-gui
rem ###################################
rem ### retroshare-gui ################
rem ###################################
cd retroshare-gui\src
if not %clean%x==x mingw32-make clean
rem qmake -r -spec ..\mkspecs\win32-g++ "CONFIG+=version_detail_bash_script" retroshare-gui.pro
qmake retroshare-gui.pro "CONFIG+=version_detail_bash_script"
CALL :TEST_ERROR
mingw32-make %%a
CALL :TEST_ERROR
echo ###################################
echo ### retroshare-gui done ###########
echo ###################################
cd ..\..
@echo off
)
@echo off
if %pack%x==packx call packaging.bat
rem clean up
rem ###################################
rem ### clean up ######################
rem ###################################
set clean=
del tmp.txt
set pack=
pause
rem ###################################
rem ### END ###########################
rem ###################################
GOTO :EOF
:TEST_ERROR
@echo off
if errorlevel 1 (
pause
set clean=
del tmp.txt
set pack=
EXIT
)
if ECHO==1 @echo on
EXIT /B
:EOF

View file

@ -1,5 +1,534 @@
retroshare06 (0.6.0-1.XXXXXX~YYYYYY) YYYYYY; urgency=low
a6ee7cc csoler Thu, 31 Dec 2015 14:15:14 -0500 Merge pull request #230 from G10h4ck/ss_port_invalid_family
fac1524 csoler Thu, 31 Dec 2015 13:58:13 -0500 updated todo list
c5feafa Gio Thu, 31 Dec 2015 19:56:50 +0100 Add missing stacktrace.h
1303d85 Gio Thu, 31 Dec 2015 19:32:46 +0100 more cleanups + sanitize p3Peers::getPeerDetails avoid to look for port on null sockaddr_storage
37a3c46 defnax Thu, 31 Dec 2015 16:40:06 +0100 Fixing Margins
ed7f958 Gio Thu, 31 Dec 2015 15:42:22 +0100 Add stacktrave.h, sanitize p3LinkMgrIMPL::retryConnectTCP avoid to look for port on null sockaddr_stor
69f6bd0 electron128 Thu, 31 Dec 2015 14:02:51 +0100 insert the newest channel posts first and the oldest last (modified patch from Eugene Tooms)
8a41554 csoler Wed, 30 Dec 2015 18:20:09 -0500 fixed some leaking memory issues in loadList() methods, and also increased consistency by not retur
48750cd csoler Wed, 30 Dec 2015 17:18:22 -0500 merged
ae16fc8 csoler Wed, 30 Dec 2015 17:13:27 -0500 Merge pull request #229 from G10h4ck/master
9c24203 Gio Wed, 30 Dec 2015 22:47:51 +0100 Fix memory leak in getLocalAddresses
cefa5d9 csoler Wed, 30 Dec 2015 13:55:15 -0500 fixed missing SSL_free when a new connection replaces the existing one
aabfcb9 csoler Wed, 30 Dec 2015 13:51:56 -0500 fixed missign initialisation of err in pqissludp.cc
d1bc892 csoler Wed, 30 Dec 2015 13:44:18 -0500 Merge pull request #228 from csoler/v0.6-GxsDebug
0299691 csoler Wed, 30 Dec 2015 11:14:10 -0500 removed overkill test that would cause sending updates to peers when no messages are available (thx
f8be606 csoler Wed, 30 Dec 2015 10:03:32 -0500 Merge pull request #227 from PhenomRetroShare/Fix_DefaultGxsId
894328b Phenom Wed, 30 Dec 2015 15:43:47 +0100 Fix default Identity on Chat
6829309 csoler Tue, 29 Dec 2015 23:40:09 -0500 merged PR 219 from Jolavilette+Phenom, with some minor modifications
2fe646c csoler Tue, 29 Dec 2015 23:39:52 -0500 merged PR 219 from Jolavilette+Phenom, with some minor modifications
7486d54 csoler Tue, 29 Dec 2015 17:59:31 -0500 Merge pull request #226 from G10h4ck/master
3cfa22e Gio Tue, 29 Dec 2015 23:51:16 +0100 Guard checkNetAddress debug, unary + comment clarification
9e0dc01 csoler Tue, 29 Dec 2015 17:31:35 -0500 changed the reset of client map into a reset f server map when subscribing a group
2d438b7 csoler Tue, 29 Dec 2015 16:39:15 -0500 Merge pull request #162 from G10h4ck/getLocalAddresses
eab4253 csoler Mon, 28 Dec 2015 18:15:51 -0500 Merge pull request #224 from PhenomRetroShare/Fix_GenCertDialogMaskingPGPKeyPassword
312cea7 defnax Mon, 28 Dec 2015 16:42:42 +0100 Fixed double selection bug on Windows Vista style
4521e8e Phenom Wed, 23 Dec 2015 15:49:05 +0100 Fix pqihandler::UpdateRates() to get more accurate.
c1b8850 Phenom Mon, 28 Dec 2015 13:45:22 +0100 Fix GenCertDialog masking PGP Key password dialog at end.
00517fe csoler Sun, 27 Dec 2015 22:22:51 -0500 Merge pull request #223 from csoler/v0.6-ContactList
71b3638 csoler Sun, 27 Dec 2015 22:19:30 -0500 removed some debug output in distant chat
a80a666 csoler Sun, 27 Dec 2015 22:16:04 -0500 added notifiction of denying conversation for distant chat
9dfac71 csoler Sun, 27 Dec 2015 21:10:20 -0500 connected GUI to distant chat permission flags system
d287a62 defnax Mon, 28 Dec 2015 00:39:58 +0100 Merge pull request #221 from PhenomRetroShare/Fix_MacOSX.X_Plugin_Compilation
b32eb6e csoler Sun, 27 Dec 2015 17:00:54 -0500 added temporal filtering to RSGraphWidget to clear up the display. Auto-changes with scale. Can be
a63482d defnax Sun, 27 Dec 2015 19:14:20 +0100 Expand All/Contacts items by default & store/load expand settings.
672ab25 csoler Sun, 27 Dec 2015 10:03:07 -0500 added safeguard against absurdly large packets in rsserial.cc and output of the beginning of the pa
ddec6b1 Phenom Sat, 26 Dec 2015 17:20:45 +0100 Update MacOS_X_InstallGuide.txt
cb4579e Phenom Thu, 24 Dec 2015 18:54:45 +0100 Fix compilation for plugins but miss RetroShare-gui library linking.
3ea2e0f defnax Sat, 26 Dec 2015 16:14:28 +0100 Merge pull request #222 from PhenomRetroShare/Fix_ColoredFontInChat
162b5fa Phenom Sat, 26 Dec 2015 15:57:46 +0100 Fix colored font in chat.
1402051 csoler Fri, 25 Dec 2015 22:37:06 -0500 added backend for distant message and distant chat filtering based on contact list
f5c2aa3 defnax Fri, 25 Dec 2015 17:23:15 +0100 update emotes
7afcc2a defnax Thu, 24 Dec 2015 17:46:02 +0100 Enabled back counting People Enabled "Sort by Posts" for Channels/Forums/Posted Fixed Width/Height
12c9194 defnax Thu, 24 Dec 2015 14:31:52 +0100 Added Send Invite Button to People Dialog.
e3f496f electron128 Thu, 24 Dec 2015 13:21:40 +0100 fixed bug from contact list branch. Identity flags (pgp-linked, contact) where resettet so sig
f30f71d csoler Wed, 23 Dec 2015 18:07:10 -0500 Merge pull request #218 from csoler/v0.6-ContactList
73f58c7 csoler Wed, 23 Dec 2015 13:48:56 -0500 improved layout and namign in MessageComposer
4c50641 csoler Wed, 23 Dec 2015 12:12:34 -0500 cosmetic change in IdDialog
52da8cd csoler Wed, 23 Dec 2015 12:08:20 -0500 fixed display of contactlist when changing status, and improved computaitonal efficiency
0183919 csoler Wed, 23 Dec 2015 11:20:10 -0500 merged before commit
98b27d6 csoler Wed, 23 Dec 2015 11:18:26 -0500 moved notify calls to RsGenExchange out of RsGxsNetService lock zone, to avoid deadlocks
15a7487 defnax Wed, 23 Dec 2015 16:55:23 +0100 Save sorting on Chat lobby
226948c defnax Wed, 23 Dec 2015 14:08:28 +0100 Merge pull request #217 from PhenomRetroShare/Fix_CompilationWhenNXS_NET_DEBUG_0
b1ce2fa defnax Wed, 23 Dec 2015 14:08:01 +0100 Merge pull request #214 from PhenomRetroShare/Fix_MacOSX.X_Compilation
1346259 Phenom Wed, 23 Dec 2015 13:45:39 +0100 Miss recomment NXS_NET_DEBUG_0...
4aea100 Phenom Wed, 23 Dec 2015 13:40:01 +0100 From jolavillette-morkitu: in rsgxsnetservice.cc when #define NXS_NET_DEBUG_0 is set to 1 the compi
5d92720 csoler Tue, 22 Dec 2015 18:33:01 -0500 merged with upstream/master
ab763c7 csoler Tue, 22 Dec 2015 18:29:27 -0500 converted file to unix mode
b7cba22 csoler Tue, 22 Dec 2015 17:43:37 -0500 updated ubuntu changelog
95d8647 defnax Tue, 22 Dec 2015 19:57:26 +0100 Optimized the emoticon selector box size based on how many emoticons are loaded (by anmo), update e
86b5591 Phenom Mon, 21 Dec 2015 17:25:02 +0100 Fix MacOSX 10.10 Yosemite Compilation
334b414 defnax Tue, 22 Dec 2015 17:24:12 +0100 cleaning up resource file for emojione, removed old smileys
8e9fe6d defnax Tue, 22 Dec 2015 01:07:02 +0100 Merge pull request #189 from hunbernd/feature/chat-enhancements
4ccab41 defnax Mon, 21 Dec 2015 22:27:10 +0100 Added new Emojione Emoticons
-- Cyril Soler <csoler@users.sourceforge.net> Thu, 31 Dec 2015 14:00:00 +0100
retroshare06 (0.6.0-1.20151222.4bf2464a~trusty) trusty; urgency=low
436f619 Gio Mon, 21 Dec 2015 17:34:53 +0100 getLocalAddresses collects loopback address too
9d78bba Gio Mon, 21 Dec 2015 15:48:18 +0100 Guard getLocalAddresses debug
9826c72 Gio Tue, 15 Dec 2015 16:37:27 +0100 added rs_inet_ntop crossplatform version of inet_ntop
ca1a970 Gio Fri, 11 Dec 2015 11:44:26 +0100 Removed dead code
1b2fa36 Gio Tue, 1 Dec 2015 23:38:44 +0100 Adapted getLocalAddresses() includes for windows
5a541e7 Gio Mon, 26 Oct 2015 13:12:21 +0100 Removed unused getLocalInterfaces_ipv4
77bcc99 Gio Mon, 26 Oct 2015 12:38:08 +0100 Added sockaddr_storage_dump(...), implemented sockaddr_storage_ipv6_iptostring(...)
747a03a Gioacchino Mazzurco Mon, 9 Mar 2015 20:00:41 +0100 Substitute getpreferredinterface flawed logic with simpler getLocalAddresses still just one address used at moment
f12b4a1 csoler Sun, 20 Dec 2015 20:53:11 -0500 Merge pull request #213 from csoler/v0.6-GxsDebug
d4926cb csoler Sun, 20 Dec 2015 20:35:48 -0500 fixed a number of memory leaks in gxsnetservice. Used a class that auto-deletes retrieved items.
ea137ad csoler Sun, 20 Dec 2015 19:07:04 -0500 fixed compilation on OSX pb in pqistreamer
d50875b csoler Sat, 19 Dec 2015 21:38:55 -0500 Merge pull request #212 from csoler/v0.6-TrafficOptim
141b799 csoler Sat, 19 Dec 2015 21:20:25 -0500 removed debug info
124da6f csoler Sat, 19 Dec 2015 21:12:57 -0500 Merge pull request #210 from G10h4ck/pqicleaning
d2e62b9 csoler Sat, 19 Dec 2015 19:18:53 -0500 Merge pull request #211 from csoler/v0.6-GxsDebug
462f969 csoler Sat, 19 Dec 2015 19:15:48 -0500 merged with upstream/master
ccc5f0f csoler Sat, 19 Dec 2015 19:04:49 -0500 improved debug info in rsgxsnetservice
5fcaa36 csoler Sat, 19 Dec 2015 19:00:06 -0500 fixed some serialising bugs, and added proper notification of observer
6910ad3 csoler Sat, 19 Dec 2015 17:38:52 -0500 added stats exchange system to gather number of posts in unsubscribed groups without the need to actually DL the messages (reduced bw a lot)
b2c27a1 Gio Sat, 19 Dec 2015 22:10:07 +0100 Made pqiperson more readable evidence some strange code
adfa94d electron128 Fri, 18 Dec 2015 19:05:18 +0100 added missing null check libresapi ApiPluginHandler
b1b75a3 csoler Fri, 18 Dec 2015 08:07:00 -0500 fixed stupid bug causing cleanRejectedMessages() to be called continuously
374aa65 csoler Thu, 17 Dec 2015 23:10:02 -0500 Merge pull request #209 from csoler/v0.6-GxsDebug
e8b881b csoler Thu, 17 Dec 2015 23:08:02 -0500 added rejection list to gxsnetservice that is fed by calls from GenExchange system, to avoid infinitely re-downloading rejected messages due to bad reputation, bad signatures, missing ids, etc
03896d7 defnax Fri, 18 Dec 2015 01:40:39 +0100 Added Sorting Menu entry.
5b63762 electron128 Thu, 17 Dec 2015 18:59:30 +0100 removed useless code which caused lots of ChatId conversation warnings
45fb453 csoler Thu, 17 Dec 2015 09:23:16 -0500 Merge pull request #208 from csoler/v0.6-GxsDebug
55e66d0 csoler Thu, 17 Dec 2015 00:08:08 -0500 fixed mismatch between API versions causing signed groups created with old API to fail author signature checking
dc034fe csoler Tue, 15 Dec 2015 23:17:35 -0500 removed debug info from GxsNetService
0c4fd8e csoler Tue, 15 Dec 2015 18:13:40 -0500 added missing time-stamping of keys
3617f9c csoler Tue, 15 Dec 2015 18:09:49 -0500 added NXS_NET_DEBUG_5 to print summary of incoming items
92780b7 csoler Tue, 15 Dec 2015 18:01:03 -0500 added auto-request of missing GXS ids for group posts authors and group authors
42bf996 defnax Tue, 15 Dec 2015 20:20:11 +0100 Sort lobby Parcipants by activity Set spacing between items
f7ab3ad electron128 Tue, 15 Dec 2015 19:56:49 +0100 allow plugins to integrate into the JSON API
8d886b8 csoler Tue, 15 Dec 2015 12:31:03 -0500 added regular timestamp-ing of GXS ids of group authors and group post authors for all subscribed groups
3f132f2 csoler Mon, 14 Dec 2015 21:13:44 -0500 added missing timestamp at message creation time and group creation time
e824a2f defnax Mon, 14 Dec 2015 16:32:00 +0100 update file extensions, patch by Agurer
f702c94 csoler Sun, 13 Dec 2015 18:22:04 -0500 added a few methods to improve consistency between client and server sides, and force update of groups in some cases (such as database erased)
96c2872 defnax Sun, 13 Dec 2015 18:20:56 +0100 Merge pull request #203 from realityfabric/master
e003f56 realityfabric Sun, 13 Dec 2015 08:27:32 -0800 Made it so that sys/select.h is only included if the operating system is not Windows
82d43eb csoler Sat, 12 Dec 2015 23:07:33 -0500 fixed a few bugs in packet packing in pqistreamer.
ed7a261 csoler Sat, 12 Dec 2015 21:07:48 -0500 added check for NULL client update map in rsgxsnetservice::debugDump()
ad1aafe csoler Sat, 12 Dec 2015 14:05:45 -0500 added missing mutex
f6a84aa csoler Sat, 12 Dec 2015 11:52:48 -0500 added packet packing in pqistreamer. To be tested for improvement in bw
534be72 csoler Fri, 11 Dec 2015 22:54:45 -0500 improved debug info in rsgxsnetservice.cc
7be7233 csoler Fri, 11 Dec 2015 22:38:17 -0500 fixed a number of timing issues in rsgxsnetservice. To be tested.
66d6f05 csoler Fri, 11 Dec 2015 19:01:20 -0500 added debugDump() method to display update timestamps of GXS groups on both sides
16d815f csoler Fri, 11 Dec 2015 18:03:44 -0500 added protocol documentation in rsgxsnetservice.cc
039db26 csoler Thu, 10 Dec 2015 22:25:09 -0500 improved debug info in rsgxsnetservice.cc
c9af8e3 csoler Thu, 10 Dec 2015 22:08:28 -0500 improved debug info in rsgxsnetservice.cc
3cb3662 csoler Thu, 10 Dec 2015 21:54:48 -0500 improved debug info in rsgxsnetservice.cc
4f41605 csoler Thu, 10 Dec 2015 14:02:11 -0500 updated TODO list
9db0524 csoler Thu, 10 Dec 2015 00:10:51 -0500 merged with upstream/master
9843c1f csoler Thu, 10 Dec 2015 00:03:01 -0500 started updating debug info in gxsnetservice
893f178 csoler Mon, 7 Dec 2015 23:09:44 -0500 changed GxsTunnel method for computing turtle hash, to avoid crashing old peers
0957e70 csoler Mon, 7 Dec 2015 22:39:45 -0500 changed the method of computation for tunnel hashes in global router in order to avoid conflict with GxsTunnel service (breaks compatibility of distant message sending)
4724007 defnax Mon, 7 Dec 2015 17:11:25 +0100 Changed Context Menu order issue: #187
e2542a6 csoler Mon, 7 Dec 2015 10:02:04 -0500 added missing check after deserialisation of grouter item which caused a crash when receiving a malformed message data
7cd880e electron128 Sat, 5 Dec 2015 17:00:57 +0100 removed member gxs_id from ChatId class, because ChatId now uses tunnel ids stored in distant_chat_id for distant chat. reverted naming confusion in in libresapi ChatHandler and fixed author of distant chat messages (distant chat is still unfinished)
0ac76d6 csoler Sat, 5 Dec 2015 10:28:16 -0500 Merge pull request #188 from csoler/v0.6-SecuredTunnelService
2a82ef5 csoler Fri, 4 Dec 2015 21:43:35 -0500 Merge pull request #186 from realityfabric/minor_edits
9193d35 csoler Fri, 4 Dec 2015 21:24:51 -0500 merged with latest master before creating PR
dcdf9df csoler Fri, 4 Dec 2015 14:14:13 -0500 merged
88d3e98 csoler Fri, 4 Dec 2015 14:13:46 -0500 updated TODO list
89693b1 csoler Fri, 4 Dec 2015 14:12:35 -0500 updated TODO list
d2a9978 defnax Fri, 4 Dec 2015 19:56:56 +0100 Fixed Qt5 Fusion stylesheet on MessageComposer
d32765c csoler Fri, 4 Dec 2015 10:53:14 -0500 updated TODO list
318be3a csoler Fri, 4 Dec 2015 00:06:14 -0500 fixed a few bugs in distant chat: disabled history (for now), improved tunnel handling
b198f1a csoler Thu, 3 Dec 2015 00:34:13 -0500 fixed some cleaning of remotely closed tunnels in GxsTunnelService
9f56199 realityfabric Wed, 2 Dec 2015 06:18:17 -0800 fixed spelling errors in several files
81b196d csoler Tue, 1 Dec 2015 23:40:35 -0500 added GUI to display authenticated tunnel info. Added counting of data sent/recvd.
60d948b csoler Mon, 30 Nov 2015 21:52:15 -0500 added void GUI for authenticated tunnels
266652f csoler Mon, 30 Nov 2015 21:02:12 -0500 put ifdefs around debug info in tunnel service
12866cd csoler Mon, 30 Nov 2015 20:51:47 -0500 fixed a few bugs in new distant chat
81ab43b csoler Mon, 30 Nov 2015 00:02:44 -0500 fixed GUI update of avatars and status for distant chat. Updated backend for new model. Fixed a few bugs in serialisation
4b38b66 defnax Sun, 29 Nov 2015 17:28:05 +0100 update todo
6951d73 csoler Sat, 28 Nov 2015 18:02:57 -0500 debugging of GxsTunnel service - fixed transport layer
a29f15a csoler Sat, 28 Nov 2015 14:55:56 -0500 fixed compilation, added missing methods for new distant chat
923efda defnax Sat, 28 Nov 2015 18:13:35 +0100 update todo list
6ca49a2 csoler Fri, 27 Nov 2015 23:37:39 -0500 fixed serialisation methods for GxsTunnel service
950f407 csoler Fri, 27 Nov 2015 14:16:57 -0500 updated todo
a2e0f41 csoler Thu, 26 Nov 2015 20:40:06 -0500 updated GUI for new distant chat
874f304 csoler Thu, 26 Nov 2015 14:48:30 -0500 Merge pull request #167 from G10h4ck/pqicleaning
26f4523 csoler Wed, 25 Nov 2015 17:34:13 -0500 fixed compilation
2f31dcf csoler Wed, 25 Nov 2015 09:27:56 -0500 Merge pull request #182 from ericthefish/master
e8173bd Ivan Lucas Wed, 25 Nov 2015 10:33:28 +0000 Improve some of the wording of labels and information
b552408 csoler Tue, 24 Nov 2015 21:57:59 -0500 added service part and item queues to GXS tunnel service
397729b defnax Tue, 24 Nov 2015 19:41:13 +0100 Added to count downloads/uploads items Enabled to get copy the DHT label values via mouse Added counting on DHT Window & added context menu for DHT Tree, to copy IP addresses to clipboard
36c68e7 csoler Tue, 24 Nov 2015 09:31:29 -0500 Merge pull request #181 from dali99/patch-1
8eadba6 Daniel L.Olsen Tue, 24 Nov 2015 14:43:09 +0100 Fixed a small spelling error
19f1a82 csoler Mon, 23 Nov 2015 22:31:31 -0500 fixed compilation
85a9e4c csoler Mon, 23 Nov 2015 22:19:18 -0500 coding phase done. Needs testing/debugging
5c0f1da csoler Sun, 22 Nov 2015 23:19:46 -0500 saving ongoing work. Implementation almoast finished.
8df9d4b csoler Sun, 22 Nov 2015 11:36:14 -0500 added some doc for tunnel service. Fixed a few function prototypes
b247056 csoler Sat, 21 Nov 2015 15:08:43 -0500 Merge pull request #179 from sirjenster/osx
c89ff9f defnax Sat, 21 Nov 2015 13:47:50 +0100 Added nickname column to pending packets & context menu action to view details Fixed ui layout.
2e76cc6 defnax Sat, 21 Nov 2015 12:32:55 +0100 Fixed DHT icon
4b84767 electron128 Sat, 21 Nov 2015 11:57:50 +0100 hide network mode selection in quick start wizard if node is a hidden node
1f9cb27 Jenster Fri, 20 Nov 2015 20:40:00 -0800 other_osx_patch
699299a Jenster Fri, 20 Nov 2015 08:10:59 -0800 latest OSX patches
47328a4 defnax Thu, 19 Nov 2015 19:11:02 +0100 Merge branch 'master' of https://github.com/RetroShare/RetroShare
4dacd9a defnax Thu, 19 Nov 2015 19:08:47 +0100 Added Ban/Unban Context menu actions for People list.
df6abc8 csoler Thu, 19 Nov 2015 10:54:38 -0500 merged before commit
fa4308e csoler Thu, 19 Nov 2015 10:52:53 -0500 updated TODO list
5404cda defnax Thu, 19 Nov 2015 12:05:52 +0100 Added Forum reply with plaintext quote (by anmo)
cb97ce6 csoler Wed, 18 Nov 2015 23:56:35 -0500 half-way through GxsTunnel service
e3d12b8 defnax Wed, 18 Nov 2015 21:24:38 +0100 Disabled Fontmetrics on RemoteDirModel Columns, it causes unusable very small column height.
7bcbc70 csoler Tue, 17 Nov 2015 18:12:46 -0500 added interface file for gxs tunnel service
cb8b814 csoler Tue, 17 Nov 2015 18:11:00 -0500 added gxs tunnel service, based on distant chat code. Does not compile yet
701f1ce defnax Tue, 17 Nov 2015 17:33:25 +0100 Fixed counting thx to sehraf
01f3db7 defnax Tue, 17 Nov 2015 15:58:22 +0100 Added to count identity items on People
17dc7c7 csoler Mon, 16 Nov 2015 23:56:37 -0500 Merge pull request #68 from chozabu/systray_tweaks
0751876 csoler Mon, 16 Nov 2015 14:06:45 -0500 changed MAX_CACHE_SIZE to not use the default (fixes previous commit that was wrong)
b44d08a csoler Sat, 14 Nov 2015 21:18:26 -0500 changed GXS id cache size to 5000 instead of 100. Should help a lot GXS id handling
e0e3621 csoler Sat, 14 Nov 2015 21:16:30 -0500 added missing wily for ubuntu packages
8238c82 electron128 Sun, 8 Nov 2015 10:34:31 +0100 fix integer size issue in ContentTypes.cpp which can lead to an infinite loop
0a21d92 electron128 Sun, 8 Nov 2015 10:23:45 +0100 Merge pull request #176 from hunbernd/feature/webui-download-enhancements
3991b6f csoler Sun, 8 Nov 2015 01:38:37 -0500 Merge pull request #175 from sembrestels/patch-1
0ef9b22 hunbernd Sun, 8 Nov 2015 01:52:23 +0100 Some fixes: * using ContentTypes to resolve static files too * added some default content types, in the case of mime.types file not present * resolve extensions with upper case letters in them
c6ad0d4 defnax Sun, 8 Nov 2015 01:07:59 +0100 Merge pull request #122 from PhenomRetroShare/Fix_PrioritySpeedMenuForDownloadFiles
b847eea hunbernd Sat, 7 Nov 2015 00:33:37 +0100 Webui: Added video support into MediaPlayerWidget
37353e5 Sem Sat, 7 Nov 2015 19:41:55 +0100 Adding libsqlcipher-dev package
88e1dc0 hunbernd Fri, 6 Nov 2015 22:51:52 +0100 Webui: added links on file names Browsers can play partial files with built-in player, or save files to disk.
ce40760 hunbernd Fri, 6 Nov 2015 22:05:35 +0100 Added support for all common content-types into MHDFilestreamerHandler File extension --> content-type associations are read from mime.types file.
413cee3 electron128 Fri, 6 Nov 2015 19:50:59 +0100 set buffer size for reading config signatures to the size of the computed signature. This fixes the load of the configuration for locations created after 8e6c7cd.
c41f98c defnax Fri, 6 Nov 2015 01:58:30 +0100 Merge pull request #86 from PhenomRetroShare/Fix_Win7_32bCompilationFromScratch
af35af1 csoler Thu, 5 Nov 2015 10:06:43 -0500 Merge pull request #174 from AsamK/hide_debug
0e2417d AsamK Wed, 9 Sep 2015 16:18:47 +0200 Hide debug messages from p3historymgr
75d462e csoler Thu, 5 Nov 2015 03:22:47 -0500 Merge pull request #173 from mr-alice/master
93368aa mr-alice Wed, 4 Nov 2015 21:08:31 -0500 show or hide ID chooser in message box depending on destination of message
3a2b5f1 defnax Wed, 4 Nov 2015 23:47:12 +0100 calculate correct icon size for the status icon
bdc70c6 hunbernd Wed, 4 Nov 2015 22:02:02 +0100 Allow arbitrary name in fstream url after hash. /fstream/fileshash/name Useful for creating file links that contains the original file name.
c4563db defnax Wed, 4 Nov 2015 17:06:44 +0100 Merge branch 'master' of https://github.com/RetroShare/RetroShare
2a998c1 defnax Wed, 4 Nov 2015 17:05:39 +0100 Added new higher resolution bullet icons with better quality
f9e61dd csoler Sat, 31 Oct 2015 13:32:19 -0400 Merge pull request #169 from AsamK/add_missing_return
f06d150 AsamK Sat, 31 Oct 2015 15:13:47 +0100 Add missing return
-- Cyril Soler <csoler@users.sourceforge.net> Fri, 30 Oct 2015 20:00:00 +0100
retroshare06 (0.6.0-1.20151030.3c70c5cc~trusty) trusty; urgency=low
2a5fe4d csoler 30 Oct 2015 21:12:47 -0400 merge before push
1bc2892 csoler 30 Oct 2015 21:11:44 -0400 removed some debug info
6554362 defnax 30 Oct 2015 15:51:13 +0100 Fixed Layout
12acf6d csoler 29 Oct 2015 23:31:23 -0400 fixed update of reputations display and used proper global score in id list
512c15c csoler 29 Oct 2015 22:58:21 -0400 fixed edit/show checkbox state in GxsGroupDialog.
958956a defnax 29 Oct 2015 17:20:32 +0100 Fixing layout & display on Details View anti spam fields
e56ba45 csoler 28 Oct 2015 21:22:07 -0400 attempt to fix the crash at exit, due to some threads asking for memory while the memory management structure is already gone
22fd4e4 csoler 28 Oct 2015 18:11:27 -0400 fixed bug causing signed lobby to refuse login on double click
459cbc6 csoler 28 Oct 2015 18:07:43 -0400 fixed bug causing forum posts to require PGP-signed ID on PGP-favored forums
04ead35 csoler 28 Oct 2015 16:00:27 -0400 Merge pull request #163 from PhenomRetroShare/AddGxsIdInTextAnchor
5beb852 csoler 28 Oct 2015 10:01:26 -0400 Merge pull request #164 from csoler/v0.6-SignedForums2
6df42a0 Phenom 28 Oct 2015 07:18:20 +0100 Add GXS Id in anchor in Chat.
1471dbc csoler 27 Oct 2015 23:53:31 -0400 fixed tooltips for anti-spam forum features
a526a29 csoler 27 Oct 2015 23:40:18 -0400 added missing flag check for anti-spam feature display
b04ce5e csoler 27 Oct 2015 22:47:02 -0400 removed debug info
79c80c9 csoler 27 Oct 2015 22:41:29 -0400 fixed a few bugs in display of tracking info
eefc8d3 defnax 28 Oct 2015 01:59:19 +0100 Fixed Tooltip on Outbox #121 Store Max Results spinbox #130
2096cd6 csoler 27 Oct 2015 20:15:50 -0400 added backward compatibility and API extension for RsGxsGrpMetaData
2cc0f6d defnax 27 Oct 2015 18:52:01 +0100 Added Decline Button to Voip Toaster Added new stylesheet from Beluga for the voip buttons
d69f270 csoler 27 Oct 2015 00:02:16 -0400 restored constants and output to non debugging state
206b27a csoler 26 Oct 2015 23:55:34 -0400 minor bugfix in msg tracking
c7d0e4c csoler 26 Oct 2015 23:38:10 -0400 enabled ID tracking forums. Fixed thresholds for anti-spam forums. Changed computation of reputation scored
b009c11 csoler 25 Oct 2015 23:45:33 -0400 changed RsGenExchange strategy to use a threshold on reputation when validating posts
e60ac99 csoler 25 Oct 2015 22:54:56 -0400 added bias to reputation score for known and signed ids. Changed computation formula to an exp
f24bddf csoler 25 Oct 2015 20:42:41 -0400 merged with upstream head
fee449b csoler 25 Oct 2015 19:28:13 -0400 added proper UI for setting anti-spam flags in GroupCreationDialog
207e84d csoler 25 Oct 2015 18:27:15 -0400 added new flag for msg tracking
3de29c5 csoler 25 Oct 2015 18:07:17 -0400 added load/save of message tracking info
47dd70f csoler 25 Oct 2015 17:16:16 -0400 added non selective tracking for GXS messages
afa3f53 electron128 25 Oct 2015 14:50:28 +0100 fix #150 cannot create pgp signed gxs identity: give users infinite time to type in their password
b340d8a electron128 25 Oct 2015 11:47:23 +0100 Hide about button and add better description for unloaded plugins
b717d60 defnax 25 Oct 2015 00:54:22 +0200 Added default Email Client Button to Web Mail Page
7db3bb1 csoler 24 Oct 2015 12:55:49 -0400 disabled debug info in GenExchange
8ea9771 csoler 24 Oct 2015 12:48:17 -0400 added new flag to GxsIdChooser to force non anonymous ids. Disabled by default
b501d91 defnax 24 Oct 2015 17:05:12 +0200 Added Invite page for Web Mail Providers (Connect Friend Wizard) Added select page style for Quick Start Wizard.
e0db78f csoler 24 Oct 2015 10:41:31 -0400 reject messages signed by non PGP-signed IDs from non anonymous forums
febd348 csoler 24 Oct 2015 00:22:55 -0400 added GUI support for non anon forums. Changed serialisation of GxsGroupMetaData so that mSignFlags is serialised in place of mAuthenFlag, which is not used anyway
a6851b6 csoler 23 Oct 2015 22:53:00 -0400 renamed old flags into indices in rsgenexchange.cc. Fixed up duplicate constants between GxsGroupDialog and rsgxsflags.h
4b402a4 csoler 23 Oct 2015 14:52:55 -0400 Merge pull request #155 from G10h4ck/huns_socket
71073c1 Gioacchino Mazzurco 12 Jan 2015 15:25:01 +0100 Respect passed parameters in unix_socket
463ebe7 csoler 21 Oct 2015 18:47:22 -0400 Merge pull request #154 from sehraf/pr-lobby-time
164c726 sehraf 21 Oct 2015 22:40:49 +0200 suggestion from cyril
bcfb3be defnax 21 Oct 2015 22:39:48 +0200 Hide some Labels on Hidden Mode
c061189 sehraf 21 Oct 2015 22:18:43 +0200 mark chat participants as inactive as long as no activity was seen and reduce time to inactivity from 30 min to 10 min (patches #67)
aec42a8 defnax 21 Oct 2015 04:16:20 +0200 Improved Network Settings Layout, better look and order
6f3ba57 csoler 20 Oct 2015 22:00:15 -0400 fixed up default sizes for list icons and main page icons for high DPI screens
1d1904c csoler 20 Oct 2015 21:03:08 -0400 added missing memory clean calls in X509 certificate generation
6398ed2 csoler 20 Oct 2015 18:39:32 -0400 added checks for result of pthread_create (issue #126)
f49f7ac csoler 20 Oct 2015 18:32:10 -0400 added missing EVP_CIPHER_CTX_cleanup calls (issue #128)
261c7fa csoler 20 Oct 2015 18:24:49 -0400 added missing fclose (issue #134)
78e9123 csoler 20 Oct 2015 18:20:37 -0400 added missing delete (issue #135)
007a3c8 csoler 20 Oct 2015 18:18:10 -0400 merge/pull
b2dbf9d csoler 20 Oct 2015 18:16:18 -0400 adding missing BIO_free (issue #138)
24a685f csoler 20 Oct 2015 18:03:06 -0400 Merge pull request #148 from G10h4ck/unsanelan
5084add csoler 20 Oct 2015 17:56:06 -0400 Merge pull request #151 from diversys/master
34758be Sergei Reznikov 20 Oct 2015 19:41:40 +0300 Add Haiku support
16a5eed Gio 17 Oct 2015 10:27:49 +0200 Removed flawed logic samenet/samesubnet you cannot determine if two ip are in the same subnet just from ips the internet is not just a bunch of /24
febea80 defnax 17 Oct 2015 02:23:46 +0200 Fixed Reputation display, and set text Alignment.
8e6c7cd csoler 16 Oct 2015 12:49:10 -0400 changed SSL cert size to 4096 bits as suggested by cave
6667031 defnax 15 Oct 2015 02:14:52 +0200 Moved to display pending packets on a QTreeWidget. Fixed People layout/spacing & display votes column.
441b164 csoler 13 Oct 2015 21:54:52 -0400 fixed small bugs in average friend reputation display
410102a csoler 13 Oct 2015 21:34:53 -0400 fixed bug causing lobby messages signed by IDs linked to unknown PGP keys to be dropped
525310e csoler 13 Oct 2015 18:22:01 -0400 merging
4f744a6 csoler 13 Oct 2015 18:21:05 -0400 updated ubuntu changlog
a75cbcd electron128 13 Oct 2015 20:36:00 +0200 webui: format time of chat messages
537c492 electron128 13 Oct 2015 20:35:24 +0200 libresapi: fixed bug in JSON serialisation of uint32_t, decimal digits had inverse order
4df3283 electron128 13 Oct 2015 20:27:53 +0200 webui: restored Makefile
0b2fdee csoler 13 Oct 2015 14:23:31 -0400 Merge pull request #147 from PhenomRetroShare/Fix_ChatWidget_IsTypingLabel
245a282 Phenom 13 Oct 2015 20:11:30 +0200 Fix centered Typing Label on ChatWidget.
477c11e csoler 13 Oct 2015 13:51:23 -0400 Merge pull request #146 from PhenomRetroShare/FixVOIP_VividCompilation
3172cd9 Phenom 13 Oct 2015 19:17:25 +0200 Fix VOIP Compilation on Vivid as they use a different version of rational.h
791f5fe defnax 13 Oct 2015 02:18:41 +0200 Fixed ID Details Dialog with Reputation
58bd186 defnax 13 Oct 2015 00:38:46 +0200 Set a default stylesheet padding size for the Accept/Decline buttons
e924193 defnax 12 Oct 2015 23:42:56 +0200 Merge pull request #144 from PhenomRetroShare/FixVOIP_HeightOfToolBarForWindowsInFullScreen
5dbd84b defnax 12 Oct 2015 23:38:05 +0200 Merge pull request #145 from PhenomRetroShare/Fix_Win32CompilationForPR#143
47c47d1 Phenom 12 Oct 2015 23:21:17 +0200 Fix Compilation on Win32 after PR#143 merged.
7bc6fdf Phenom 12 Oct 2015 23:17:00 +0200 Fix the height of the ToolBar in VOIP FullScreen for Windows.
-- Cyril Soler <csoler@users.sourceforge.net> Fri, 30 Oct 2015 20:00:00 +0100
retroshare06 (0.6.0-1.0120234~trusty) trusty; urgency=low
0120234 csoler 12 Oct 2015 15:06:12 -0400 Merge pull request #143 from csoler/v0.6-Reputations
71c8dfd csoler 12 Oct 2015 14:45:11 -0400 manual merge before creating a conflict-free PR
f18cc82 csoler 12 Oct 2015 14:22:51 -0400 fixed up constants for reputation system, now that is has been tested
e6bb307 csoler 12 Oct 2015 14:04:23 -0400 added update for forum messages list when an author gets banned
7dc5984 csoler 12 Oct 2015 14:03:53 -0400 added update for forum messages list when an author gets banned
022ac10 defnax 12 Oct 2015 18:58:12 +0200 Merge pull request #141 from PhenomRetroShare/AddVOIP_ReactivateSoundEvents
3d32fab Phenom 12 Oct 2015 18:25:03 +0200 Reactivate SoundEvents in VOIP.
86b47d8 csoler 12 Oct 2015 10:58:24 -0400 reduced icon size a little bit in GxsTreeWidgetItem
5a3756f csoler 12 Oct 2015 10:41:48 -0400 fixed bug on reputation cutoff. Updated tooltips
36101a9 csoler 12 Oct 2015 00:28:21 -0400 fixed small bug preventing msg exchange
82c16c6 csoler 11 Oct 2015 22:08:19 -0400 fixed GUI tooltips over banned items. Added dropping of messages from banned ide
1a76bea csoler 11 Oct 2015 21:41:35 -0400 enabled bannign button in forums, and disable message passing for banned users
ad4dabf csoler 11 Oct 2015 13:31:54 -0400 Merge pull request #140 from PhenomRetroShare/AddVOIP_Accept,RingAndHangUp
ebe48f4 csoler 11 Oct 2015 11:12:11 -0400 added proper memory release after mallocs in distant chat (SVN bug 383)
e309dd6 csoler 11 Oct 2015 10:00:11 -0400 fixed banning users from forum threads
6a3f4ce Phenom 11 Oct 2015 10:31:06 +0200 Update Toaster when ringing.
f750818 csoler 10 Oct 2015 21:25:06 -0400 added proper icons and names for banned users
68ca57c csoler 10 Oct 2015 18:27:15 -0400 added removal of messages frm banned users
3deee00 Phenom 10 Oct 2015 18:47:07 +0200 Hang Up when close chat window.
1989f36 Phenom 10 Oct 2015 15:21:59 +0200 Add Accept, Ring and HangUp event for Video and Audio. Now you don't send data b
1a229ef defnax 10 Oct 2015 14:16:12 +0200 Fixed to display GXS ID item with a better icon size
59d2ca9 csoler 9 Oct 2015 18:55:07 -0400 fixed bug causing uninitialised friend average reputation to be shown
338fcee csoler 9 Oct 2015 18:51:16 -0400 added button in forums to flag poster identity as bad
ce96e88 csoler 9 Oct 2015 17:51:10 -0400 debugging of reputation system
ffb8f73 defnax 9 Oct 2015 12:07:23 +0200 Merge branch 'master' of https://github.com/RetroShare/RetroShare
e97f23d defnax 9 Oct 2015 12:06:16 +0200 Improved icon size display on GroupTree.
bb7a8f2 csoler 8 Oct 2015 23:54:18 -0400 fixed some reputation sending bugs
8c6c934 csoler 8 Oct 2015 23:02:34 -0400 fixed a few bugs in reputation items serialisation code and GUI display
1cf9c34 csoler 8 Oct 2015 19:48:22 -0400 fixed compilation for MacOS
4a4625e csoler 8 Oct 2015 18:54:12 -0400 fixed compilation for windows (to be tested)
3d21d99 csoler 8 Oct 2015 18:39:50 -0400 added debug info for reputation system
80ed6d1 csoler 7 Oct 2015 23:44:24 -0400 added pruning of opinions to limit data in memory. Fixed up types and sending/rec
e776eff csoler 7 Oct 2015 21:24:31 -0400 added new method rsGetHostByName to use gethostbyname_r for re-entrant calls. Upd
f1f722a csoler 7 Oct 2015 19:08:35 -0400 added missing shutdown of non responsive socket that could leak FDs (suggested by
39672b2 csoler 7 Oct 2015 18:59:58 -0400 fixed typo causing non free of mutex_buf structure in pqissl.cc
3cbf0f6 defnax 7 Oct 2015 20:13:18 +0200 Fixed Cert Display on Email Invite Page
78e6f67 csoler 6 Oct 2015 23:56:39 -0400 added some documentation in p3gxsreputation.cc, and the method for computing fina
b094089 csoler 6 Oct 2015 22:39:14 -0400 fixed compilation
95bdd7f defnax 7 Oct 2015 01:35:31 +0200 Fixed ChatWidget Margin's Set Alignment for frame off's Video icon
993ca63 defnax 6 Oct 2015 19:58:42 +0200 Fixed icons display
3f116e2 defnax 6 Oct 2015 18:54:43 +0200 display voip icons in a bigger size
fedb8f7 csoler 6 Oct 2015 09:47:54 -0400 Merge pull request #129 from PhenomRetroShare/FixVOIP_AllowVOIPToSaveSetting
ff46d90 csoler 6 Oct 2015 08:58:30 -0400 Merge pull request #120 from PhenomRetroShare/AddVOIP_HideChatTextButton
9f6bc0c csoler 6 Oct 2015 00:11:18 -0400 added code for all reputation items
05d95d3 Phenom 5 Oct 2015 21:04:20 +0200 Use QFontMetricsF to define Icon size.
2b1d39c Phenom 4 Oct 2015 14:12:20 +0200 Add HideChat Button. Change layout of video when text is hidden. Add toolbar in f
5d8972e Phenom 3 Oct 2015 02:11:52 +0200 Add real FullScreen Mode
0120234 csoler 12 Oct 2015 15:06:12 -0400 Merge pull request #143 from csoler/v0.6-Reputations
71c8dfd csoler 12 Oct 2015 14:45:11 -0400 manual merge before creating a conflict-free PR
f18cc82 csoler 12 Oct 2015 14:22:51 -0400 fixed up constants for reputation system, now that is has been tested
e6bb307 csoler 12 Oct 2015 14:04:23 -0400 added update for forum messages list when an author gets banned
7dc5984 csoler 12 Oct 2015 14:03:53 -0400 added update for forum messages list when an author gets banned
022ac10 defnax 12 Oct 2015 18:58:12 +0200 Merge pull request #141 from PhenomRetroShare/AddVOIP_ReactivateSoundEvents
3d32fab Phenom 12 Oct 2015 18:25:03 +0200 Reactivate SoundEvents in VOIP.
86b47d8 csoler 12 Oct 2015 10:58:24 -0400 reduced icon size a little bit in GxsTreeWidgetItem
5a3756f csoler 12 Oct 2015 10:41:48 -0400 fixed bug on reputation cutoff. Updated tooltips
36101a9 csoler 12 Oct 2015 00:28:21 -0400 fixed small bug preventing msg exchange
82c16c6 csoler 11 Oct 2015 22:08:19 -0400 fixed GUI tooltips over banned items. Added dropping of messages from banned ide
1a76bea csoler 11 Oct 2015 21:41:35 -0400 enabled bannign button in forums, and disable message passing for banned users
ad4dabf csoler 11 Oct 2015 13:31:54 -0400 Merge pull request #140 from PhenomRetroShare/AddVOIP_Accept,RingAndHangUp
ebe48f4 csoler 11 Oct 2015 11:12:11 -0400 added proper memory release after mallocs in distant chat (SVN bug 383)
e309dd6 csoler 11 Oct 2015 10:00:11 -0400 fixed banning users from forum threads
6a3f4ce Phenom 11 Oct 2015 10:31:06 +0200 Update Toaster when ringing.
f750818 csoler 10 Oct 2015 21:25:06 -0400 added proper icons and names for banned users
68ca57c csoler 10 Oct 2015 18:27:15 -0400 added removal of messages frm banned users
3deee00 Phenom 10 Oct 2015 18:47:07 +0200 Hang Up when close chat window.
1989f36 Phenom 10 Oct 2015 15:21:59 +0200 Add Accept, Ring and HangUp event for Video and Audio. Now you don't send data b
1a229ef defnax 10 Oct 2015 14:16:12 +0200 Fixed to display GXS ID item with a better icon size
59d2ca9 csoler 9 Oct 2015 18:55:07 -0400 fixed bug causing uninitialised friend average reputation to be shown
338fcee csoler 9 Oct 2015 18:51:16 -0400 added button in forums to flag poster identity as bad
ce96e88 csoler 9 Oct 2015 17:51:10 -0400 debugging of reputation system
ffb8f73 defnax 9 Oct 2015 12:07:23 +0200 Merge branch 'master' of https://github.com/RetroShare/RetroShare
e97f23d defnax 9 Oct 2015 12:06:16 +0200 Improved icon size display on GroupTree.
bb7a8f2 csoler 8 Oct 2015 23:54:18 -0400 fixed some reputation sending bugs
8c6c934 csoler 8 Oct 2015 23:02:34 -0400 fixed a few bugs in reputation items serialisation code and GUI display
1cf9c34 csoler 8 Oct 2015 19:48:22 -0400 fixed compilation for MacOS
4a4625e csoler 8 Oct 2015 18:54:12 -0400 fixed compilation for windows (to be tested)
3d21d99 csoler 8 Oct 2015 18:39:50 -0400 added debug info for reputation system
80ed6d1 csoler 7 Oct 2015 23:44:24 -0400 added pruning of opinions to limit data in memory. Fixed up types and sending/rec
e776eff csoler 7 Oct 2015 21:24:31 -0400 added new method rsGetHostByName to use gethostbyname_r for re-entrant calls. Upd
f1f722a csoler 7 Oct 2015 19:08:35 -0400 added missing shutdown of non responsive socket that could leak FDs (suggested by
39672b2 csoler 7 Oct 2015 18:59:58 -0400 fixed typo causing non free of mutex_buf structure in pqissl.cc
3cbf0f6 defnax 7 Oct 2015 20:13:18 +0200 Fixed Cert Display on Email Invite Page
78e6f67 csoler 6 Oct 2015 23:56:39 -0400 added some documentation in p3gxsreputation.cc, and the method for computing fina
b094089 csoler 6 Oct 2015 22:39:14 -0400 fixed compilation
95bdd7f defnax 7 Oct 2015 01:35:31 +0200 Fixed ChatWidget Margin's Set Alignment for frame off's Video icon
993ca63 defnax 6 Oct 2015 19:58:42 +0200 Fixed icons display
3f116e2 defnax 6 Oct 2015 18:54:43 +0200 display voip icons in a bigger size
fedb8f7 csoler 6 Oct 2015 09:47:54 -0400 Merge pull request #129 from PhenomRetroShare/FixVOIP_AllowVOIPToSaveSetting
ff46d90 csoler 6 Oct 2015 08:58:30 -0400 Merge pull request #120 from PhenomRetroShare/AddVOIP_HideChatTextButton
9f6bc0c csoler 6 Oct 2015 00:11:18 -0400 added code for all reputation items
05d95d3 Phenom 5 Oct 2015 21:04:20 +0200 Use QFontMetricsF to define Icon size.
2b1d39c Phenom 4 Oct 2015 14:12:20 +0200 Add HideChat Button. Change layout of video when text is hidden. Add toolbar in f
5d8972e Phenom 3 Oct 2015 02:11:52 +0200 Add real FullScreen Mode
8a7e359 Phenom 1 Oct 2015 23:41:34 +0200 Add a button on VOIP to hide text when video is on.
3c8f232 Phenom 5 Oct 2015 19:15:53 +0200 Allow VOIP to save its settings.
d4c838b csoler 5 Oct 2015 08:51:33 -0400 Merge pull request #127 from sehraf/pr-disable-sorting
6a570af sehraf 5 Oct 2015 09:26:36 +0200 disable sorting while editing network view
7a7f4c9 csoler 4 Oct 2015 23:18:31 -0400 added missing file
317e7ea csoler 4 Oct 2015 23:14:49 -0400 added some backend for reputation system
c17dddb csoler 4 Oct 2015 17:47:30 -0400 updated GUI for reputation
b5bfddd csoler 3 Oct 2015 22:08:24 -0400 commit from PR#86 for VOIP, modified so as to restore real-time preview and video
9158ed6 csoler 3 Oct 2015 10:46:36 -0400 fixed potential buffer overrun (reported by GuessWho)
7fa687a csoler 3 Oct 2015 10:29:08 -0400 Merge pull request #119 from PhenomRetroShare/AddWebUI_BroadcastInLobbiesLis
b22069c csoler 3 Oct 2015 10:28:17 -0400 Merge pull request #123 from PhenomRetroShare/Fix_ChatWidgetDeleteKeyEvent
64389e3 Phenom 3 Oct 2015 11:00:16 +0200 Fiw Delete key event in ChatWidget.
904ea94 Phenom 2 Oct 2015 19:10:54 +0200 Remove (void)
986853d Phenom 1 Oct 2015 18:49:39 +0200 Add Broadcast in list of lobbies. Before you can only write text on it if unread
b055500 csoler 2 Oct 2015 11:03:52 -0400 Merge pull request #117 from G10h4ck/master
bd94fcd csoler 2 Oct 2015 10:53:00 -0400 Merge pull request #98 from PhenomRetroShare/AddMinimumFontSizeInChat
f6abe2f csoler 2 Oct 2015 10:50:14 -0400 Merge pull request #115 from PhenomRetroShare/AddWebUI_LobbyOrderByType
e83ae76 Gio 27 Sep 2015 20:15:41 +0200 pqiconnect remove ni NULL pointer check as it would crash anyway for null pointer d
28b9a44 Gio 27 Sep 2015 15:29:32 +0200 Write in a sane way pqissl::connect_parameter
b16ecc8 Gio 27 Sep 2015 15:11:55 +0200 Remove some garbage from pqissl
d6ba9a2 Phenom 25 Sep 2015 17:00:50 +0200 Order in WebUI Lobbies by first: auto_subscribe, is_private and then subscribed
3025f4d csoler 24 Sep 2015 18:18:11 -0400 removed aliasign problem that breaks compilation on gentoo
22d4893 csoler 24 Sep 2015 18:03:19 -0400 removed a few compilation warning that might cause compilation errors on some sy
0614a24 csoler 23 Sep 2015 22:11:50 -0400 Merge pull request #111 from csoler/v0.6-ImprovedExtIPDetermination
24b3325 csoler 23 Sep 2015 21:45:15 -0400 Improved reliability of the determination of external address: removed DHT stunn
323d894 csoler 22 Sep 2015 23:21:14 -0400 Merge pull request #110 from jenster/newbranchformychanges
68fd1b2 jenster 22 Sep 2015 18:33:16 -0700 First Mac/OSX compile fixes
6071be9 csoler 22 Sep 2015 11:20:28 -0400 Merge pull request #109 from AsamK/workaround_broken_sqlcipher
c80ad59 AsamK 22 Sep 2015 16:31:21 +0200 Add workaround for broken sqlcipher packages
7293cd3 csoler 21 Sep 2015 22:58:58 -0400 updated ubuntu changelog
1d54630 thunder2 17 Sep 2015 10:05:31 +0200 Fixed Windows compile.
66691d4 csoler 16 Sep 2015 20:01:39 -0400 Merge pull request #108 from sehraf/i2p
04abfad sehraf 16 Sep 2015 17:01:20 +0200 manually reverted changes by Qt Creator
7c7e4f8 sehraf 16 Sep 2015 12:13:54 +0200 added ip addr. field to the add certificate dialog
6202e83 sehraf 16 Sep 2015 11:48:32 +0200 add default case to gui instead of falling back to tor labeling
d3d184f sehraf 16 Sep 2015 11:09:04 +0200 added simple step-by-step guide to add a I2P server tunnel
e54358a sehraf 16 Sep 2015 10:55:33 +0200 added simple step-by-step guide to add a I2P client tunnel
1dd3375 sehraf 15 Sep 2015 17:14:55 +0200 hide debug output
d24b281 sehraf 15 Sep 2015 17:10:48 +0200 optimizations * reduced calls to mPeermgr * use switch convenience * small fixes
bfcf43f sehraf 15 Sep 2015 16:18:46 +0200 fixed connection type detection and other small things
8725aab sehraf 14 Sep 2015 15:14:39 +0200 gui fixes
6b87c38 sehraf 14 Sep 2015 14:56:14 +0200 small fixes
6ec1919 sehraf 14 Sep 2015 12:39:46 +0200 gui changes
b0251e3 sehraf 14 Sep 2015 12:12:28 +0200 generalized tooltips
4b19e73 sehraf 14 Sep 2015 09:56:43 +0200 added comments to functions
8a7e359 Phenom 1 Oct 2015 23:41:34 +0200 Add a button on VOIP to hide text when video is on.
3c8f232 Phenom 5 Oct 2015 19:15:53 +0200 Allow VOIP to save its settings.
d4c838b csoler 5 Oct 2015 08:51:33 -0400 Merge pull request #127 from sehraf/pr-disable-sorting
6a570af sehraf 5 Oct 2015 09:26:36 +0200 disable sorting while editing network view
7a7f4c9 csoler 4 Oct 2015 23:18:31 -0400 added missing file
317e7ea csoler 4 Oct 2015 23:14:49 -0400 added some backend for reputation system
c17dddb csoler 4 Oct 2015 17:47:30 -0400 updated GUI for reputation
b5bfddd csoler 3 Oct 2015 22:08:24 -0400 commit from PR#86 for VOIP, modified so as to restore real-time preview and video
9158ed6 csoler 3 Oct 2015 10:46:36 -0400 fixed potential buffer overrun (reported by GuessWho)
7fa687a csoler 3 Oct 2015 10:29:08 -0400 Merge pull request #119 from PhenomRetroShare/AddWebUI_BroadcastInLobbiesLis
b22069c csoler 3 Oct 2015 10:28:17 -0400 Merge pull request #123 from PhenomRetroShare/Fix_ChatWidgetDeleteKeyEvent
64389e3 Phenom 3 Oct 2015 11:00:16 +0200 Fiw Delete key event in ChatWidget.
904ea94 Phenom 2 Oct 2015 19:10:54 +0200 Remove (void)
986853d Phenom 1 Oct 2015 18:49:39 +0200 Add Broadcast in list of lobbies. Before you can only write text on it if unread
b055500 csoler 2 Oct 2015 11:03:52 -0400 Merge pull request #117 from G10h4ck/master
bd94fcd csoler 2 Oct 2015 10:53:00 -0400 Merge pull request #98 from PhenomRetroShare/AddMinimumFontSizeInChat
f6abe2f csoler 2 Oct 2015 10:50:14 -0400 Merge pull request #115 from PhenomRetroShare/AddWebUI_LobbyOrderByType
e83ae76 Gio 27 Sep 2015 20:15:41 +0200 pqiconnect remove ni NULL pointer check as it would crash anyway for null pointer d
28b9a44 Gio 27 Sep 2015 15:29:32 +0200 Write in a sane way pqissl::connect_parameter
b16ecc8 Gio 27 Sep 2015 15:11:55 +0200 Remove some garbage from pqissl
d6ba9a2 Phenom 25 Sep 2015 17:00:50 +0200 Order in WebUI Lobbies by first: auto_subscribe, is_private and then subscribed
3025f4d csoler 24 Sep 2015 18:18:11 -0400 removed aliasign problem that breaks compilation on gentoo
22d4893 csoler 24 Sep 2015 18:03:19 -0400 removed a few compilation warning that might cause compilation errors on some sy
0614a24 csoler 23 Sep 2015 22:11:50 -0400 Merge pull request #111 from csoler/v0.6-ImprovedExtIPDetermination
24b3325 csoler 23 Sep 2015 21:45:15 -0400 Improved reliability of the determination of external address: removed DHT stunn
323d894 csoler 22 Sep 2015 23:21:14 -0400 Merge pull request #110 from jenster/newbranchformychanges
68fd1b2 jenster 22 Sep 2015 18:33:16 -0700 First Mac/OSX compile fixes
6071be9 csoler 22 Sep 2015 11:20:28 -0400 Merge pull request #109 from AsamK/workaround_broken_sqlcipher
c80ad59 AsamK 22 Sep 2015 16:31:21 +0200 Add workaround for broken sqlcipher packages
-- Cyril Soler <csoler@users.sourceforge.net> Mon, 12 Oct 2015 20:00:00 +0100
retroshare06 (0.6.0-1.7293cd3~trusty) trusty; urgency=low
7293cd3 csoler Mon, 21 Sep 2015 22:58:58 -0400 updated ubuntu changelog
1d54630 thunder2 17 Sep 2015 10:05:31 +0200 Fixed Windows compile.
66691d4 csoler 16 Sep 2015 20:01:39 -0400 Merge pull request #108 from sehraf/i2p
04abfad sehraf 16 Sep 2015 17:01:20 +0200 manually reverted changes by Qt Creator
7c7e4f8 sehraf 16 Sep 2015 12:13:54 +0200 added ip addr. field to the add certificate dialog
6202e83 sehraf 16 Sep 2015 11:48:32 +0200 add default case to gui instead of falling back to tor labeling
d3d184f sehraf 16 Sep 2015 11:09:04 +0200 added simple step-by-step guide to add a I2P server tunnel
e54358a sehraf 16 Sep 2015 10:55:33 +0200 added simple step-by-step guide to add a I2P client tunnel
1dd3375 sehraf 15 Sep 2015 17:14:55 +0200 hide debug output
d24b281 sehraf 15 Sep 2015 17:10:48 +0200 optimizations * reduced calls to mPeermgr * use switch convenience * small fixes
bfcf43f sehraf 15 Sep 2015 16:18:46 +0200 fixed connection type detection and other small things
8725aab sehraf 14 Sep 2015 15:14:39 +0200 gui fixes
6b87c38 sehraf 14 Sep 2015 14:56:14 +0200 small fixes
6ec1919 sehraf 14 Sep 2015 12:39:46 +0200 gui changes
b0251e3 sehraf 14 Sep 2015 12:12:28 +0200 generalized tooltips
4b19e73 sehraf 14 Sep 2015 09:56:43 +0200 added comments to functions
900e51b csoler 13 Sep 2015 18:08:06 -0400 Merge pull request #107 from PhenomRetroShare/AddFriendListItemMouseEvents
48e6618 Phenom 13 Sep 2015 19:00:31 +0200 Send Mouse event to FriendList's item, since ElidedLabel was fixed.
7195d4c csoler 10 Sep 2015 09:41:28 -0400 Merge pull request #105 from ericthefish/master
4880fc4 Ivan Lucas 10 Sep 2015 11:21:01 +0100 Fixed grammar on add friend wizard by rewording slightly
840e930 Ivan Lucas 10 Sep 2015 10:29:15 +0100 Fix Spelling and Grammar
770e934 Ivan Lucas 10 Sep 2015 10:18:14 +0100 Merge remote-tracking branch 'upstream/master'
4a0539c csoler 9 Sep 2015 19:57:07 -0400 Merge pull request #103 from AsamK/html_parsing
1acd4a3 csoler 9 Sep 2015 16:44:59 -0400 Merge pull request #104 from PhenomRetroShare/Fix_ElidedLabel_mousePresEvent
ce9fc7b Phenom 9 Sep 2015 22:37:38 +0200 Fix ElidedLabel::mousePressEvent.
75a7a89 Ivan Lucas 9 Sep 2015 15:19:17 +0100 Fix typo
7aad9c1 AsamK 9 Sep 2015 13:36:00 +0200 Improve HTML parsing in libresapi
b8c3c89 AsamK 9 Sep 2015 11:53:01 +0200 Extract getPlainText method
ebd5da5 thunder2 8 Sep 2015 16:34:22 +0200 Optimizations in RsGenExchange, p3GxsForums and p3GxsChannels. - Removed not used variables
avoid copy constructors - Use swap instead of operator= to move elements of std containers
490b88c csoler 8 Sep 2015 14:17:29 -0400 Merge pull request #100 from ericthefish/master
a2e7e4d Ivan Lucas 8 Sep 2015 16:12:50 +0100 Fixed spelling/grammar
4f8b098 Ivan Lucas 8 Sep 2015 16:00:00 +0100 Fixing spelling
c4061fc thunder2 7 Sep 2015 22:27:04 +0200 Removed not used time consuming calculation of row count from RetroCursor.
29a1fa2 thunder2 7 Sep 2015 21:48:18 +0200 Removed unnecessary copy of results in RsGxsDataAccess.
0bc77d7 sehraf 8 Sep 2015 13:48:30 +0200 added some error handling
da417ee csoler 7 Sep 2015 20:38:47 -0400 Merge pull request #96 from AsamK/qmake_3
63e38af csoler 7 Sep 2015 20:36:03 -0400 Merge pull request #94 from AsamK/correct_libav_version
03d99ae sehraf 7 Sep 2015 23:55:57 +0200 made GenCertDislog more generic
4fc6c73 sehraf 7 Sep 2015 23:40:52 +0200 replaced some ifs with switch
e2768e0 defnax 7 Sep 2015 23:34:39 +0200 Added last used field to Person Details Window
fed4345 sehraf 7 Sep 2015 22:57:54 +0200 made server settings more generic and added i2p support
95d6b06 sehraf 7 Sep 2015 18:46:19 +0200 first working version
0107f4e sehraf 7 Sep 2015 12:59:21 +0200 first run on gui integration
ba74c04 sehraf 7 Sep 2015 11:51:24 +0200 removed duplicated code, fixed compile, few additions
c17d0e1 sehraf 7 Sep 2015 11:22:15 +0200 add i2p support to libretroshare
2c1743f defnax 7 Sep 2015 15:13:32 +0200 Added send message function for Participants list.
cc4be39 defnax 7 Sep 2015 15:08:56 +0200 Merge branch 'master' of https://github.com/RetroShare/RetroShare
0793a6a AsamK 6 Sep 2015 14:19:21 +0200 Use PLUGIN_DIR to define plugin directory only once
fe1ec9d AsamK 5 Sep 2015 22:49:57 +0200 Fixed mac compile. Moved sqlcipher.a to libretroshare.pro
571336e AsamK 5 Sep 2015 23:49:15 +0200 Move duplicate common stuff out of platform parts
66b9557 AsamK 5 Sep 2015 23:48:24 +0200 Use PKGCONFIG instead of manually specifying LIBS for Linux
b8e3a43 thunder2 6 Sep 2015 21:28:34 +0200 Auto download of recommended files adds the sender as source of the download.
5f36500 thunder2 6 Sep 2015 14:21:05 +0200 Fixed click in column "Friend nodes" in FriendList.
869077b thunder2 5 Sep 2015 12:46:18 +0200 Combined selects in RsDataService::retrieveNxsGrps/RsDataService::retrieveNxsMsgs.
d6f50c7 AsamK 5 Sep 2015 15:44:10 +0200 Fix libav version check
e9a5523 defnax 5 Sep 2015 00:16:07 +0200 Merge branch 'master' of https://github.com/RetroShare/RetroShare
7f8dae9 defnax 4 Sep 2015 16:33:43 +0200 Merge branch 'master' of https://github.com/RetroShare/RetroShare
07c5030 defnax 3 Sep 2015 17:41:30 +0200 Merge branch 'master' of https://github.com/RetroShare/RetroShare
3d6e978 defnax 2 Sep 2015 13:06:15 +0200 Fixed Status Label on Distant Chat
-- Cyril Soler <csoler@users.sourceforge.net> Mon, 21 Sep 2015 20:00:00 +0100
retroshare06 (0.6.0-1.20150905.8bb76c95~trusty) trusty; urgency=low
a276986 ( ) Merge pull request #60 from PhenomRetroShare/Fix_AllowChatTextFormatOption
88a6931 (GUI ) Allow Chat Text Format Option working.
0b5b20d ( ) Merge pull request #59 from AsamK/qmake_improvements
@ -98,9 +627,9 @@ retroshare06 (0.6.0-1.XXXXXX~YYYYYY) YYYYYY; urgency=low
4d7f733 (Packaging ) fixed bug in git parameter in packaging script
9734f32 (Packaging ) updated ubuntu changelog. improved ubuntu packaging script
-- Cyril Soler <csoler@users.sourceforge.net> Sun, 16 Aug 2015 20:00:00 +0100
-- Cyril Soler <csoler@users.sourceforge.net> Sun, 05 Sep 2015 20:00:00 +0100
retroshare06 (0.6.0-1.20150816~9734f32a) trusty; urgency=low
retroshare06 (0.6.0-1.20150816.9734f32a~trusty) trusty; urgency=low
f6b830d (branch merging) Merge pull request #35 from hunbernd/chat-fix
16859a1 (GUI ) Fix: chatlobby toaster not working
@ -1531,7 +2060,7 @@ retroshare (0.5.4-0.6685~precise) precise; urgency=low
* Bug fixes
- Added missing location from cert when addign new friend
- Added missing location from cert when adding new friend
- Added missing IndicateConfigChanged to p3PeerMgrIMPL::setDynDNS
- Fixed crash when closing the main window without the setting "Minimize to Tray Icon"
- Renamed the setting "Do not Minimize to Tray Icon" to "Minimize to Tray
@ -2605,7 +3134,7 @@ retroshare (0.5.3-0.4953~natty) natty; urgency=low
- Fixed Download toaster (utf8 in file name, use QDesktopServices vs RsUrlHandler for collections, fixed
crash after opening a collection) (Patch from AsamK).
- fixed utf8 chars in certificate links (Patch from AsamK)
- removed cache adding strategy to DL queue that was O(n^2). Now addign cache at the end of the queue
- removed cache adding strategy to DL queue that was O(n^2). Now adding cache at the end of the queue
- Fixed bug when the user clicks on a link without http:// in a QTextBrowser. This link was
oppened directly in RetroShare.
- Attempted fix for maintaining External Port in Manual Forwarded Mode.

View file

@ -47,7 +47,7 @@ while [ ${#} -gt 0 ]; do
done
if test "${dist}" = "" ; then
dist="precise trusty vivid"
dist="precise trusty vivid wily"
fi
echo Attempting to get revision number...

View file

@ -1,44 +0,0 @@
CPPFLAGS += -g -Wall -D BE_DEBUG -lpthread
LDFLAGS += -g -Wall -D BE_DEBUG -lpthread
CFLAGS += -g -Wall -D BE_DEBUG
CC = g++
LIB = -lpthread
CPPLIB = -lpthread
EXEC = bdmsgs_test bdmetric_test bdquery_test bdspace_test bdspace_test2 bdnode_test bdnode_test2 bdstore_test
EXEC += bdnode_multitest1 bdmidids_test
EXEC += udpbitdht_nettest bencode_test
EXEC += bdmgr_multitest
#EXEC += bdudp_test
all: $(EXEC)
OBJ = bencode.o bdmsgs.o bdobj.o
OBJ += bdpeer.o bdquery.o bdnode.o bdstore.o bdhash.o
OBJ += bdmanager.o bdstddht.o
# udp base objs
OBJ += bdthreads.o udplayer.o udpstack.o
OBJ += udpbitdht.o
bdmsgs_test: $(OBJ) bdmsgs_test.o
bdmetric_test: $(OBJ) bdmetric_test.o
bdquery_test: $(OBJ) bdquery_test.o
bdspace_test: $(OBJ) bdspace_test.o
bdspace_test2: $(OBJ) bdspace_test2.o
bdnode_test: $(OBJ) bdnode_test.o
bdnode_test2: $(OBJ) bdnode_test2.o
bdmidids_test: $(OBJ) bdmidids_test.o
bdnode_multitest1: $(OBJ) bdnode_multitest1.o
bdmgr_multitest: $(OBJ) bdmgr_multitest.o
bdstore_test: $(OBJ) bdstore_test.o
bdudp_test: $(OBJ) bdudp_test.o
udpbitdht_nettest: $(OBJ) udpbitdht_nettest.o
bencode_test: $(OBJ) bencode_test.o
clean:
rm -f *.o core $(EXEC)
.PHONY: all clean

View file

@ -1,16 +0,0 @@
CXXFLAGS = -Wall -g -I..
#CXXFLAGS += -arch i386 # OSX
LIBS = -L../lib -lbitdht -lpthread
EXEC : bssdht
EGOBJ = bdhandler.o bssdht.o bootstrap_fn.o
bssdht: $(EGOBJ)
$(CXX) $(CXXFLAGS) -o bssdht $(EGOBJ) $(LIBS)

View file

@ -4,6 +4,8 @@ TEMPLATE = lib
CONFIG += staticlib
CONFIG -= qt
TARGET = bitdht
DESTDIR = lib
QMAKE_CXXFLAGS *= -Wall -DBE_DEBUG
profiling {
@ -27,7 +29,6 @@ debug {
################################# Linux ##########################################
linux-* {
DESTDIR = lib
QMAKE_CC = g++
}
@ -50,7 +51,6 @@ unix {
win32-x-g++ {
OBJECTS_DIR = temp/win32xgcc/obj
DESTDIR = lib.win32xgcc
# These have been replaced by _WIN32 && __MINGW32__
# DEFINES *= WINDOWS_SYS WIN32 WIN_CROSS_UBUNTU
QMAKE_CXXFLAGS *= -Wmissing-include-dirs
@ -70,7 +70,6 @@ win32 {
DEFINES *= STATICLIB WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T
# These have been replaced by _WIN32 && __MINGW32__
#DEFINES *= WINDOWS_SYS WIN32 STATICLIB MINGW
DESTDIR = lib
# Switch on extra warnings
QMAKE_CFLAGS += -Wextra
@ -93,18 +92,21 @@ mac {
QMAKE_CC = g++
OBJECTS_DIR = temp/obj
MOC_DIR = temp/moc
DESTDIR = lib
}
################################# FreeBSD ##########################################
freebsd-* {
DESTDIR = lib
}
################################# OpenBSD ##########################################
openbsd-* {
}
################################# Haiku ##########################################
haiku-* {
DESTDIR = lib
}
@ -168,5 +170,3 @@ SOURCES += \
bitdht/bdquerymgr.cc \
util/bdbloom.cc \
bitdht/bdfriendlist.cc \

View file

@ -1,91 +0,0 @@
LIB_TOP_DIR = ..
TEST_TOP_DIR = $(LIB_TOP_DIR)/tests
##### Define any flags that are needed for this section #######
###############################################################
###############################################################
include $(TEST_TOP_DIR)/scripts/config.mk
###############################################################
# Generic Test Harnesses.
TESTOBJ = bdmetric_test.o bdmsgs_test.o bdnode_test.o bdspace_test.o
TESTOBJ += bdmgr_multitest.o bdquery_test.o bdstore_test.o
TESTOBJ += bdmidids_test.o bdspace_test2.o udpbitdht_nettest.o
TESTOBJ += bdbloom_test.o bdbloom_makefilter.o
#TESTOBJ += bencode_test.o bdudp_test.o
#TESTOBJ = bdnode_test.o bdnode_multitest1.o bdnode_test2.o
TESTS = bdmetric_test bdmsgs_test bdspace_test
TESTS += bdmgr_multitest bdquery_test bdstore_test
TESTS += bdmidids_test bdspace_test2 udpbitdht_nettest
TESTS += bdbloom_test
#TESTS += bencode_test bdudp_test
#Tests to Fix.
#TESTS = bdnode_test bdnode_multitest1 bdnode_test2
MANUAL_TESTS =
all: tests $(MANUAL_TESTS)
bdmsgs_test: bdmsgs_test.o
$(CC) $(CFLAGS) -o bdmsgs_test bdmsgs_test.o $(LIBS)
bdmetric_test: bdmetric_test.o
$(CC) $(CFLAGS) -o bdmetric_test bdmetric_test.o $(LIBS)
bdquery_test: bdquery_test.o
$(CC) $(CFLAGS) -o bdquery_test bdquery_test.o $(LIBS)
bdspace_test: bdspace_test.o
$(CC) $(CFLAGS) -o bdspace_test bdspace_test.o $(LIBS)
bdspace_test2: bdspace_test2.o
$(CC) $(CFLAGS) -o bdspace_test2 bdspace_test2.o $(LIBS)
bdnode_test: bdnode_test.o
$(CC) $(CFLAGS) -o bdnode_test bdnode_test.o $(LIBS)
bdnode_test2: bdnode_test2.o
$(CC) $(CFLAGS) -o bdnode_test2 bdnode_test2.o $(LIBS)
bdmidids_test: bdmidids_test.o
$(CC) $(CFLAGS) -o bdmidids_test bdmidids_test.o $(LIBS)
bdnode_multitest1: bdnode_multitest1.o
$(CC) $(CFLAGS) -o bdnode_multitest1 bdnode_multitest1.o $(LIBS)
bdmgr_multitest: bdmgr_multitest.o
$(CC) $(CFLAGS) -o bdmgr_multitest bdmgr_multitest.o $(LIBS)
bdstore_test: bdstore_test.o
$(CC) $(CFLAGS) -o bdstore_test bdstore_test.o $(LIBS)
bdudp_test: bdudp_test.o
$(CC) $(CFLAGS) -o bdudp_test bdudp_test.o $(LIBS)
udpbitdht_nettest: udpbitdht_nettest.o
$(CC) $(CFLAGS) -o udpbitdht_nettest udpbitdht_nettest.o $(LIBS)
bencode_test: bencode_test.o
$(CC) $(CFLAGS) -o bencode_test bencode_test.o $(LIBS)
bdbloom_test: bdbloom_test.o
$(CC) $(CFLAGS) -o bdbloom_test bdbloom_test.o $(LIBS)
bdbloom_makefilter: bdbloom_makefilter.o
$(CC) $(CFLAGS) -o bdbloom_makefilter bdbloom_makefilter.o $(LIBS)
clobber: remove_extra_files
remove_extra_files:
-$(RM) $(MANUAL_TESTS)
###############################################################
include $(TEST_TOP_DIR)/scripts/rules.mk
###############################################################

View file

@ -32,6 +32,9 @@
#include <string.h>
#include <stdlib.h>
#include <time.h>
#ifndef WIN32
#include <sys/select.h>
#endif
/***
* #define UDP_ENABLE_BROADCAST 1

View file

@ -13,7 +13,7 @@ static bool auto_seed = bdRandom::seed( (time(NULL) + ((uint32_t) pthread_self()
#else
#ifdef __APPLE__
static bool auto_seed = bdRandom::seed( (time(NULL) + pthread_mach_thread_np(pthread_self())*0x1293fe + (getpid()^0x113ef76b))^0x18e34a12 ) ;
#elif defined(__FreeBSD__)
#elif defined(__FreeBSD__) || (__HAIKU__)
// since this is completely insecure anyway, just kludge for now
static bool auto_seed = bdRandom::seed(time(NULL));
#elif defined(__OpenBSD__)

View file

@ -0,0 +1,41 @@
#include "ApiPluginHandler.h"
namespace resource_api
{
ApiPluginHandler::ApiPluginHandler(StateTokenServer* statetokenserver, const RsPlugInInterfaces& ifaces)
{
for(int i = 0; i < ifaces.mPluginHandler->nbPlugins(); i++)
{
RsPlugin* plugin = ifaces.mPluginHandler->plugin(i);
// if plugin is not loaded, pointer is null
if(plugin == 0)
continue;
std::string entrypoint;
ResourceRouter* child = plugin->new_resource_api_handler(ifaces, statetokenserver, entrypoint);
if(child != 0)
{
mChildren.push_back(child);
if(isNameUsed(entrypoint))
{
std::cerr << "Cannot add plugin api entry point with name=" << entrypoint << ", becaus ethis name is already in use!" << std::endl;
}
else
{
std::cerr << "Added libresapi plugin with entrypoint " << entrypoint << std::endl;
addResourceHandler(entrypoint, child, &ResourceRouter::handleRequest);
}
}
}
}
ApiPluginHandler::~ApiPluginHandler()
{
for(std::vector<ResourceRouter*>::iterator vit = mChildren.begin(); vit != mChildren.end(); ++vit)
{
delete *vit;
}
mChildren.clear();
}
} // namespace resource_api

View file

@ -0,0 +1,20 @@
#pragma once
#include "ResourceRouter.h"
#include <retroshare/rsplugin.h>
namespace resource_api
{
// forwards all incoming requests to retroshare plugins
class ApiPluginHandler: public ResourceRouter
{
public:
ApiPluginHandler(StateTokenServer* statetokenserver, const RsPlugInInterfaces& ifaces);
virtual ~ApiPluginHandler();
private:
std::vector<ResourceRouter*> mChildren;
};
} // namespace resource_api

View file

@ -13,6 +13,8 @@
#include "JsonStream.h"
#include "StateTokenServer.h" // for the state token serialisers
#include "ApiPluginHandler.h"
/*
data types in json http://json.org/
string (utf-8 unicode)
@ -226,10 +228,11 @@ public:
mPeersHandler(sts, ifaces.mNotify, ifaces.mPeers, ifaces.mMsgs),
mIdentityHandler(ifaces.mIdentity),
mForumHandler(ifaces.mGxsForums),
mServiceControlHandler(rsServiceControl), // TODO: don't use global variable here
mServiceControlHandler(ifaces.mServiceControl),
mFileSearchHandler(sts, ifaces.mNotify, ifaces.mTurtle, ifaces.mFiles),
mTransfersHandler(sts, ifaces.mFiles),
mChatHandler(sts, ifaces.mNotify, ifaces.mMsgs, ifaces.mPeers, ifaces.mIdentity, &mPeersHandler)
mChatHandler(sts, ifaces.mNotify, ifaces.mMsgs, ifaces.mPeers, ifaces.mIdentity, &mPeersHandler),
mApiPluginHandler(sts, ifaces)
{
// the dynamic cast is to not confuse the addResourceHandler template like this:
// addResourceHandler(derived class, parent class)
@ -249,6 +252,8 @@ public:
&TransfersHandler::handleRequest);
router.addResourceHandler("chat", dynamic_cast<ResourceRouter*>(&mChatHandler),
&ChatHandler::handleRequest);
router.addResourceHandler("apiplugin", dynamic_cast<ResourceRouter*>(&mApiPluginHandler),
&ChatHandler::handleRequest);
}
PeersHandler mPeersHandler;
@ -258,6 +263,7 @@ public:
FileSearchHandler mFileSearchHandler;
TransfersHandler mTransfersHandler;
ChatHandler mChatHandler;
ApiPluginHandler mApiPluginHandler;
};
ApiServer::ApiServer():

View file

@ -7,6 +7,7 @@
#include <algorithm>
#include <util/rsdir.h>
#include "util/ContentTypes.h"
// for filestreamer
#include <retroshare/rsfiles.h>
@ -275,11 +276,20 @@ public:
sendMessage(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Error: rsFiles is null. Retroshare is probably not yet started.");
return MHD_YES;
}
if(url[0] == 0 || (mHash=RsFileHash(url+strlen(FILESTREAMER_ENTRY_PATH))).isNull())
std::string urls(url);
urls = urls.substr(strlen(FILESTREAMER_ENTRY_PATH));
size_t perpos = urls.find('/');
if(perpos == std::string::npos){
mHash = RsFileHash(urls);
}else{
mHash = RsFileHash(urls.substr(0, perpos));
}
if(urls.empty() || mHash.isNull())
{
sendMessage(connection, MHD_HTTP_NOT_FOUND, "Error: URL is not a valid file hash");
return MHD_YES;
}
FileInfo info;
std::list<RsFileHash> dls;
rsFiles->FileDownloads(dls);
@ -293,8 +303,13 @@ public:
struct MHD_Response* resp = MHD_create_response_from_callback(
mSize, 1024*1024, &contentReadercallback, this, NULL);
// only mp3 at the moment
MHD_add_response_header(resp, "Content-Type", "audio/mpeg3");
// get content-type from extension
std::string ext = "";
unsigned int i = info.fname.rfind('.');
if(i != std::string::npos)
ext = info.fname.substr(i+1);
MHD_add_response_header(resp, "Content-Type", ContentTypes::cTypeFromExt(ext).c_str());
secure_queue_response(connection, MHD_HTTP_OK, resp);
MHD_destroy_response(resp);
return MHD_YES;
@ -635,27 +650,10 @@ int ApiServerMHD::accessHandlerCallback(MHD_Connection *connection,
{
extension = filename[i] + extension;
i--;
}
const char* type = 0;
if(extension == "html")
type = "text/html";
else if(extension == "css")
type = "text/css";
else if(extension == "js")
type = "text/javascript";
else if(extension == "jsx") // react.js jsx files
type = "text/jsx";
else if(extension == "png")
type = "image/png";
else if(extension == "jpg" || extension == "jpeg")
type = "image/jpeg";
else if(extension == "gif")
type = "image/gif";
else
type = "application/octet-stream";
};
struct MHD_Response* resp = MHD_create_response_from_fd(s.st_size, fd);
MHD_add_response_header(resp, "Content-Type", type);
MHD_add_response_header(resp, "Content-Type", ContentTypes::cTypeFromExt(extension).c_str());
secure_queue_response(connection, MHD_HTTP_OK, resp);
MHD_destroy_response(resp);
return MHD_YES;

View file

@ -42,6 +42,12 @@ StreamBase& operator << (StreamBase& left, ChatHandler::Msg& m)
bool compare_lobby_id(const ChatHandler::Lobby& l1, const ChatHandler::Lobby& l2)
{
if(l1.auto_subscribe && !l2.auto_subscribe) return true;
if(!l1.auto_subscribe && l2.auto_subscribe) return false;
if(l1.is_private && !l2.is_private) return true;
if(!l1.is_private && l2.is_private) return false;
if(l1.subscribed && !l2.subscribed) return true;
if(!l1.subscribed && l2.subscribed) return false;
return l1.id < l2.id;
}
@ -65,13 +71,17 @@ StreamBase& operator <<(StreamBase& left, KeyValueReference<ChatLobbyId> kv)
StreamBase& operator << (StreamBase& left, ChatHandler::Lobby& l)
{
ChatId chatId(l.id);
if (l.is_broadcast)
chatId = ChatId::makeBroadcastId();
left << makeKeyValueReference("id", l.id)
<< makeKeyValue("chat_id", ChatId(l.id).toStdString())
<< makeKeyValue("chat_id", chatId.toStdString())
<< makeKeyValueReference("name",l.name)
<< makeKeyValueReference("topic", l.topic)
<< makeKeyValueReference("subscribed", l.subscribed)
<< makeKeyValueReference("auto_subscribe", l.auto_subscribe)
<< makeKeyValueReference("is_private", l.is_private)
<< makeKeyValueReference("is_broadcast", l.is_broadcast)
<< makeKeyValueReference("gxs_id", l.gxs_id);
return left;
}
@ -81,7 +91,7 @@ StreamBase& operator << (StreamBase& left, ChatHandler::ChatInfo& info)
left << makeKeyValueReference("remote_author_id", info.remote_author_id)
<< makeKeyValueReference("remote_author_name", info.remote_author_name)
<< makeKeyValueReference("is_broadcast", info.is_broadcast)
<< makeKeyValueReference("is_gxs_id", info.is_gxs_id)
<< makeKeyValueReference("is_distant_chat_id", info.is_distant_chat_id)
<< makeKeyValueReference("is_lobby", info.is_lobby)
<< makeKeyValueReference("is_peer", info.is_peer);
return left;
@ -157,11 +167,23 @@ void ChatHandler::tick()
l.subscribed = true;
l.auto_subscribe = info.lobby_flags & RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE;
l.is_private = !(info.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC);
l.is_broadcast = false;
l.gxs_id = info.gxs_id;
lobbies.push_back(l);
}
}
{
Lobby l;
l.name = "BroadCast";
l.topic = "Retroshare broadcast chat: messages are sent to all connected friends.";
l.subscribed = true;
l.auto_subscribe = false;
l.is_private = false;
l.is_broadcast = true;
lobbies.push_back(l);
}
std::vector<VisibleChatLobbyRecord> unsubscribed_lobbies;
mRsMsgs->getListOfNearbyChatLobbies(unsubscribed_lobbies);
for(std::vector<VisibleChatLobbyRecord>::iterator vit = unsubscribed_lobbies.begin(); vit != unsubscribed_lobbies.end(); ++vit)
@ -176,6 +198,7 @@ void ChatHandler::tick()
l.subscribed = false;
l.auto_subscribe = info.lobby_flags & RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE;
l.is_private = !(info.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC);
l.is_broadcast = false;
l.gxs_id = RsGxsId();
lobbies.push_back(l);
}
@ -199,12 +222,20 @@ void ChatHandler::tick()
author_id = msg.broadcast_peer_id.toStdString();
author_name = mRsPeers->getPeerName(msg.broadcast_peer_id);
}
else if(msg.chat_id.isGxsId())
else if(msg.chat_id.isDistantChatId())
{
author_id = msg.chat_id.toGxsId().toStdString();
DistantChatPeerInfo dcpinfo ;
if(!rsMsgs->getDistantChatStatus(msg.chat_id.toDistantChatId(),dcpinfo))
{
std::cerr << "(EE) cannot get info for distant chat peer " << msg.chat_id.toDistantChatId() << std::endl;
continue ;
}
RsIdentityDetails details;
if(!gxs_id_failed && mRsIdentity->getIdDetails(msg.chat_id.toGxsId(), details))
if(!gxs_id_failed && mRsIdentity->getIdDetails(msg.incoming? dcpinfo.to_id: dcpinfo.own_id, details))
{
author_id = details.mId.toStdString();
author_name = details.mNickname;
}
else
@ -252,7 +283,7 @@ void ChatHandler::tick()
{
ChatInfo info;
info.is_broadcast = msg.chat_id.isBroadcast();
info.is_gxs_id = msg.chat_id.isGxsId();
info.is_distant_chat_id = msg.chat_id.isDistantChatId();
info.is_lobby = msg.chat_id.isLobbyId();
info.is_peer = msg.chat_id.isPeerId();
if(msg.chat_id.isLobbyId())
@ -263,12 +294,15 @@ void ChatHandler::tick()
info.remote_author_name = vit->name;
}
}
else if(msg.chat_id.isGxsId())
else if(msg.chat_id.isDistantChatId())
{
RsIdentityDetails details;
if(!gxs_id_failed && mRsIdentity->getIdDetails(msg.chat_id.toGxsId(), details))
DistantChatPeerInfo dcpinfo ;
if(!gxs_id_failed && rsMsgs->getDistantChatStatus(msg.chat_id.toDistantChatId(),dcpinfo)
&& mRsIdentity->getIdDetails(msg.incoming? dcpinfo.to_id: dcpinfo.own_id, details))
{
info.remote_author_id = msg.chat_id.toGxsId().toStdString();
info.remote_author_id = details.mId.toStdString();
info.remote_author_name = details.mNickname;
}
else
@ -294,62 +328,7 @@ void ChatHandler::tick()
// remove html tags from chat message
// extract links form href
const std::string& in = msg.msg;
std::string out;
bool ignore = false;
bool keep_link = false;
std::string last_six_chars;
Triple current_link;
std::vector<Triple> links;
for(unsigned int i = 0; i < in.size(); ++i)
{
if(keep_link && in[i] == '"')
{
keep_link = false;
current_link.second = out.size();
}
if(last_six_chars == "href=\"")
{
keep_link = true;
current_link.first = out.size();
}
// "rising edge" sets mode to ignore
if(in[i] == '<')
{
ignore = true;
}
if(!ignore || keep_link)
out += in[i];
// "falling edge" resets mode to keep
if(in[i] == '>')
ignore = false;
last_six_chars += in[i];
if(last_six_chars.size() > 6)
last_six_chars = last_six_chars.substr(1);
std::string a = "</a>";
if( current_link.first != -1
&& last_six_chars.size() >= a.size()
&& last_six_chars.substr(last_six_chars.size()-a.size()) == a)
{
// only allow these protocols
// we don't want for example javascript:alert(0)
std::string http = "http://";
std::string https = "https://";
std::string retroshare = "retroshare://";
if( out.substr(current_link.first, http.size()) == http
|| out.substr(current_link.first, https.size()) == https
|| out.substr(current_link.first, retroshare.size()) == retroshare)
{
current_link.third = out.size();
links.push_back(current_link);
}
current_link = Triple();
}
}
m.msg = out;
m.links = links;
getPlainText(msg.msg, m.msg, m.links);
m.recv_time = msg.recvTime;
m.send_time = msg.sendTime;
@ -390,7 +369,77 @@ void ChatHandler::tick()
}
}
void ChatHandler::handleWildcard(Request &req, Response &resp)
void ChatHandler::getPlainText(const std::string& in, std::string &out, std::vector<Triple> &links)
{
if (in.size() == 0)
return;
if (in[0] != '<' || in[in.size() - 1] != '>')
{
// It's a plain text message without HTML
out = in;
return;
}
bool ignore = false;
bool keep_link = false;
std::string last_six_chars;
unsigned int tag_start_index = 0;
Triple current_link;
for(unsigned int i = 0; i < in.size(); ++i)
{
if(keep_link && in[i] == '"')
{
keep_link = false;
current_link.second = out.size();
}
if(last_six_chars == "href=\"")
{
keep_link = true;
current_link.first = out.size();
}
// "rising edge" sets mode to ignore
if(in[i] == '<')
{
tag_start_index = i;
ignore = true;
}
if(!ignore || keep_link)
out += in[i];
// "falling edge" resets mode to keep
if(in[i] == '>') {
// leave ignore mode on, if it's a style tag
if (tag_start_index == 0 || tag_start_index + 6 > i || in.substr(tag_start_index, 6) != "<style")
ignore = false;
}
last_six_chars += in[i];
if(last_six_chars.size() > 6)
last_six_chars = last_six_chars.substr(1);
std::string a = "</a>";
if( current_link.first != -1
&& last_six_chars.size() >= a.size()
&& last_six_chars.substr(last_six_chars.size()-a.size()) == a)
{
// only allow these protocols
// we don't want for example javascript:alert(0)
std::string http = "http://";
std::string https = "https://";
std::string retroshare = "retroshare://";
if( out.substr(current_link.first, http.size()) == http
|| out.substr(current_link.first, https.size()) == https
|| out.substr(current_link.first, retroshare.size()) == retroshare)
{
current_link.third = out.size();
links.push_back(current_link);
}
current_link = Triple();
}
}
}
void ChatHandler::handleWildcard(Request &/*req*/, Response &resp)
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
resp.mDataStream.getStreamToMember();
@ -447,7 +496,7 @@ void ChatHandler::handleSubscribeLobby(Request &req, Response &resp)
resp.setFail("lobby join failed. (See console for more info)");
}
void ChatHandler::handleUnsubscribeLobby(Request &req, Response &resp)
void ChatHandler::handleUnsubscribeLobby(Request &req, Response &/*resp*/)
{
ChatLobbyId id = 0;
req.mStream << makeKeyValueReference("id", id);
@ -626,17 +675,17 @@ void ChatHandler::handleInfo(Request &req, Response &resp)
resp.setOk();
}
void ChatHandler::handleTypingLabel(Request &req, Response &resp)
void ChatHandler::handleTypingLabel(Request &/*req*/, Response &/*resp*/)
{
}
void ChatHandler::handleSendStatus(Request &req, Response &resp)
void ChatHandler::handleSendStatus(Request &/*req*/, Response &/*resp*/)
{
}
void ChatHandler::handleUnreadMsgs(Request &req, Response &resp)
void ChatHandler::handleUnreadMsgs(Request &/*req*/, Response &resp)
{
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/

View file

@ -57,13 +57,14 @@ public:
class Lobby{
public:
Lobby(): id(0), subscribed(false), auto_subscribe(false), is_private(false){}
Lobby(): id(0), subscribed(false), auto_subscribe(false), is_private(false), is_broadcast(false){}
ChatLobbyId id;
std::string name;
std::string topic;
bool subscribed;
bool auto_subscribe;
bool is_private;
bool is_broadcast;
RsGxsId gxs_id;// for subscribed lobbies: the id we use to write messages
@ -75,6 +76,7 @@ public:
&& subscribed == l.subscribed
&& auto_subscribe == l.auto_subscribe
&& is_private == l.is_private
&& is_broadcast == l.is_broadcast
&& gxs_id == l.gxs_id;
}
};
@ -82,7 +84,7 @@ public:
class ChatInfo{
public:
bool is_broadcast;
bool is_gxs_id;
bool is_distant_chat_id;
bool is_lobby;
bool is_peer;
std::string remote_author_id;
@ -102,6 +104,8 @@ private:
void handleSendStatus(Request& req, Response& resp);
void handleUnreadMsgs(Request& req, Response& resp);
void getPlainText(const std::string& in, std::string &out, std::vector<Triple> &links);
StateTokenServer* mStateTokenServer;
RsNotify* mNotify;
RsMsgs* mRsMsgs;

View file

@ -7,6 +7,7 @@
#include <retroshare/rsdisc.h>
#include <retroshare/rsdht.h>
#include <retroshare/rsnotify.h>
#include <retroshare/rsservicecontrol.h>
#include <retroshare/rsidentity.h>
#include <retroshare/rsgxscircles.h>
@ -28,6 +29,8 @@ bool getPluginInterfaces(RsPlugInInterfaces& interfaces)
interfaces.mDisc = rsDisc;
interfaces.mDht = rsDht;
interfaces.mNotify = rsNotify;
interfaces.mServiceControl = rsServiceControl;
interfaces.mPluginHandler = rsPlugins;
// gxs
interfaces.mGxsDir = "";

View file

@ -103,10 +103,8 @@ void GxsResponseTask::streamGxsId(RsGxsId id, StreamBase &stream)
{
stream << makeKeyValueReference("id", id)
<< makeKeyValueReference("gxs_id", id)
<< makeKeyValueReference("is_own", vit->mIsOwnId)
<< makeKeyValueReference("name", vit->mNickname)
<< makeKeyValueReference("pgp_linked", vit->mPgpLinked)
<< makeKeyValueReference("pgp_known", vit->mPgpKnown);
<< makeKeyValueReference("flags", vit->mFlags)
<< makeKeyValueReference("name", vit->mNickname);
return;
}
}

View file

@ -14,9 +14,9 @@ StreamBase& operator <<(StreamBase& left, KeyValueReference<uint32_t> ref)
{
digit = num % 10;
num = num / 10;
str += (char)(digit + '0');
str = (char)(digit + '0') + str;
}
str += (char)(num + '0');
str = (char)(num + '0') + str;
left << makeKeyValueReference(ref.key, str);
}
else

View file

@ -55,4 +55,17 @@ ResponseTask* ResourceRouter::handleRequest(Request& req, Response& resp)
return 0;
}
bool ResourceRouter::isNameUsed(std::string name)
{
std::vector<std::pair<std::string, HandlerBase*> >::iterator vit;
for(vit = mHandlers.begin(); vit != mHandlers.end(); vit++)
{
if(vit->first == name)
{
return true;
}
}
return false;
}
} // namespace resource_api

View file

@ -1,6 +1,7 @@
#pragma once
#include "ApiTypes.h"
#include <iostream>
namespace resource_api
{
@ -20,6 +21,8 @@ public:
void addResourceHandler(std::string name, T* instance, ResponseTask* (T::*callback)(Request& req, Response& resp));
template <class T>
void addResourceHandler(std::string name, T* instance, void (T::*callback)(Request& req, Response& resp));
bool isNameUsed(std::string name);
private:
class HandlerBase
{
@ -61,6 +64,10 @@ private:
template <class T>
void ResourceRouter::addResourceHandler(std::string name, T* instance, ResponseTask* (T::*callback)(Request& req, Response& resp))
{
if(isNameUsed(name))
{
std::cerr << "ResourceRouter::addResourceHandler ERROR: name=" << name << " alerady in use. Not adding new Handler!" << std::endl;
}
Handler<T>* handler = new Handler<T>();
handler->instance = instance;
handler->method = callback;
@ -69,6 +76,10 @@ void ResourceRouter::addResourceHandler(std::string name, T* instance, ResponseT
template <class T>
void ResourceRouter::addResourceHandler(std::string name, T* instance, void (T::*callback)(Request& req, Response& resp))
{
if(isNameUsed(name))
{
std::cerr << "ResourceRouter::addResourceHandler ERROR: name=" << name << " alerady in use. Not adding new Handler!" << std::endl;
}
InstantResponseHandler<T>* handler = new InstantResponseHandler<T>();
handler->instance = instance;
handler->method = callback;

View file

@ -408,7 +408,7 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp)
std::string err_string;
if(!RsAccounts::GeneratePGPCertificate(pgp_name, "", pgp_password, pgp_id, 2048, err_string))
{
resp.setFail("could not cerate pgp key: "+err_string);
resp.setFail("could not create pgp key: "+err_string);
return;
}
}

View file

@ -2,8 +2,10 @@
TEMPLATE = lib
CONFIG += staticlib
CONFIG += create_prl
CONFIG -= qt
TARGET = resapi
TARGET_PRL = libresapi
DESTDIR = lib
CONFIG += libmicrohttpd
@ -22,10 +24,21 @@ unix {
win32{
DEFINES *= WINDOWS_SYS
INCLUDEPATH += $$PWD/../../../libs/include
INCLUDEPATH += . $$INC_DIR
}
libmicrohttpd{
linux {
CONFIG += link_pkgconfig
PKGCONFIG *= libmicrohttpd
} else {
mac {
INCLUDEPATH += . $$INC_DIR
for(lib, LIB_DIR):exists($$lib/libmicrohttpd.a){ LIBS *= $$lib/libmicrohttpd.a}
} else {
LIBS *= -lmicrohttpd
}
}
SOURCES += \
api/ApiServerMHD.cpp
@ -51,7 +64,9 @@ SOURCES += \
api/GetPluginInterfaces.cpp \
api/ChatHandler.cpp \
api/LivereloadHandler.cpp \
api/TmpBlobStore.cpp
api/TmpBlobStore.cpp \
util/ContentTypes.cpp \
api/ApiPluginHandler.cpp
HEADERS += \
api/ApiServer.h \
@ -74,4 +89,6 @@ HEADERS += \
api/GetPluginInterfaces.h \
api/ChatHandler.h \
api/LivereloadHandler.h \
api/TmpBlobStore.h
api/TmpBlobStore.h \
util/ContentTypes.h \
api/ApiPluginHandler.h

View file

@ -0,0 +1,88 @@
#include "ContentTypes.h"
#include <fstream>
#include <cctype>
#include <algorithm>
RsMutex ContentTypes::ctmtx = RsMutex("CTMTX");
std::map<std::string, std::string> ContentTypes::cache;
bool ContentTypes::inited = false;
#ifdef WINDOWS_SYS
//Next to the executable
const char* ContentTypes::filename = ".\\mime.types";
#else
const char* ContentTypes::filename = "/etc/mime.types";
#endif
std::string ContentTypes::cTypeFromExt(const std::string &extension)
{
if(extension.empty())
return DEFAULTCT;
RsStackMutex mtx(ctmtx);
if(!inited)
addBasic();
std::string extension2(extension); //lower case
std::transform(extension2.begin(), extension2.end(), extension2.begin(),::tolower);
//looking into the cache
std::map<std::string,std::string>::iterator it;
it = cache.find(extension2);
if (it != cache.end())
{
std::cout << "Mime " + it->second + " for extension ." + extension2 + " was found in cache" << std::endl;
return it->second;
}
//looking into mime.types
std::string line;
std::string ext;
std::ifstream file(filename);
while(getline(file, line))
{
if(line.empty() || line[0] == '#') continue;
size_t i = line.find_first_of("\t ");
size_t j;
while(i != std::string::npos) //tokenize
{
j = i;
i = line.find_first_of("\t ", i+1);
if(i == std::string::npos)
ext = line.substr(j+1);
else
ext = line.substr(j+1, i-j-1);
if(extension2 == ext)
{
std::string mime = line.substr(0, line.find_first_of("\t "));
cache[extension2] = mime;
std::cout << "Mime " + mime + " for extension ." + extension2 + " was found in mime.types" << std::endl;
return mime;
}
}
}
//nothing found
std::cout << "Mime for " + extension2 + " was not found in " + filename + " falling back to " << DEFAULTCT << std::endl;
cache[extension2] = DEFAULTCT;
return DEFAULTCT;
}
//Add some basic content-types before first use.
//It keeps webui usable in the case of mime.types file not exists.
void ContentTypes::addBasic()
{
inited = true;
cache["html"] = "text/html";
cache["css"] = "text/css";
cache["js"] = "text/javascript";
cache["jsx"] = "text/jsx";
cache["png"] = "image/png";
cache["jpg"] = "image/jpeg";
cache["jpeg"] = "image/jpeg";
cache["gif"] = "image/gif";
}

View file

@ -0,0 +1,23 @@
#ifndef CONTENTTYPES_H
#define CONTENTTYPES_H
#include <util/rsthreads.h>
#include <map>
#include <string>
#define DEFAULTCT "application/octet-stream"
class ContentTypes
{
public:
static std::string cTypeFromExt(const std::string& extension);
private:
static std::map<std::string, std::string> cache;
static RsMutex ctmtx;
static const char* filename;
static bool inited;
static void addBasic();
};
#endif // CONTENTTYPES_H

View file

@ -66,6 +66,10 @@ td{
background-color: midnightblue;
}
.filelink{
color: inherit;
}
input, textarea{
color: lime;
font-family: monospace;

View file

@ -4,7 +4,15 @@ RS.start();
var api_url = window.location.protocol + "//" + window.location.hostname + ":" + window.location.port + "/api/v2/";
var filestreamer_url = window.location.protocol + "//" +window.location.hostname + ":" + window.location.port + "/fstream/";
var upload_url = window.location.protocol + "//" +window.location.hostname + ":" + window.location.port + "/upload/";
var upload_url = window.location.protocol + "//" + window.location.hostname + ":" + window.location.port + "/upload/";
var extensions = {
mp3: "audio",
ogg: "audio",
wav: "audio",
webm: "video",
mp4: "video"
};
// livereload
function start_live_reload()
@ -558,7 +566,8 @@ var DownloadsWidget = React.createClass({
widget.emit("play_file", {name: file.name, hash: file.hash})
};
var playBtn = <div></div>;
if(file.name.slice(-3) === "mp3")
var splits = file.name.split(".");
if(splits[splits.length-1].toLowerCase() in extensions)
playBtn = <div className="btn" onClick={playFn}>play</div>;
var ctrlBtn = <div></div>;
@ -571,7 +580,7 @@ var DownloadsWidget = React.createClass({
ctrlBtn = <div className="btn" onClick={pauseFn}>pause</div>;
}
return(<tr>
<td>{this.props.data.name}</td>
<td><a className="filelink" target="_blank" href={filestreamer_url + this.props.data.hash + "/" + encodeURIComponent(this.props.data.name)}>{this.props.data.name}</a></td>
<td>{makeFriendlyUnit(this.props.data.size)}</td>
<td><ProgressBar progress={this.props.data.transfered / this.props.data.size}/></td>
<td>{makeFriendlyUnit(this.props.data.transfer_rate*1e3)}/s</td>
@ -673,7 +682,7 @@ var SearchWidget = React.createClass({
},
});
var AudioPlayerWidget = React.createClass({
var MediaPlayerWidget = React.createClass({
mixins: [SignalSlotMixin],
getInitialState: function(){
return {file: undefined};
@ -691,13 +700,28 @@ var AudioPlayerWidget = React.createClass({
}
else
{
return(
var splits = this.state.file.name.split(".");
var mediatype = extensions[splits[splits.length - 1].toLowerCase()];
if (mediatype == "audio") {
return (
<div>
<p>{this.state.file.name}</p>
<audio controls src={filestreamer_url+this.state.file.hash} type="audio/mpeg">
<audio controls autoPlay src={filestreamer_url+this.state.file.hash}>
</audio>
</div>
);
} else if (mediatype == "video") {
return(
<div>
<p>{this.state.file.name}</p>
<video height="300" controls autoPlay src={filestreamer_url+this.state.file.hash}>
Your browser does not support the video tag.
</video>
</div>
);
} else {
return(<div></div>);
}
}
},
});
@ -1467,7 +1491,7 @@ var ChatWidget = React.createClass({
<ChatInfoWidget id={this.props.id}/>
{
this.state.data.map(function(msg){
return <div key={msg.id}>{msg.send_time} {msg.author_name}: {markup(msg.msg, msg.links)}</div>;
return <div key={msg.id}>{new Date(msg.send_time*1000).toLocaleTimeString()} {msg.author_name}: {markup(msg.msg, msg.links)}</div>;
})
}
<input type="text" ref="input" onKeyDown={
@ -1702,7 +1726,7 @@ var MainWidget = React.createClass({
}
mainpage = <div>
<UnreadChatMsgsCountWidget/>
<AudioPlayerWidget/>
<MediaPlayerWidget/>
<IdentitySelectorWidget/>
{mainpage}
</div>;

View file

@ -66,6 +66,10 @@ td{
background-color: midnightblue;
}
.filelink{
color: inherit;
}
input, textarea{
color: lime;
font-family: monospace;

View file

@ -4,7 +4,15 @@ RS.start();
var api_url = window.location.protocol + "//" + window.location.hostname + ":" + window.location.port + "/api/v2/";
var filestreamer_url = window.location.protocol + "//" +window.location.hostname + ":" + window.location.port + "/fstream/";
var upload_url = window.location.protocol + "//" +window.location.hostname + ":" + window.location.port + "/upload/";
var upload_url = window.location.protocol + "//" + window.location.hostname + ":" + window.location.port + "/upload/";
var extensions = {
mp3: "audio",
ogg: "audio",
wav: "audio",
webm: "video",
mp4: "video"
};
// livereload
function start_live_reload()
@ -558,7 +566,8 @@ var DownloadsWidget = React.createClass({
widget.emit("play_file", {name: file.name, hash: file.hash})
};
var playBtn = <div></div>;
if(file.name.slice(-3) === "mp3")
var splits = file.name.split(".");
if(splits[splits.length-1].toLowerCase() in extensions)
playBtn = <div className="btn" onClick={playFn}>play</div>;
var ctrlBtn = <div></div>;
@ -571,7 +580,7 @@ var DownloadsWidget = React.createClass({
ctrlBtn = <div className="btn" onClick={pauseFn}>pause</div>;
}
return(<tr>
<td>{this.props.data.name}</td>
<td><a className="filelink" target="_blank" href={filestreamer_url + this.props.data.hash + "/" + encodeURIComponent(this.props.data.name)}>{this.props.data.name}</a></td>
<td>{makeFriendlyUnit(this.props.data.size)}</td>
<td><ProgressBar progress={this.props.data.transfered / this.props.data.size}/></td>
<td>{makeFriendlyUnit(this.props.data.transfer_rate*1e3)}/s</td>
@ -673,7 +682,7 @@ var SearchWidget = React.createClass({
},
});
var AudioPlayerWidget = React.createClass({
var MediaPlayerWidget = React.createClass({
mixins: [SignalSlotMixin],
getInitialState: function(){
return {file: undefined};
@ -691,13 +700,28 @@ var AudioPlayerWidget = React.createClass({
}
else
{
return(
var splits = this.state.file.name.split(".");
var mediatype = extensions[splits[splits.length - 1].toLowerCase()];
if (mediatype == "audio") {
return (
<div>
<p>{this.state.file.name}</p>
<audio controls src={filestreamer_url+this.state.file.hash} type="audio/mpeg">
<audio controls autoPlay src={filestreamer_url+this.state.file.hash}>
</audio>
</div>
);
} else if (mediatype == "video") {
return(
<div>
<p>{this.state.file.name}</p>
<video height="300" controls autoPlay src={filestreamer_url+this.state.file.hash}>
Your browser does not support the video tag.
</video>
</div>
);
} else {
return(<div></div>);
}
}
},
});
@ -1467,7 +1491,7 @@ var ChatWidget = React.createClass({
<ChatInfoWidget id={this.props.id}/>
{
this.state.data.map(function(msg){
return <div key={msg.id}>{msg.send_time} {msg.author_name}: {markup(msg.msg, msg.links)}</div>;
return <div key={msg.id}>{new Date(msg.send_time*1000).toLocaleTimeString()} {msg.author_name}: {markup(msg.msg, msg.links)}</div>;
})
}
<input type="text" ref="input" onKeyDown={
@ -1702,7 +1726,7 @@ var MainWidget = React.createClass({
}
mainpage = <div>
<UnreadChatMsgsCountWidget/>
<AudioPlayerWidget/>
<MediaPlayerWidget/>
<IdentitySelectorWidget/>
{mainpage}
</div>;

File diff suppressed because it is too large Load diff

View file

@ -25,35 +25,43 @@
#pragma once
#include <turtle/turtleclientservice.h>
#include <chat/rschatitems.h>
#include <retroshare/rsmsgs.h>
#include <retroshare/rsgxstunnel.h>
class RsGixs ;
static const uint32_t DISTANT_CHAT_AES_KEY_SIZE = 16 ;
class DistantChatService: public RsTurtleClientService
class DistantChatService: public RsGxsTunnelService::RsGxsTunnelClientService
{
public:
DistantChatService(RsGixs *pids)
: mGixs(pids), mDistantChatMtx("distant chat")
{
mTurtle = NULL ;
}
// So, public interface only uses DistandChatPeerId, but internally, this is converted into a RsGxsTunnelService::RsGxsTunnelId
void flush() ;
virtual void connectToTurtleRouter(p3turtle *) ;
DistantChatService() ;
virtual void triggerConfigSave()=0 ;
bool processLoadListItem(const RsItem *item) ;
void addToSaveList(std::list<RsItem*>& list) const;
// Creates the invite if the public key of the distant peer is available.
// Om success, stores the invite in the map above, so that we can respond to tunnel requests.
//
bool initiateDistantChatConnexion(const RsGxsId& to_gxs_id,const RsGxsId &from_gxs_id, uint32_t &error_code) ;
bool closeDistantChatConnexion(const RsGxsId& pid) ;
virtual bool getDistantChatStatus(const RsGxsId &gxs_id,uint32_t &status, RsGxsId *from_gxs_id=NULL) ;
bool initiateDistantChatConnexion(const RsGxsId& to_gxs_id, const RsGxsId &from_gxs_id, DistantChatPeerId& dcpid, uint32_t &error_code) ;
bool closeDistantChatConnexion(const DistantChatPeerId &tunnel_id) ;
// derived in p3ChatService
// Sets flags to only allow connexion from some people.
uint32_t getDistantChatPermissionFlags() ;
bool setDistantChatPermissionFlags(uint32_t flags) ;
// Returns the status of a distant chat contact. The contact is defined by the tunnel id (turned into a DistantChatPeerId) because
// each pair of talking GXS id needs to be treated separately
virtual bool getDistantChatStatus(const DistantChatPeerId &tunnel_id, DistantChatPeerInfo& cinfo) ;
// derived in p3ChatService, so as to pass down some info
virtual void handleIncomingItem(RsItem *) = 0;
virtual bool handleRecvChatMsgItem(RsChatMsgItem *ci)=0 ;
@ -62,78 +70,33 @@ public:
void handleRecvChatStatusItem(RsChatStatusItem *cs) ;
private:
class DistantChatPeerInfo
struct DistantChatContact
{
public:
DistantChatPeerInfo() : last_contact(0), last_keep_alive_sent(0), status(0), direction(0)
{
memset(aes_key, 0, DISTANT_CHAT_AES_KEY_SIZE);
}
time_t last_contact ; // used to keep track of working connexion
time_t last_keep_alive_sent ; // last time we sent a keep alive packet.
unsigned char aes_key[DISTANT_CHAT_AES_KEY_SIZE] ;
uint32_t status ; // info: do we have a tunnel ?
RsPeerId virtual_peer_id; // given by the turtle router. Identifies the tunnel.
RsGxsId own_gxs_id ; // gxs id we're using to talk.
RsTurtleGenericTunnelItem::Direction direction ; // specifiec wether we are client(managing the tunnel) or server.
RsGxsId from_id ;
RsGxsId to_id ;
};
class DistantChatDHInfo
{
public:
DistantChatDHInfo() : dh(0), direction(0), status(0) {}
DH *dh ;
RsGxsId gxs_id ;
RsTurtleGenericTunnelItem::Direction direction ;
uint32_t status ;
TurtleFileHash hash ;
};
// This maps contains the current peers to talk to with distant chat.
//
std::map<RsGxsId, DistantChatPeerInfo> _distant_chat_contacts ; // current peers we can talk to
std::map<RsPeerId,DistantChatDHInfo> _distant_chat_virtual_peer_ids ; // current virtual peers. Used to figure out tunnels, etc.
std::map<DistantChatPeerId, DistantChatContact> mDistantChatContacts ; // current peers we can talk to
// List of items to be sent asap. Used to store items that we cannot pass directly to
// sendTurtleData(), because of Mutex protection.
// Permission handling
std::list<RsChatItem*> pendingDistantChatItems ;
uint32_t mDistantChatPermissions ;
// Overloaded from RsTurtleClientService
// Overloaded from RsGxsTunnelClientService
virtual bool handleTunnelRequest(const RsFileHash &hash,const RsPeerId& peer_id) ;
virtual void receiveTurtleData(RsTurtleGenericTunnelItem *item,const RsFileHash& hash,const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction) ;
void addVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&,RsTurtleGenericTunnelItem::Direction dir) ;
void removeVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&) ;
void markDistantChatAsClosed(const RsGxsId &gxs_id) ;
void startClientDistantChatConnection(const RsGxsId &to_gxs_id,const RsGxsId& from_gxs_id) ;
void locked_restartDHSession(const RsPeerId &virtual_peer_id, const RsGxsId &own_gxs_id) ;
public:
virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) ;
//bool getHashFromVirtualPeerId(const TurtleVirtualPeerId& pid,RsFileHash& hash) ;
private:
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelService::RsGxsTunnelId& tunnel_id) ;
virtual void notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId& tunnel_id,uint32_t tunnel_status) ;
virtual void receiveData(const RsGxsTunnelService::RsGxsTunnelId& id,unsigned char *data,uint32_t data_size) ;
static TurtleFileHash hashFromGxsId(const RsGxsId& destination) ;
static RsGxsId gxsIdFromHash(const TurtleFileHash& sum) ;
// Utility functions.
void handleRecvDHPublicKey(RsChatDHPublicKeyItem *item) ;
bool locked_sendDHPublicKey(const DH *dh, const RsGxsId &own_gxs_id, const RsPeerId &virtual_peer_id) ;
bool locked_initDHSessionKey(DH *&dh);
DistantChatPeerId virtualPeerIdFromHash(const TurtleFileHash& hash ) ; // ... and to a hash for p3turtle
// Utility functions
void sendTurtleData(RsChatItem *) ;
void sendEncryptedTurtleData(const uint8_t *buff,uint32_t rssize,const RsGxsId &gxs_id) ;
bool handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id) ;
static TurtleFileHash hashFromVirtualPeerId(const DistantChatPeerId& peerId) ; // converts IDs so that we can talk to RsPeerId from outside
p3turtle *mTurtle ;
RsGixs *mGixs ;
void markDistantChatAsClosed(const DistantChatPeerId& dcpid) ;
RsGxsTunnelService *mGxsTunnels ;
RsMutex mDistantChatMtx ;
};

View file

@ -34,6 +34,7 @@
#include "pqi/p3historymgr.h"
#include "retroshare/rspeers.h"
#include "retroshare/rsiface.h"
#include "retroshare/rsreputations.h"
#include "retroshare/rsidentity.h"
#include "rsserver/p3face.h"
#include "gxs/rsgixs.h"
@ -168,13 +169,27 @@ bool DistributedChatService::handleRecvChatLobbyMsgItem(RsChatMsgItem *ci)
{
RsIdentityDetails details;
if(!rsIdentity->getIdDetails(cli->signature.keyId,details) || !details.mPgpKnown)
if(!rsIdentity->getIdDetails(cli->signature.keyId,details))
{
#ifdef DEBUG_CHAT_LOBBIES
std::cerr << "(WW) cannot get ID " << cli->signature.keyId << " for checking signature of lobby item." << std::endl;
#endif
return false;
}
if(!(details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED))
{
std::cerr << "(WW) Received a lobby msg/item that is not PGP-authed (id=" << cli->signature.keyId << "), whereas the lobby flags require it. Rejecting!" << std::endl;
return false ;
}
}
if(rsReputations->isIdentityBanned(cli->signature.keyId))
{
std::cerr << "(WW) Received lobby msg/item from banned identity " << cli->signature.keyId << ". Dropping it." << std::endl;
return false ;
}
if(!bounceLobbyObject(cli,cli->PeerId())) // forwards the message to friends, keeps track of subscribers, etc.
return false;
@ -665,13 +680,26 @@ void DistributedChatService::handleRecvChatLobbyEventItem(RsChatLobbyEventItem *
{
RsIdentityDetails details;
if(!rsIdentity->getIdDetails(item->signature.keyId,details) || !details.mPgpKnown)
if(!rsIdentity->getIdDetails(item->signature.keyId,details))
{
#ifdef DEBUG_CHAT_LOBBIES
std::cerr << "(WW) cannot get ID " << item->signature.keyId << " for checking signature of lobby item." << std::endl;
#endif
return ;
}
if(!(details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED))
{
std::cerr << "(WW) Received a lobby msg/item that is not PGP-authed (ID=" << item->signature.keyId << "), whereas the lobby flags require it. Rejecting!" << std::endl;
return ;
}
}
if(rsReputations->isIdentityBanned(item->signature.keyId))
{
std::cerr << "(WW) Received lobby msg/item from banned identity " << item->signature.keyId << ". Dropping it." << std::endl;
return ;
}
addTimeShiftStatistics((int)now - (int)item->sendTime) ;
if(now+100 > (time_t) item->sendTime + MAX_KEEP_MSG_RECORD) // the message is older than the max cache keep minus 100 seconds ! It's too old, and is going to make an echo!
@ -1260,7 +1288,7 @@ void DistributedChatService::handleRecvLobbyInvite(RsChatLobbyInviteItem *item)
else
std::cerr << " : Match!" << std::endl;
std::cerr << " Addign new friend " << item->PeerId() << " to lobby." << std::endl;
std::cerr << " Adding new friend " << item->PeerId() << " to lobby." << std::endl;
#endif
it->second.participating_friends.insert(item->PeerId()) ;
@ -1699,7 +1727,7 @@ bool DistributedChatService::setIdentityForChatLobby(const ChatLobbyId& lobby_id
// Only send a nickname change event if the two Identities are not anonymous
if(rsIdentity->getIdDetails(nick,det1) && rsIdentity->getIdDetails(it->second.gxs_id,det2) && det1.mPgpLinked && det2.mPgpLinked)
if(rsIdentity->getIdDetails(nick,det1) && rsIdentity->getIdDetails(it->second.gxs_id,det2) && (det1.mFlags & det2.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED))
sendLobbyStatusPeerChangedNickname(lobby_id, nick.toStdString()) ;
}
@ -1870,7 +1898,6 @@ void DistributedChatService::addToSaveList(std::list<RsItem*>& list) const
bool DistributedChatService::processLoadListItem(const RsItem *item)
{
const RsConfigKeyValueSet *vitem = NULL ;
_default_identity.clear() ;
if(NULL != (vitem = dynamic_cast<const RsConfigKeyValueSet*>(item)))
for(std::list<RsTlvKeyValue>::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit)

View file

@ -54,7 +54,7 @@ static const uint32_t MAX_AVATAR_JPEG_SIZE = 32767; // Maximum size
// Images are 96x96, which makes approx. 27000 bytes uncompressed.
p3ChatService::p3ChatService(p3ServiceControl *sc,p3IdService *pids, p3LinkMgr *lm, p3HistoryMgr *historyMgr)
:DistantChatService(pids),DistributedChatService(getServiceInfo().mServiceType,sc,historyMgr,pids), mChatMtx("p3ChatService"),mServiceCtrl(sc), mLinkMgr(lm) , mHistoryMgr(historyMgr)
: DistributedChatService(getServiceInfo().mServiceType,sc,historyMgr,pids), mChatMtx("p3ChatService"),mServiceCtrl(sc), mLinkMgr(lm) , mHistoryMgr(historyMgr)
{
_serializer = new RsChatSerialiser() ;
@ -86,7 +86,7 @@ int p3ChatService::tick()
receiveChatQueue();
DistributedChatService::flush() ;
DistantChatService::flush() ;
//DistantChatService::flush() ;
return 0;
}
@ -217,17 +217,18 @@ void p3ChatService::sendStatusString(const ChatId& id , const std::string& statu
sendLobbyStatusString(id.toLobbyId(),status_string) ;
else if(id.isBroadcast())
sendGroupChatStatusString(status_string);
else if(id.isPeerId() || id.isGxsId())
else if(id.isPeerId() || id.isDistantChatId())
{
RsChatStatusItem *cs = new RsChatStatusItem ;
cs->status_string = status_string ;
cs->flags = RS_CHAT_FLAG_PRIVATE ;
RsPeerId vpid;
if(id.isGxsId())
vpid = RsPeerId(id.toGxsId());
if(id.isDistantChatId())
vpid = RsPeerId(id.toDistantChatId());
else
vpid = id.toPeerId();
cs->PeerId(vpid);
#ifdef CHAT_DEBUG
@ -285,9 +286,11 @@ void p3ChatService::checkSizeAndSendMessage(RsChatMsgItem *msg)
bool p3ChatService::isOnline(const RsPeerId& pid)
{
// check if the id is a tunnel id or a peer id.
uint32_t status ;
if(getDistantChatStatus(RsGxsId(pid),status))
return status == RS_DISTANT_CHAT_STATUS_CAN_TALK ;
DistantChatPeerInfo dcpinfo;
if(getDistantChatStatus(DistantChatPeerId(pid),dcpinfo))
return dcpinfo.status == RS_DISTANT_CHAT_STATUS_CAN_TALK ;
else
return mServiceCtrl->isPeerConnected(getServiceInfo().mServiceType, pid);
}
@ -301,7 +304,7 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg)
sendPublicChat(msg);
return true;
}
else if(destination.isPeerId()==false && destination.isGxsId()==false)
else if(destination.isPeerId()==false && destination.isDistantChatId()==false)
{
std::cerr << "p3ChatService::sendChat() Error: chat id type not handled. Is it empty?" << std::endl;
return false;
@ -313,8 +316,8 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg)
#endif
RsPeerId vpid;
if(destination.isGxsId())
vpid = RsPeerId(destination.toGxsId()); // convert to virtual peer id
if(destination.isDistantChatId())
vpid = RsPeerId(destination.toDistantChatId()); // convert to virtual peer id
else
vpid = destination.toPeerId();
@ -378,6 +381,11 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg)
#endif
RsServer::notify()->notifyChatMessage(message);
// cyril: history is temporarily diabled for distant chat, since we need to store the full tunnel ID, but then
// at loading time, the ID is not known so that chat window shows 00000000 as a peer.
if(!message.chat_id.isDistantChatId())
mHistoryMgr->addMessage(message);
checkSizeAndSendMessage(ci);
@ -497,11 +505,11 @@ void p3ChatService::handleIncomingItem(RsItem *item)
return ; // don't delete! It's handled by handleRecvChatMsgItem in some specific cases only.
}
if(DistantChatService::handleRecvItem(dynamic_cast<RsChatItem*>(item)))
{
delete item ;
return ;
}
// if(DistantChatService::handleRecvItem(dynamic_cast<RsChatItem*>(item)))
// {
// delete item ;
// return ;
// }
if(DistributedChatService::handleRecvItem(dynamic_cast<RsChatItem*>(item)))
{
@ -749,7 +757,13 @@ bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *ci)
cm.incoming = true;
cm.online = true;
RsServer::notify()->notifyChatMessage(cm);
// cyril: history is temporarily diabled for distant chat, since we need to store the full tunnel ID, but then
// at loading time, the ID is not known so that chat window shows 00000000 as a peer.
if(!cm.chat_id.isDistantChatId())
mHistoryMgr->addMessage(cm);
return true ;
}
@ -766,7 +780,7 @@ void p3ChatService::handleRecvChatStatusItem(RsChatStatusItem *cs)
std::cerr << "Received status string \"" << cs->status_string << "\"" << std::endl ;
#endif
uint32_t status;
DistantChatPeerInfo dcpinfo;
if(cs->flags & RS_CHAT_FLAG_REQUEST_CUSTOM_STATE) // no state here just a request.
sendCustomState(cs->PeerId()) ;
@ -782,9 +796,9 @@ void p3ChatService::handleRecvChatStatusItem(RsChatStatusItem *cs)
#endif
sendCustomStateRequest(cs->PeerId()) ;
}
else if(DistantChatService::getDistantChatStatus(RsGxsId(cs->PeerId()), status))
else if(DistantChatService::getDistantChatStatus(DistantChatPeerId(cs->PeerId()), dcpinfo))
{
RsServer::notify()->notifyChatStatus(ChatId(RsGxsId(cs->PeerId())), cs->status_string) ;
RsServer::notify()->notifyChatStatus(ChatId(DistantChatPeerId(cs->PeerId())), cs->status_string) ;
}
else if(cs->flags & RS_CHAT_FLAG_PRIVATE)
{
@ -816,9 +830,9 @@ void p3ChatService::initChatMessage(RsChatMsgItem *c, ChatMessage &m)
return;
}
uint32_t status;
if(DistantChatService::getDistantChatStatus(RsGxsId(c->PeerId()), status))
m.chat_id = ChatId(RsGxsId(c->PeerId()));
DistantChatPeerInfo dcpinfo;
if(DistantChatService::getDistantChatStatus(DistantChatPeerId(c->PeerId()), dcpinfo))
m.chat_id = ChatId(DistantChatPeerId(c->PeerId()));
if (c -> chatFlags & RS_CHAT_FLAG_PRIVATE)
m.chatflags |= RS_CHAT_PRIVATE;
@ -1178,16 +1192,14 @@ bool p3ChatService::loadList(std::list<RsItem*>& load)
continue;
}
if(DistributedChatService::processLoadListItem(*it))
{
delete *it;
continue;
}
DistributedChatService::processLoadListItem(*it) ;
DistantChatService::processLoadListItem(*it) ;
// delete unknown items
delete *it;
}
load.clear() ;
return true;
}
@ -1224,6 +1236,7 @@ bool p3ChatService::saveList(bool& cleanup, std::list<RsItem*>& list)
}
DistributedChatService::addToSaveList(list) ;
DistantChatService::addToSaveList(list) ;
return true;
}

View file

@ -53,7 +53,7 @@ typedef RsPeerId ChatLobbyVirtualPeerId ;
*/
class p3ChatService: public p3Service, public DistantChatService, public DistributedChatService, public p3Config, public pqiServiceMonitor
{
public:
public:
p3ChatService(p3ServiceControl *cs, p3IdService *pids,p3LinkMgr *cm, p3HistoryMgr *historyMgr);
virtual RsServiceInfo getServiceInfo();
@ -155,7 +155,7 @@ class p3ChatService: public p3Service, public DistantChatService, public Distrib
*/
bool clearPrivateChatQueue(bool incoming, const RsPeerId &id);
protected:
protected:
/************* from p3Config *******************/
virtual RsSerialiser *setupSerialiser() ;
@ -174,7 +174,7 @@ class p3ChatService: public p3Service, public DistantChatService, public Distrib
/// Same, for storing messages in incoming list
virtual void locked_storeIncomingMsg(RsChatMsgItem *) ;
private:
private:
RsMutex mChatMtx;
class AvatarInfo ;

View file

@ -51,18 +51,6 @@ std::ostream& RsChatMsgItem::print(std::ostream &out, uint16_t indent)
printRsItemEnd(out, "RsChatMsgItem", indent);
return out;
}
std::ostream& RsChatDHPublicKeyItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsChatDHPublicKeyItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << " Signature Key ID: " << signature.keyId << std::endl ;
out << " Public Key ID: " << gxs_key.keyId << std::endl ;
printRsItemEnd(out, "RsChatMsgItem", indent);
return out;
}
std::ostream& RsChatLobbyListItem::print(std::ostream &out, uint16_t indent)
{
@ -277,7 +265,6 @@ RsItem *RsChatSerialiser::deserialise(void *data, uint32_t *pktsize)
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST: return new RsChatLobbyListRequestItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST: return new RsChatLobbyListItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG: return new RsChatLobbyConfigItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY: return new RsChatDHPublicKeyItem(data,*pktsize) ;
default:
std::cerr << "Unknown packet type in chat!" << std::endl ;
return NULL ;
@ -437,17 +424,6 @@ uint32_t RsChatLobbyConfigItem::serial_size()
return s;
}
uint32_t RsChatDHPublicKeyItem::serial_size()
{
uint32_t s = 8 ; // header
s += 4 ; // BN size
s += BN_num_bytes(public_key) ; // public_key
s += signature.TlvSize() ; // signature
s += gxs_key.TlvSize() ; // gxs_key
return s ;
}
/*************************************************************************/
RsChatAvatarItem::~RsChatAvatarItem()
@ -459,41 +435,6 @@ RsChatAvatarItem::~RsChatAvatarItem()
}
}
bool RsChatDHPublicKeyItem::serialise(void *data,uint32_t& pktsize)
{
uint32_t tlvsize = serial_size() ;
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize);
/* skip the header */
offset += 8;
uint32_t s = BN_num_bytes(public_key) ;
ok &= setRawUInt32(data, tlvsize, &offset, s);
BN_bn2bin(public_key,&((unsigned char *)data)[offset]) ;
offset += s ;
ok &= signature.SetTlv(data, tlvsize, &offset);
ok &= gxs_key.SetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsChatDHPublicKeyItem::serialiseItem() Size Error! offset=" << offset << ", tlvsize=" << tlvsize << std::endl;
}
return ok ;
}
/* serialise the data to the buffer */
bool RsChatMsgItem::serialise(void *data, uint32_t& pktsize)
{
@ -995,28 +936,6 @@ bool RsChatLobbyConfigItem::serialise(void *data, uint32_t& pktsize)
return ok;
}
RsChatDHPublicKeyItem::RsChatDHPublicKeyItem(void *data,uint32_t /*size*/)
: RsChatItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY)
{
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(data);
bool ok = true ;
uint32_t s=0 ;
/* get mandatory parts first */
ok &= getRawUInt32(data, rssize, &offset, &s);
public_key = BN_bin2bn(&((unsigned char *)data)[offset],s,NULL) ;
offset += s ;
ok &= signature.GetTlv(data, rssize, &offset) ;
ok &= gxs_key.GetTlv(data, rssize, &offset) ;
if (offset != rssize)
std::cerr << "RsChatDHPublicKeyItem::() Size error while deserializing." << std::endl ;
if (!ok)
std::cerr << "RsChatDHPublicKeyItem::() Unknown error while deserializing." << std::endl ;
}
RsChatMsgItem::RsChatMsgItem(void *data,uint32_t /*size*/,uint8_t subtype)
: RsChatItem(subtype)
{

View file

@ -48,6 +48,7 @@ const uint32_t RS_CHAT_FLAG_LOBBY = 0x0200;
const uint32_t RS_CHAT_FLAG_CLOSING_DISTANT_CONNECTION = 0x0400;
const uint32_t RS_CHAT_FLAG_ACK_DISTANT_CONNECTION = 0x0800;
const uint32_t RS_CHAT_FLAG_KEEP_ALIVE = 0x1000;
const uint32_t RS_CHAT_FLAG_CONNEXION_REFUSED = 0x2000;
const uint32_t RS_CHATMSG_CONFIGFLAG_INCOMING = 0x0001;

View file

@ -1052,6 +1052,7 @@ bool CacheStrapper::loadList(std::list<RsItem *>& load)
delete (*it);
}
}
load.clear() ;
/* assemble a list of dirs to clean (union of cache dirs) */
std::list<std::string> cacheDirs;

View file

@ -175,6 +175,7 @@ HashCache::HashCache(const std::string& path)
if(!f->good())
{
delete f ;
std::cerr << "Unencrypted file cache not present either." << std::endl;
return ;
}

View file

@ -33,7 +33,11 @@
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#ifdef __MAC_10_10
#include <unordered_set>
#else
#include <tr1/unordered_set>
#endif
#include <iomanip>
#include <fstream>
#include <sys/stat.h>
@ -54,8 +58,11 @@ static const char FILE_CACHE_SEPARATOR_CHAR = '|' ;
****/
static RsMutex FIndexPtrMtx("FIndexPtrMtx") ;
#ifdef __MAC_10_10
std::unordered_set<void*> FileIndex::_pointers ;
#else
std::tr1::unordered_set<void*> FileIndex::_pointers ;
#endif
void FileIndex::registerEntry(void*p)
{
RsStackMutex m(FIndexPtrMtx) ;
@ -780,7 +787,7 @@ int FileIndex::loadIndex(const std::string& filename, const RsFileHash& expected
fclose(file);
return 0;
}
int bytesread = 0 ;
uint64_t bytesread = 0 ;
if(size != (bytesread = fread(compressed_data,1,size,file)))
{
std::cerr << "FileIndex::loadIndex(): can't read " << size << " bytes from file " << filename << ". Only " << bytesread << " actually read." << std::endl;
@ -1089,7 +1096,7 @@ int FileIndex::saveIndex(const std::string& filename, RsFileHash &fileHash, uint
std::cerr << "FileIndex::saveIndex error opening file for writting: " << filename << ". Giving up." << std::endl;
return 0;
}
int outwritten ;
uint32_t outwritten ;
if(compressed_data_size != (outwritten=fwrite(compressed_data,1,compressed_data_size,file)))
{
@ -1370,7 +1377,7 @@ void *FileIndex::findRef(const std::string& fpath) const
std::cerr << "FileIndex::updateFileEntry() NULL parent";
std::cerr << std::endl;
//#endif
return false;
return NULL;
}
std::cerr << "Found parent directory: " << std::endl;
std::cerr << " parent.name = " << parent->name << std::endl;

View file

@ -27,7 +27,11 @@
#include <string>
#include <map>
#include <set>
#if __MAC_10_10
#include <unordered_set>
#else
#include <tr1/unordered_set>
#endif
#include <list>
#include <vector>
#include <stdint.h>
@ -246,7 +250,11 @@ class FileIndex
PersonEntry *root;
#ifdef __MAC_10_10
static std::unordered_set<void*> _pointers ;
#else
static std::tr1::unordered_set<void*> _pointers ;
#endif
static void registerEntry(void*p) ;
static void unregisterEntry(void*p) ;
static bool isValid(void*p) ;

View file

@ -279,6 +279,11 @@ bool p3BitDht::loadList(std::list<RsItem *>& load)
/* error */
std::cerr << "p3BitDht::loadList() Error only expecting 1 item";
std::cerr << std::endl;
for(std::list<RsItem*>::iterator it=load.begin();it!=load.end();++it)
delete *it ;
load.clear() ;
return false;
}
RsItem *item = load.front();
@ -290,6 +295,7 @@ bool p3BitDht::loadList(std::list<RsItem *>& load)
/* error */
std::cerr << "p3BitDht::loadList() Error expecting item = config";
std::cerr << std::endl;
delete item ;
return false;
}
@ -393,6 +399,7 @@ bool p3BitDht::loadList(std::list<RsItem *>& load)
setRelayMode(mode);
}
load.clear() ;
return true;
}

View file

@ -96,7 +96,7 @@ void ChunkMap::setAvailabilityMap(const CompressedChunkMap& map)
// do some sanity check
//
if( (((int)_map.size()-1)>>5) >= map._map.size() )
if( (((int)_map.size()-1)>>5) >= (int)map._map.size() )
{
std::cerr << "ChunkMap::setPeerAvailabilityMap: Compressed chunkmap received is too small or corrupted." << std::endl;
return ;

View file

@ -2224,6 +2224,7 @@ bool ftController::loadList(std::list<RsItem *>& load)
/* cleanup */
delete (*it);
}
load.clear() ;
return true;
}

View file

@ -328,6 +328,8 @@ bool ftFiMonitor::loadList(std::list<RsItem *>& load)
if(sscanf(mit->second.c_str(),"%d",&t) == 1)
setWatchPeriod(t);
}
delete *it ;
continue ;
}
RsFileConfigItem *fi = dynamic_cast<RsFileConfigItem *>(*it);
@ -348,10 +350,13 @@ bool ftFiMonitor::loadList(std::list<RsItem *>& load)
info.shareflags &= ~DIR_FLAGS_NETWORK_WIDE_GROUPS ; // disabling this flag for know, for consistency reasons
dirList.push_back(info) ;
delete *it ;
}
/* set directories */
setSharedDirectories(dirList);
load.clear() ;
return true;
}

View file

@ -484,6 +484,7 @@ bool ftExtraList::loadList(std::list<RsItem *>& load)
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
}
load.clear() ;
return true;
}

View file

@ -42,7 +42,7 @@ static const uint32_t GROUTER_CLIENT_SERVICE_DATA_STATUS_FAILED = 0x0002 ; //
class GRouterClientService
{
public:
public:
// This method is called by the turtle router to send data that comes out of a turtle tunnel.
// The turtle router stays responsible for the memory management of data. Most of the time the
// data chunk is a serialized item to be de-serialized by the client service.
@ -73,6 +73,10 @@ class GRouterClientService
// 2 - call pt->registerTunnelService(this), so that the TR knows that service and can send back information to it.
//
virtual void connectToGlobalRouter(p3GRouter *pt) = 0 ;
// should be derived to determine wether the client accepts data from this peer or not. If not, the data is dropped.
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id) =0;
};

View file

@ -50,6 +50,7 @@ RsItem *RsGRouterSerialiser::deserialise(void *data, uint32_t *pktsize)
case RS_PKT_SUBTYPE_GROUTER_TRANSACTION_ACKN: return deserialise_RsGRouterTransactionAcknItem (data, *pktsize);
case RS_PKT_SUBTYPE_GROUTER_SIGNED_RECEIPT: return deserialise_RsGRouterSignedReceiptItem (data, *pktsize);
case RS_PKT_SUBTYPE_GROUTER_MATRIX_CLUES: return deserialise_RsGRouterMatrixCluesItem (data, *pktsize);
case RS_PKT_SUBTYPE_GROUTER_MATRIX_TRACK: return deserialise_RsGRouterMatrixTrackItem (data, *pktsize);
case RS_PKT_SUBTYPE_GROUTER_FRIENDS_LIST: return deserialise_RsGRouterMatrixFriendListItem(data, *pktsize);
case RS_PKT_SUBTYPE_GROUTER_ROUTING_INFO: return deserialise_RsGRouterRoutingInfoItem (data, *pktsize);
@ -269,6 +270,28 @@ RsGRouterMatrixFriendListItem *RsGRouterSerialiser::deserialise_RsGRouterMatrixF
return item;
}
RsGRouterMatrixTrackItem *RsGRouterSerialiser::deserialise_RsGRouterMatrixTrackItem(void *data, uint32_t pktsize) const
{
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(data);
bool ok = true ;
RsGRouterMatrixTrackItem *item = new RsGRouterMatrixTrackItem() ;
ok &= item->provider_id.deserialise(data, pktsize, offset) ;
ok &= item->message_id.deserialise(data,pktsize,offset) ;
ok &= getRawTimeT(data, pktsize, &offset, item->time_stamp) ;
if (offset != rssize || !ok)
{
std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl;
delete item;
return NULL ;
}
return item;
}
RsGRouterMatrixCluesItem *RsGRouterSerialiser::deserialise_RsGRouterMatrixCluesItem(void *data, uint32_t pktsize) const
{
uint32_t offset = 8; // skip the header
@ -559,6 +582,17 @@ uint32_t RsGRouterMatrixFriendListItem::serial_size() const
return s ;
}
uint32_t RsGRouterMatrixTrackItem::serial_size() const
{
uint32_t s = 8 ; // header
s += 8 ; // time_stamp
s += RsPeerId::SIZE_IN_BYTES; // provider_id
s += RsMessageId::SIZE_IN_BYTES; // message_id
return s ;
}
uint32_t RsGRouterRoutingInfoItem::serial_size() const
{
uint32_t s = 8 ; // header
@ -637,6 +671,26 @@ bool RsGRouterMatrixCluesItem::serialise(void *data,uint32_t& size) const
return ok;
}
bool RsGRouterMatrixTrackItem::serialise(void *data,uint32_t& size) const
{
uint32_t tlvsize,offset=0;
bool ok = true;
if(!serialise_header(data,size,tlvsize,offset))
return false ;
ok &= provider_id.serialise(data, tlvsize, offset) ;
ok &= message_id.serialise(data,tlvsize,offset) ;
ok &= setRawTimeT(data, tlvsize, &offset, time_stamp) ;
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsGRouterMatrixTrackItem::serialisedata() size error! " << std::endl;
}
return ok;
}
bool FriendTrialRecord::deserialise(void *data,uint32_t& offset,uint32_t size)
{
bool ok = true ;
@ -701,6 +755,7 @@ bool RsGRouterRoutingInfoItem::serialise(void *data,uint32_t& size) const
// ------------------------------------- IO --------------------------------------- //
// -----------------------------------------------------------------------------------//
//
std::ostream& RsGRouterSignedReceiptItem::print(std::ostream& o, uint16_t)
{
o << "RsGRouterReceiptItem:" << std::endl ;
@ -746,6 +801,15 @@ std::ostream& RsGRouterRoutingInfoItem::print(std::ostream& o, uint16_t)
return o ;
}
std::ostream& RsGRouterMatrixTrackItem::print(std::ostream& o, uint16_t)
{
o << "RsGRouterMatrixTrackItem:" << std::endl ;
o << " provider_id: " << provider_id << std::endl;
o << " message_id: " << message_id << std::endl;
o << " time_stamp: " << time_stamp << std::endl;
return o ;
}
std::ostream& RsGRouterMatrixCluesItem::print(std::ostream& o, uint16_t)
{
o << "RsGRouterMatrixCluesItem:" << std::endl ;

View file

@ -40,13 +40,12 @@ const uint8_t RS_PKT_SUBTYPE_GROUTER_DATA_deprecated = 0x05 ; // do
const uint8_t RS_PKT_SUBTYPE_GROUTER_DATA_deprecated2 = 0x06 ; // don't use!
const uint8_t RS_PKT_SUBTYPE_GROUTER_DATA = 0x07 ; // used to send data to a destination (Signed by source)
const uint8_t RS_PKT_SUBTYPE_GROUTER_SIGNED_RECEIPT = 0x08 ; // long-distance acknowledgement of data received
const uint8_t RS_PKT_SUBTYPE_GROUTER_TRANSACTION_CHUNK = 0x10 ; // chunk of data. Used internally.
const uint8_t RS_PKT_SUBTYPE_GROUTER_TRANSACTION_ACKN = 0x11 ; // acknowledge for finished transaction. Not necessary, but increases fiability.
const uint8_t RS_PKT_SUBTYPE_GROUTER_MATRIX_CLUES = 0x80 ; // item to save matrix clues
const uint8_t RS_PKT_SUBTYPE_GROUTER_FRIENDS_LIST = 0x82 ; // item to save friend lists
const uint8_t RS_PKT_SUBTYPE_GROUTER_ROUTING_INFO = 0x93 ; //
const uint8_t RS_PKT_SUBTYPE_GROUTER_MATRIX_TRACK = 0x94 ; // item to save matrix track info
const uint8_t QOS_PRIORITY_RS_GROUTER = 4 ; // relevant for items that travel through friends
@ -243,6 +242,24 @@ class RsGRouterMatrixCluesItem: public RsGRouterItem
std::list<RoutingMatrixHitEntry> clues ;
};
class RsGRouterMatrixTrackItem: public RsGRouterItem
{
public:
RsGRouterMatrixTrackItem() : RsGRouterItem(RS_PKT_SUBTYPE_GROUTER_MATRIX_TRACK)
{ setPriorityLevel(0) ; } // this item is never sent through the network
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 = 0) ;
// packet data
//
RsGxsMessageId message_id ;
RsPeerId provider_id ;
time_t time_stamp ;
};
class RsGRouterMatrixFriendListItem: public RsGRouterItem
{
public:
@ -317,6 +334,7 @@ private:
RsGRouterTransactionAcknItem *deserialise_RsGRouterTransactionAcknItem(void *data,uint32_t size) const ;
RsGRouterSignedReceiptItem *deserialise_RsGRouterSignedReceiptItem(void *data,uint32_t size) const ;
RsGRouterMatrixCluesItem *deserialise_RsGRouterMatrixCluesItem(void *data,uint32_t size) const ;
RsGRouterMatrixTrackItem *deserialise_RsGRouterMatrixTrackItem(void *data,uint32_t size) const ;
RsGRouterMatrixFriendListItem *deserialise_RsGRouterMatrixFriendListItem(void *data,uint32_t size) const ;
RsGRouterRoutingInfoItem *deserialise_RsGRouterRoutingInfoItem(void *data,uint32_t size) const ;
};

View file

@ -34,6 +34,48 @@ GRouterMatrix::GRouterMatrix()
_proba_need_updating = true ;
}
bool GRouterMatrix::addTrackingInfo(const RsGxsMessageId& mid,const RsPeerId& source_friend)
{
time_t now = time(NULL) ;
RoutingTrackEntry rte ;
rte.friend_id = source_friend ;
rte.time_stamp = now ;
_tracking_clues[mid] = rte ;
#ifdef ROUTING_MATRIX_DEBUG
std::cerr << "GRouterMatrix::addTrackingInfo(): Added clue mid=" << mid << ", from " << source_friend << " ID=" << source_friend << std::endl;
#endif
return true ;
}
bool GRouterMatrix::cleanUp()
{
// remove all tracking entries that have become too old.
#ifdef ROUTING_MATRIX_DEBUG
std::cerr << "GRouterMatrix::cleanup()" << std::endl;
#endif
time_t now = time(NULL) ;
for(std::map<RsGxsMessageId,RoutingTrackEntry>::iterator it(_tracking_clues.begin());it!=_tracking_clues.end();)
if(it->second.time_stamp + RS_GROUTER_MAX_KEEP_TRACKING_CLUES < now)
{
#ifdef ROUTING_MATRIX_DEBUG
std::cerr << " removing old entry msgId=" << it->first << ", from id " << it->second.friend_id << ", obtained " << (now - it->second.time_stamp) << " secs ago." << std::endl;
#endif
std::map<RsGxsMessageId,RoutingTrackEntry>::iterator tmp(it) ;
++tmp ;
_tracking_clues.erase(it) ;
it=tmp ;
}
else
++it ;
return true ;
}
bool GRouterMatrix::addRoutingClue(const GRouterKeyId& key_id,const RsPeerId& source_friend,float weight)
{
// 1 - get the friend index.
@ -118,6 +160,18 @@ void GRouterMatrix::getListOfKnownKeys(std::vector<GRouterKeyId>& key_ids) const
key_ids.push_back(it->first) ;
}
bool GRouterMatrix::getTrackingInfo(const RsGxsMessageId& mid, RsPeerId &source_friend)
{
std::map<RsGxsMessageId,RoutingTrackEntry>::const_iterator it = _tracking_clues.find(mid) ;
if(it == _tracking_clues.end())
return false ;
source_friend = it->second.friend_id;
return true ;
}
void GRouterMatrix::debugDump() const
{
std::cerr << " Proba needs up: " << _proba_need_updating << std::endl;
@ -143,6 +197,10 @@ void GRouterMatrix::debugDump() const
std::cerr << it->second[i] << " " ;
std::cerr << std::endl;
}
std::cerr << " Tracking clues: " << std::endl;
for(std::map<RsGxsMessageId, RoutingTrackEntry>::const_iterator it(_tracking_clues.begin());it!=_tracking_clues.end();++it)
std::cerr << " " << it->first << ": from " << it->second.friend_id << " " << now - it->second.time_stamp << " secs ago." << std::endl;
}
bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, const std::vector<RsPeerId>& friends, std::vector<float>& probas) const
@ -256,12 +314,24 @@ bool GRouterMatrix::saveList(std::list<RsItem*>& items)
items.push_back(item) ;
}
for(std::map<RsGxsMessageId,RoutingTrackEntry>::const_iterator it(_tracking_clues.begin());it!=_tracking_clues.end();++it)
{
RsGRouterMatrixTrackItem *item = new RsGRouterMatrixTrackItem ;
item->provider_id = it->second.friend_id ;
item->time_stamp = it->second.time_stamp ;
item->message_id = it->first ;
items.push_back(item) ;
}
return true ;
}
bool GRouterMatrix::loadList(std::list<RsItem*>& items)
{
RsGRouterMatrixFriendListItem *itm1 = NULL ;
RsGRouterMatrixCluesItem *itm2 = NULL ;
RsGRouterMatrixTrackItem *itm3 = NULL ;
#ifdef ROUTING_MATRIX_DEBUG
std::cerr << " GRoutingMatrix::loadList()" << std::endl;
@ -269,6 +339,17 @@ bool GRouterMatrix::loadList(std::list<RsItem*>& items)
for(std::list<RsItem*>::const_iterator it(items.begin());it!=items.end();++it)
{
if(NULL != (itm3 = dynamic_cast<RsGRouterMatrixTrackItem*>(*it)))
{
#ifdef ROUTING_MATRIX_DEBUG
std::cerr << " initing tracking clues." << std::endl;
#endif
RoutingTrackEntry rte ;
rte.friend_id = itm3->provider_id ;
rte.time_stamp = itm3->time_stamp ;
_tracking_clues[itm3->message_id] = rte;
}
if(NULL != (itm2 = dynamic_cast<RsGRouterMatrixCluesItem*>(*it)))
{
#ifdef ROUTING_MATRIX_DEBUG

View file

@ -42,6 +42,12 @@ struct RoutingMatrixHitEntry
time_t time_stamp ;
};
struct RoutingTrackEntry
{
RsPeerId friend_id ; // not the full key. Gets too big otherwise!
time_t time_stamp ;
};
class GRouterMatrix
{
public:
@ -61,15 +67,19 @@ class GRouterMatrix
// Record one routing clue. The events can possibly be merged in time buckets.
//
bool addRoutingClue(const GRouterKeyId& id,const RsPeerId& source_friend,float weight) ;
bool addTrackingInfo(const RsGxsMessageId& id,const RsPeerId& source_friend) ;
bool saveList(std::list<RsItem*>& items) ;
bool loadList(std::list<RsItem*>& items) ;
bool cleanUp() ;
// Dump info in terminal.
//
void debugDump() const ;
void getListOfKnownKeys(std::vector<GRouterKeyId>& key_ids) const ;
bool getTrackingInfo(const RsGxsMessageId& id,RsPeerId& source_friend);
private:
// returns the friend id, possibly creating a new id.
//
@ -83,6 +93,7 @@ class GRouterMatrix
//
std::map<GRouterKeyId, std::list<RoutingMatrixHitEntry> > _routing_clues ; // received routing clues. Should be saved.
std::map<GRouterKeyId, std::vector<float> > _time_combined_hits ; // hit matrix after time-convolution filter
std::map<RsGxsMessageId,RoutingTrackEntry> _tracking_clues ; // who provided the most recent messages
// This is used to avoid re-computing probas when new events have been received.
//
@ -93,6 +104,5 @@ class GRouterMatrix
//
std::map<RsPeerId,uint32_t> _friend_indices ; // index for each friend to lookup in the routing matrix Not saved.
std::vector<RsPeerId> _reverse_friend_indices ;// SSLid corresponding to each friend index. Saved.
};

View file

@ -39,7 +39,8 @@ static const uint16_t GROUTER_CLIENT_ID_MESSAGES = 0x1001 ;
static const uint32_t RS_GROUTER_MATRIX_MAX_HIT_ENTRIES = 10 ; // max number of clues to store
static const uint32_t RS_GROUTER_MATRIX_MIN_TIME_BETWEEN_HITS = 60 ; // can be set to up to half the publish time interval. Prevents flooding routes.
static const uint32_t RS_GROUTER_MIN_CONFIG_SAVE_PERIOD = 5 ; // at most save config every 5 seconds
static const uint32_t RS_GROUTER_MIN_CONFIG_SAVE_PERIOD = 10 ; // at most save config every 10 seconds
static const uint32_t RS_GROUTER_MAX_KEEP_TRACKING_CLUES = 86400*10 ; // max time for which we keep record of tracking info: 10 days.
static const float RS_GROUTER_BASE_WEIGHT_ROUTED_MSG = 1.0f ; // base contribution of routed message clue to routing matrix
static const float RS_GROUTER_BASE_WEIGHT_GXS_PACKET = 0.1f ; // base contribution of GXS message to routing matrix
@ -56,7 +57,7 @@ static const uint32_t MAX_INACTIVE_DATA_PIPE_DELAY = 300 ; // cl
static const time_t RS_GROUTER_DEBUG_OUTPUT_PERIOD = 10 ; // Output everything
static const time_t RS_GROUTER_AUTOWASH_PERIOD = 10 ; // Autowash every minute. Not a costly operation.
static const time_t RS_GROUTER_MATRIX_UPDATE_PERIOD = 1 *10 ; // Check for key advertising every 10 minutes
static const time_t RS_GROUTER_MATRIX_UPDATE_PERIOD = 60*10 ; // Check for key advertising every 10 minutes
static const uint32_t GROUTER_ITEM_MAX_CACHE_KEEP_TIME = 2*86400 ; // Cached items are kept for 48 hours at most.
static const uint32_t RS_GROUTER_DATA_STATUS_UNKNOWN = 0x0000 ; // unknown. Unused.

View file

@ -252,6 +252,7 @@ int p3GRouter::tick()
_last_matrix_update_time = now ;
_routing_matrix.updateRoutingProbabilities() ; // This should be locked.
_routing_matrix.cleanUp() ; // This should be locked.
}
#ifdef GROUTER_DEBUG
@ -315,6 +316,7 @@ bool p3GRouter::registerKey(const RsGxsId& authentication_key,const GRouterServi
grouter_debug() << " Auth GXS Id : " << authentication_key << std::endl;
grouter_debug() << " Client id : " << std::hex << client_id << std::dec << std::endl;
grouter_debug() << " Description : " << info.description_string << std::endl;
grouter_debug() << " Hash : " << hash << std::endl;
#endif
return true ;
@ -509,6 +511,12 @@ void p3GRouter::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,const RsFileH
RsItem *itm = RsGRouterSerialiser().deserialise(item->data_bytes,&item->data_size) ;
if(itm == NULL)
{
std::cerr << "(EE) p3GRouter::receiveTurtleData(): cannot de-serialise data. Somthing wrong in the format. Item data (size="<< item->data_size << "): " << RsUtil::BinToHex((char*)item->data_bytes,item->data_size) << std::endl;
return ;
}
itm->PeerId(virtual_peer_id) ;
// At this point we can have either a transaction chunk, or a transaction ACK.
@ -1653,10 +1661,13 @@ void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item)
std::cerr << " notyfying client." << std::endl;
#endif
if(client->acceptDataFromPeer(decrypted_item->signature.keyId))
{
client->receiveGRouterData(decrypted_item->destination_key,decrypted_item->signature.keyId,service_id,decrypted_item->data_bytes,decrypted_item->data_size);
decrypted_item->data_bytes = NULL ;
decrypted_item->data_size = 0 ;
}
delete decrypted_item ;
}
@ -1673,9 +1684,13 @@ bool p3GRouter::locked_getClientAndServiceId(const TurtleFileHash& hash, const R
{
client = NULL ;
service_id = 0;
RsGxsId gxs_id ;
makeGxsIdAndClientId(hash,gxs_id,service_id) ;
if(!locked_getGxsIdAndClientId(hash,gxs_id,service_id))
{
std::cerr << " p3GRouter::ERROR: locked_getGxsIdAndClientId(): no key registered for hash " << hash << std::endl;
return false ;
}
if(gxs_id != destination_key)
{
@ -1698,6 +1713,15 @@ bool p3GRouter::locked_getClientAndServiceId(const TurtleFileHash& hash, const R
return true ;
}
void p3GRouter::addTrackingInfo(const RsGxsMessageId& mid,const RsPeerId& peer_id)
{
RS_STACK_MUTEX(grMtx) ;
#ifdef GROUTER_DEBUG
grouter_debug() << "Received new routing clue for key " << mid << " from peer " << peer_id << std::endl;
#endif
_routing_matrix.addTrackingInfo(mid,peer_id) ;
_changed = true ;
}
void p3GRouter::addRoutingClue(const GRouterKeyId& id,const RsPeerId& peer_id)
{
RS_STACK_MUTEX(grMtx) ;
@ -1705,6 +1729,7 @@ void p3GRouter::addRoutingClue(const GRouterKeyId& id,const RsPeerId& peer_id)
grouter_debug() << "Received new routing clue for key " << id << " from peer " << peer_id << std::endl;
#endif
_routing_matrix.addRoutingClue(id,peer_id,RS_GROUTER_BASE_WEIGHT_GXS_PACKET) ;
_changed = true ;
}
bool p3GRouter::registerClientService(const GRouterServiceId& id,GRouterClientService *service)
@ -2002,15 +2027,25 @@ Sha1CheckSum p3GRouter::makeTunnelHash(const RsGxsId& destination,const GRouterS
bytes[18] = (client >> 8) & 0xff ;
bytes[19] = client & 0xff ;
return Sha1CheckSum(bytes) ;
return RsDirUtil::sha1sum(bytes,20) ;
}
void p3GRouter::makeGxsIdAndClientId(const TurtleFileHash& sum,RsGxsId& gxs_id,GRouterServiceId& client_id)
bool p3GRouter::locked_getGxsIdAndClientId(const TurtleFileHash& sum,RsGxsId& gxs_id,GRouterServiceId& client_id)
{
assert( gxs_id.SIZE_IN_BYTES == 16) ;
assert(Sha1CheckSum::SIZE_IN_BYTES == 20) ;
gxs_id = RsGxsId(sum.toByteArray());// takes the first 16 bytes
client_id = sum.toByteArray()[19] + (sum.toByteArray()[18] << 8) ;
//gxs_id = RsGxsId(sum.toByteArray());// takes the first 16 bytes
//client_id = sum.toByteArray()[19] + (sum.toByteArray()[18] << 8) ;
std::map<Sha1CheckSum, GRouterPublishedKeyInfo>::const_iterator it = _owned_key_ids.find(sum);
if(it == _owned_key_ids.end())
return false ;
gxs_id = it->second.authentication_key ;
client_id = it->second.service_id ;
return true ;
}
bool p3GRouter::loadList(std::list<RsItem*>& items)
{
@ -2060,6 +2095,7 @@ bool p3GRouter::loadList(std::list<RsItem*>& items)
#ifdef GROUTER_DEBUG
debugDump();
#endif
items.clear() ;
return true ;
}
bool p3GRouter::saveList(bool& cleanup,std::list<RsItem*>& items)
@ -2154,6 +2190,13 @@ bool p3GRouter::getRoutingCacheInfo(std::vector<GRouterRoutingCacheInfo>& infos)
return true ;
}
bool p3GRouter::getTrackingInfo(const RsGxsMessageId &mid, RsPeerId &provider_id)
{
RS_STACK_MUTEX(grMtx) ;
return _routing_matrix.getTrackingInfo(mid,provider_id) ;
}
// Dump everything
//
void p3GRouter::debugDump()
@ -2214,8 +2257,8 @@ void p3GRouter::debugDump()
grouter_debug() << " Routing matrix: " << std::endl;
// if(_debug_enabled)
// _routing_matrix.debugDump() ;
if(_debug_enabled)
_routing_matrix.debugDump() ;
}

View file

@ -130,6 +130,7 @@ public:
//===================================================//
virtual void addRoutingClue(const GRouterKeyId& id,const RsPeerId& peer_id) ;
virtual void addTrackingInfo(const RsGxsMessageId& mid,const RsPeerId& peer_id) ;
//===================================================//
// Client/server request services //
@ -167,6 +168,7 @@ public:
// - Cache state (memory size, etc)
//
virtual bool getRoutingCacheInfo(std::vector<GRouterRoutingCacheInfo>& info) ;
virtual bool getTrackingInfo(const RsGxsMessageId& mid, RsPeerId& provider_id) ;
//===================================================//
// Derived from p3Service //
@ -223,7 +225,9 @@ private:
void handleLowLevelTransactionAckItem(RsGRouterTransactionAcknItem*) ;
static Sha1CheckSum computeDataItemHash(RsGRouterGenericDataItem *data_item);
#ifdef __APPLE__
public:
#endif
class nullstream: public std::ostream {};
std::ostream& grouter_debug() const
@ -232,7 +236,9 @@ private:
return _debug_enabled?(std::cerr):null;
}
#ifdef __APPLE__
private:
#endif
void routePendingObjects() ;
void handleTunnels() ;
void autoWash() ;
@ -263,8 +269,8 @@ private:
bool decryptDataItem(RsGRouterGenericDataItem *item) ;
static Sha1CheckSum makeTunnelHash(const RsGxsId& destination,const GRouterServiceId& client);
static void makeGxsIdAndClientId(const TurtleFileHash &sum,RsGxsId& gxs_id,GRouterServiceId& client_id);
bool locked_getGxsIdAndClientId(const TurtleFileHash &sum,RsGxsId& gxs_id,GRouterServiceId& client_id);
bool locked_sendTransactionData(const RsPeerId& pid,const RsGRouterTransactionItem& item);
void locked_collectAvailableFriends(const GRouterKeyId &gxs_id,std::list<RsPeerId>& friend_peers, const std::set<RsPeerId>& incoming_routes,bool is_origin);
@ -300,7 +306,6 @@ private:
//
GRouterMatrix _routing_matrix ;
// Stores the keys which identify the router's node. For each key, a structure holds:
// - the client service
// - flags

View file

@ -27,6 +27,7 @@
#include "gxssecurity.h"
#include "pqi/authgpg.h"
#include "util/rsdir.h"
#include "util/rsmemory.h"
//#include "retroshare/rspeers.h"
/****
@ -749,7 +750,7 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
in_offset += size_net_ekl;
// Conservative limits to detect weird errors due to corrupted encoding.
if(eklen < 0 || eklen > 512 || eklen+in_offset > inlen)
if(eklen < 0 || eklen > 512 || eklen+in_offset > (int)inlen)
{
std::cerr << "Error while deserialising encryption key length: eklen = " << std::dec << eklen << ". Giving up decryption." << std::endl;
free(ek);
@ -857,38 +858,48 @@ bool GxsSecurity::validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& s
#endif
}
std::vector<uint32_t> api_versions_to_check ;
api_versions_to_check.push_back(RS_GXS_GRP_META_DATA_VERSION_ID_0002) ; // put newest first, for debug info purpose
api_versions_to_check.push_back(RS_GXS_GRP_META_DATA_VERSION_ID_0001) ;
RsTlvKeySignatureSet signSet = grpMeta.signSet;
grpMeta.signSet.TlvClear();
uint32_t metaDataLen = grpMeta.serial_size();
uint32_t allGrpDataLen = metaDataLen + grp.grp.bin_len;
char* metaData = new char[metaDataLen];
char* allGrpData = new char[allGrpDataLen]; // msgData + metaData
int signOk =0;
EVP_PKEY *signKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(signKey, rsakey);
grpMeta.serialise(metaData, metaDataLen);
for(uint32_t i=0;i<api_versions_to_check.size() && 0==signOk;++i)
{
uint32_t metaDataLen = grpMeta.serial_size(api_versions_to_check[i]);
uint32_t allGrpDataLen = metaDataLen + grp.grp.bin_len;
RsTemporaryMemory metaData(metaDataLen) ;
RsTemporaryMemory allGrpData(allGrpDataLen) ;// msgData + metaData
grpMeta.serialise(metaData, metaDataLen,api_versions_to_check[i]);
// copy msg data and meta in allmsgData buffer
memcpy(allGrpData, grp.grp.bin_data, grp.grp.bin_len);
memcpy(allGrpData+(grp.grp.bin_len), metaData, metaDataLen);
delete[] metaData ;
EVP_PKEY *signKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(signKey, rsakey);
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_VerifyInit(mdctx, EVP_sha1());
EVP_VerifyUpdate(mdctx, allGrpData, allGrpDataLen);
int signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey);
signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey);
EVP_MD_CTX_destroy(mdctx);
delete[] allGrpData ;
if(i>0)
std::cerr << "(WW) Checking group signature with old api version " << i+1 << " : tag " << std::hex << api_versions_to_check[i] << std::dec << " result: " << signOk << std::endl;
}
/* clean up */
EVP_PKEY_free(signKey);
EVP_MD_CTX_destroy(mdctx);
// restore data
grpMeta.signSet = signSet;
@ -906,7 +917,7 @@ bool GxsSecurity::validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& s
std::cerr << std::endl;
#endif
return false;
return false;
}

View file

@ -152,6 +152,11 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d
mColMsg_MetaData = addColumn(mMsgColumns, KEY_NXS_META);
mColMsg_MsgId = addColumn(mMsgColumns, KEY_MSG_ID);
// for retrieving msg data with meta
mMsgColumnsWithMeta = mMsgColumns;
mColMsg_WithMetaOffset = mMsgColumnsWithMeta.size();
mMsgColumnsWithMeta.insert(mMsgColumnsWithMeta.end(), mMsgMetaColumns.begin(), mMsgMetaColumns.end());
// for retrieving grp meta data
mColGrpMeta_GrpId = addColumn(mGrpMetaColumns, KEY_GRP_ID);
mColGrpMeta_TimeStamp = addColumn(mGrpMetaColumns, KEY_TIME_STAMP);
@ -184,6 +189,11 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d
mColGrp_NxsData = addColumn(mGrpColumns, KEY_NXS_DATA);
mColGrp_MetaData = addColumn(mGrpColumns, KEY_NXS_META);
// for retrieving grp data with meta
mGrpColumnsWithMeta = mGrpColumns;
mColGrp_WithMetaOffset = mGrpColumnsWithMeta.size();
mGrpColumnsWithMeta.insert(mGrpColumnsWithMeta.end(), mGrpMetaColumns.begin(), mGrpMetaColumns.end());
// Group id columns
mColGrpId_GrpId = addColumn(mGrpIdColumn, KEY_GRP_ID);
@ -474,7 +484,7 @@ bool RsDataService::finishReleaseUpdate(int release, bool result)
return result;
}
RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c)
RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c, int colOffset)
{
#ifdef RS_DATA_SERVICE_DEBUG
std::cerr << "RsDataService::locked_getGrpMeta()";
@ -492,27 +502,27 @@ RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c)
// grpId
std::string tempId;
c.getString(mColGrpMeta_GrpId, tempId);
c.getString(mColGrpMeta_GrpId + colOffset, tempId);
grpMeta->mGroupId = RsGxsGroupId(tempId);
c.getString(mColGrpMeta_NxsIdentity, tempId);
c.getString(mColGrpMeta_NxsIdentity + colOffset, tempId);
grpMeta->mAuthorId = RsGxsId(tempId);
c.getString(mColGrpMeta_Name, grpMeta->mGroupName);
c.getString(mColGrpMeta_OrigGrpId, tempId);
c.getString(mColGrpMeta_Name + colOffset, grpMeta->mGroupName);
c.getString(mColGrpMeta_OrigGrpId + colOffset, tempId);
grpMeta->mOrigGrpId = RsGxsGroupId(tempId);
c.getString(mColGrpMeta_ServString, grpMeta->mServiceString);
c.getString(mColGrpMeta_ServString + colOffset, grpMeta->mServiceString);
std::string temp;
c.getString(mColGrpMeta_NxsHash, temp);
c.getString(mColGrpMeta_NxsHash + colOffset, temp);
grpMeta->mHash = RsFileHash(temp);
grpMeta->mReputationCutOff = c.getInt32(mColGrpMeta_RepCutoff);
grpMeta->mSignFlags = c.getInt32(mColGrpMeta_SignFlags);
grpMeta->mReputationCutOff = c.getInt32(mColGrpMeta_RepCutoff + colOffset);
grpMeta->mSignFlags = c.getInt32(mColGrpMeta_SignFlags + colOffset);
grpMeta->mPublishTs = c.getInt32(mColGrpMeta_TimeStamp);
grpMeta->mGroupFlags = c.getInt32(mColGrpMeta_NxsFlags);
grpMeta->mGrpSize = c.getInt32(mColGrpMeta_NxsDataLen);
grpMeta->mPublishTs = c.getInt32(mColGrpMeta_TimeStamp + colOffset);
grpMeta->mGroupFlags = c.getInt32(mColGrpMeta_NxsFlags + colOffset);
grpMeta->mGrpSize = c.getInt32(mColGrpMeta_NxsDataLen + colOffset);
offset = 0; data = NULL; data_len = 0;
data = (char*)c.getData(mColGrpMeta_KeySet, data_len);
data = (char*)c.getData(mColGrpMeta_KeySet + colOffset, data_len);
if(data)
ok &= grpMeta->keys.GetTlv(data, data_len, &offset);
@ -520,22 +530,22 @@ RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c)
grpMeta->keys.TlvClear() ;
// local meta
grpMeta->mSubscribeFlags = c.getInt32(mColGrpMeta_SubscrFlag);
grpMeta->mPop = c.getInt32(mColGrpMeta_Pop);
grpMeta->mVisibleMsgCount = c.getInt32(mColGrpMeta_MsgCount);
grpMeta->mLastPost = c.getInt32(mColGrpMeta_LastPost);
grpMeta->mGroupStatus = c.getInt32(mColGrpMeta_Status);
grpMeta->mSubscribeFlags = c.getInt32(mColGrpMeta_SubscrFlag + colOffset);
grpMeta->mPop = c.getInt32(mColGrpMeta_Pop + colOffset);
grpMeta->mVisibleMsgCount = c.getInt32(mColGrpMeta_MsgCount + colOffset);
grpMeta->mLastPost = c.getInt32(mColGrpMeta_LastPost + colOffset);
grpMeta->mGroupStatus = c.getInt32(mColGrpMeta_Status + colOffset);
c.getString(mColGrpMeta_CircleId, tempId);
c.getString(mColGrpMeta_CircleId + colOffset, tempId);
grpMeta->mCircleId = RsGxsCircleId(tempId);
grpMeta->mCircleType = c.getInt32(mColGrpMeta_CircleType);
c.getString(mColGrpMeta_InternCircle, tempId);
grpMeta->mCircleType = c.getInt32(mColGrpMeta_CircleType + colOffset);
c.getString(mColGrpMeta_InternCircle + colOffset, tempId);
grpMeta->mInternalCircle = RsGxsCircleId(tempId);
std::string s ; c.getString(mColGrpMeta_Originator, s) ;
std::string s ; c.getString(mColGrpMeta_Originator + colOffset, s) ;
grpMeta->mOriginator = RsPeerId(s);
grpMeta->mAuthenFlags = c.getInt32(mColGrpMeta_AuthenFlags);
grpMeta->mRecvTS = c.getInt32(mColGrpMeta_RecvTs);
grpMeta->mAuthenFlags = c.getInt32(mColGrpMeta_AuthenFlags + colOffset);
grpMeta->mRecvTS = c.getInt32(mColGrpMeta_RecvTs + colOffset);
c.getString(mColGrpMeta_ParentGrpId, tempId);
@ -591,7 +601,7 @@ RsNxsGrp* RsDataService::locked_getGroup(RetroCursor &c)
return NULL;
}
RsGxsMsgMetaData* RsDataService::locked_getMsgMeta(RetroCursor &c)
RsGxsMsgMetaData* RsDataService::locked_getMsgMeta(RetroCursor &c, int colOffset)
{
RsGxsMsgMetaData* msgMeta = new RsGxsMsgMetaData();
@ -602,44 +612,43 @@ RsGxsMsgMetaData* RsDataService::locked_getMsgMeta(RetroCursor &c)
char* data = NULL;
std::string gId;
c.getString(mColMsgMeta_GrpId, gId);
c.getString(mColMsgMeta_GrpId + colOffset, gId);
msgMeta->mGroupId = RsGxsGroupId(gId);
std::string temp;
c.getString(mColMsgMeta_MsgId, temp);
c.getString(mColMsgMeta_MsgId + colOffset, temp);
msgMeta->mMsgId = RsGxsMessageId(temp);
// without these, a msg is meaningless
ok &= (!msgMeta->mGroupId.isNull()) && (!msgMeta->mMsgId.isNull());
c.getString(mColMsgMeta_OrigMsgId, temp);
c.getString(mColMsgMeta_OrigMsgId + colOffset, temp);
msgMeta->mOrigMsgId = RsGxsMessageId(temp);
c.getString(mColMsgMeta_NxsIdentity, temp);
c.getString(mColMsgMeta_NxsIdentity + colOffset, temp);
msgMeta->mAuthorId = RsGxsId(temp);
c.getString(mColMsgMeta_Name, msgMeta->mMsgName);
c.getString(mColMsgMeta_NxsServString, msgMeta->mServiceString);
c.getString(mColMsgMeta_Name + colOffset, msgMeta->mMsgName);
c.getString(mColMsgMeta_NxsServString + colOffset, msgMeta->mServiceString);
c.getString(mColMsgMeta_NxsHash, temp);
c.getString(mColMsgMeta_NxsHash + colOffset, temp);
msgMeta->mHash = RsFileHash(temp);
msgMeta->recvTS = c.getInt32(mColMsgMeta_RecvTs);
msgMeta->recvTS = c.getInt32(mColMsgMeta_RecvTs + colOffset);
offset = 0;
data = (char*)c.getData(mColMsgMeta_SignSet, data_len);
data = (char*)c.getData(mColMsgMeta_SignSet + colOffset, data_len);
msgMeta->signSet.GetTlv(data, data_len, &offset);
msgMeta->mMsgSize = c.getInt32(mColMsgMeta_NxsDataLen);
msgMeta->mMsgSize = c.getInt32(mColMsgMeta_NxsDataLen + colOffset);
msgMeta->mMsgFlags = c.getInt32(mColMsgMeta_NxsFlags);
msgMeta->mPublishTs = c.getInt32(mColMsgMeta_TimeStamp);
msgMeta->mMsgFlags = c.getInt32(mColMsgMeta_NxsFlags + colOffset);
msgMeta->mPublishTs = c.getInt32(mColMsgMeta_TimeStamp + colOffset);
offset = 0; data_len = 0;
// thread and parent id
c.getString(mColMsgMeta_MsgThreadId, temp);
c.getString(mColMsgMeta_MsgThreadId + colOffset, temp);
msgMeta->mThreadId = RsGxsMessageId(temp);
c.getString(mColMsgMeta_MsgParentId, temp);
c.getString(mColMsgMeta_MsgParentId + colOffset, temp);
msgMeta->mParentId = RsGxsMessageId(temp);
// local meta
msgMeta->mMsgStatus = c.getInt32(mColMsgMeta_MsgStatus);
msgMeta->mChildTs = c.getInt32(mColMsgMeta_ChildTs);
msgMeta->mMsgStatus = c.getInt32(mColMsgMeta_MsgStatus + colOffset);
msgMeta->mChildTs = c.getInt32(mColMsgMeta_ChildTs + colOffset);
if(ok)
return msgMeta;
@ -1020,13 +1029,13 @@ int RsDataService::retrieveNxsGrps(std::map<RsGxsGroupId, RsNxsGrp *> &grp, bool
if(grp.empty()){
RsStackMutex stack(mDbMutex);
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, mGrpColumns, "", "");
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, withMeta ? mGrpColumnsWithMeta : mGrpColumns, "", "");
if(c)
{
std::vector<RsNxsGrp*> grps;
locked_retrieveGroups(c, grps);
locked_retrieveGroups(c, grps, withMeta ? mColGrp_WithMetaOffset : 0);
std::vector<RsNxsGrp*>::iterator vit = grps.begin();
#ifdef RS_DATA_SERVICE_DEBUG_TIME
@ -1051,12 +1060,12 @@ int RsDataService::retrieveNxsGrps(std::map<RsGxsGroupId, RsNxsGrp *> &grp, bool
for(; mit != grp.end(); ++mit)
{
const RsGxsGroupId& grpId = mit->first;
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, mGrpColumns, "grpId='" + grpId.toStdString() + "'", "");
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, withMeta ? mGrpColumnsWithMeta : mGrpColumns, "grpId='" + grpId.toStdString() + "'", "");
if(c)
{
std::vector<RsNxsGrp*> grps;
locked_retrieveGroups(c, grps);
locked_retrieveGroups(c, grps, withMeta ? mColGrp_WithMetaOffset : 0);
if(!grps.empty())
{
@ -1085,38 +1094,10 @@ int RsDataService::retrieveNxsGrps(std::map<RsGxsGroupId, RsNxsGrp *> &grp, bool
std::cerr << "RsDataService::retrieveNxsGrps() " << mDbName << ", Requests: " << requestedGroups << ", Results: " << resultCount << ", Time: " << timer.duration() << std::endl;
#endif
if(withMeta && !grp.empty())
{
std::map<RsGxsGroupId, RsGxsGrpMetaData*> metaMap;
std::map<RsGxsGroupId, RsNxsGrp *>::iterator mit = grp.begin();
for(; mit != grp.end(); ++mit)
metaMap.insert(std::make_pair(mit->first, (RsGxsGrpMetaData*)(NULL)));
retrieveGxsGrpMetaData(metaMap);
mit = grp.begin();
for(; mit != grp.end(); ++mit)
{
RsNxsGrp* grpPtr = grp[mit->first];
grpPtr->metaData = metaMap[mit->first];
#ifdef RS_DATA_SERVICE_DEBUG
std::cerr << "RsDataService::retrieveNxsGrps() GrpId: " << mit->first.toStdString();
std::cerr << " CircleType: " << (uint32_t) grpPtr->metaData->mCircleType;
std::cerr << " CircleId: " << grpPtr->metaData->mCircleId.toStdString();
std::cerr << std::endl;
#endif
}
#ifdef RS_DATA_SERVICE_DEBUG_TIME
std::cerr << "RsDataService::retrieveNxsGrps() " << mDbName << ", Time with meta: " << timer.duration() << std::endl;
#endif
}
return 1;
}
void RsDataService::locked_retrieveGroups(RetroCursor* c, std::vector<RsNxsGrp*>& grps){
void RsDataService::locked_retrieveGroups(RetroCursor* c, std::vector<RsNxsGrp*>& grps, int metaOffset){
if(c){
bool valid = c->moveToFirst();
@ -1127,6 +1108,9 @@ void RsDataService::locked_retrieveGroups(RetroCursor* c, std::vector<RsNxsGrp*>
// only add the latest grp info
if(g)
{
if (metaOffset) {
g->metaData = locked_getGrpMeta(*c, metaOffset);
}
grps.push_back(g);
}
valid = c->moveToNext();
@ -1143,8 +1127,6 @@ int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, b
GxsMsgReq::const_iterator mit = reqIds.begin();
GxsMsgReq metaReqIds;// collects metaReqIds if needed
for(; mit != reqIds.end(); ++mit)
{
@ -1158,15 +1140,11 @@ int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, b
RsStackMutex stack(mDbMutex);
RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, mMsgColumns, KEY_GRP_ID+ "='" + grpId.toStdString() + "'", "");
RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, withMeta ? mMsgColumnsWithMeta : mMsgColumns, KEY_GRP_ID+ "='" + grpId.toStdString() + "'", "");
if(c)
{
locked_retrieveMessages(c, msgSet);
#ifdef RS_DATA_SERVICE_DEBUG_TIME
resultCount += msgSet.size();
#endif
locked_retrieveMessages(c, msgSet, withMeta ? mColMsg_WithMetaOffset : 0);
}
delete c;
@ -1180,36 +1158,24 @@ int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, b
RsStackMutex stack(mDbMutex);
RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, mMsgColumns, KEY_GRP_ID+ "='" + grpId.toStdString()
RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, withMeta ? mMsgColumnsWithMeta : mMsgColumns, KEY_GRP_ID+ "='" + grpId.toStdString()
+ "' AND " + KEY_MSG_ID + "='" + msgId.toStdString() + "'", "");
if(c)
{
locked_retrieveMessages(c, msgSet);
#ifdef RS_DATA_SERVICE_DEBUG_TIME
resultCount += c->getResultCount();
#endif
locked_retrieveMessages(c, msgSet, withMeta ? mColMsg_WithMetaOffset : 0);
}
delete c;
}
}
#ifdef RS_DATA_SERVICE_DEBUG_TIME
resultCount += msgSet.size();
#endif
msg[grpId] = msgSet;
if(withMeta)
{
std::vector<RsGxsMessageId> msgIds;
std::vector<RsNxsMsg*>::iterator lit = msgSet.begin(),
lit_end = msgSet.end();
for(; lit != lit_end; ++lit)
msgIds.push_back( (*lit)->msgId );
metaReqIds[grpId] = msgIds;
}
msgSet.clear();
}
@ -1217,73 +1183,19 @@ int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, b
std::cerr << "RsDataService::retrieveNxsMsgs() " << mDbName << ", Requests: " << reqIds.size() << ", Results: " << resultCount << ", Time: " << timer.duration() << std::endl;
#endif
// tres expensive !?
if(withMeta)
{
GxsMsgMetaResult metaResult;
// request with meta ids so there is no chance of
// a mem leak being left over
retrieveGxsMsgMetaData(metaReqIds, metaResult);
GxsMsgResult::iterator mit2 = msg.begin(), mit2_end = msg.end();
for(; mit2 != mit2_end; ++mit2)
{
const RsGxsGroupId& grpId = mit2->first;
std::vector<RsNxsMsg*>& msgV = msg[grpId];
std::vector<RsNxsMsg*>::iterator lit = msgV.begin(),
lit_end = msgV.end();
// as retrieval only attempts to retrieve what was found this elimiates chance
// of a memory fault as all are assigned
for(; lit != lit_end; ++lit)
{
std::vector<RsGxsMsgMetaData*>& msgMetaV = metaResult[grpId];
std::vector<RsGxsMsgMetaData*>::iterator meta_lit = msgMetaV.begin();
RsNxsMsg* msgPtr = *lit;
for(; meta_lit != msgMetaV.end(); )
{
RsGxsMsgMetaData* meta = *meta_lit;
if(meta->mMsgId == msgPtr->msgId)
{
msgPtr->metaData = meta;
meta_lit = msgMetaV.erase(meta_lit);
}else{
++meta_lit;
}
}
}
std::vector<RsGxsMsgMetaData*>& msgMetaV = metaResult[grpId];
std::vector<RsGxsMsgMetaData*>::iterator meta_lit;
// clean up just in case, should not go in here
for(meta_lit = msgMetaV.begin(); meta_lit !=
msgMetaV.end(); )
{
RsGxsMsgMetaData* meta = *meta_lit;
delete meta;
meta_lit = msgMetaV.erase(meta_lit);
}
}
#ifdef RS_DATA_SERVICE_DEBUG_TIME
std::cerr << "RsDataService::retrieveNxsMsgs() " << mDbName << ", Time with meta: " << timer.duration() << std::endl;
#endif
}
return 1;
}
void RsDataService::locked_retrieveMessages(RetroCursor *c, std::vector<RsNxsMsg *> &msgs)
void RsDataService::locked_retrieveMessages(RetroCursor *c, std::vector<RsNxsMsg *> &msgs, int metaOffset)
{
bool valid = c->moveToFirst();
while(valid){
RsNxsMsg* m = locked_getMessage(*c);
if(m){
if (metaOffset) {
m->metaData = locked_getMsgMeta(*c, metaOffset);
}
msgs.push_back(m);
}
@ -1318,10 +1230,6 @@ int RsDataService::retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaRes
if (c)
{
locked_retrieveMsgMeta(c, metaSet);
#ifdef RS_DATA_SERVICE_DEBUG_TIME
resultCount += metaSet.size();
#endif
}
}else{
@ -1336,13 +1244,13 @@ int RsDataService::retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaRes
if (c)
{
locked_retrieveMsgMeta(c, metaSet);
}
}
}
#ifdef RS_DATA_SERVICE_DEBUG_TIME
resultCount += c->getResultCount();
resultCount += metaSet.size();
#endif
}
}
}
msgMeta[grpId] = metaSet;
}
@ -1361,7 +1269,7 @@ void RsDataService::locked_retrieveMsgMeta(RetroCursor *c, std::vector<RsGxsMsgM
{
bool valid = c->moveToFirst();
while(valid){
RsGxsMsgMetaData* m = locked_getMsgMeta(*c);
RsGxsMsgMetaData* m = locked_getMsgMeta(*c, 0);
if(m != NULL)
msgMeta.push_back(m);
@ -1402,7 +1310,7 @@ int RsDataService::retrieveGxsGrpMetaData(std::map<RsGxsGroupId, RsGxsGrpMetaDat
while(valid)
{
RsGxsGrpMetaData* g = locked_getGrpMeta(*c);
RsGxsGrpMetaData* g = locked_getGrpMeta(*c, 0);
if(g)
{
grp[g->mGroupId] = g;
@ -1431,7 +1339,7 @@ int RsDataService::retrieveGxsGrpMetaData(std::map<RsGxsGroupId, RsGxsGrpMetaDat
while(valid)
{
RsGxsGrpMetaData* g = locked_getGrpMeta(*c);
RsGxsGrpMetaData* g = locked_getGrpMeta(*c, 0);
if(g)
{

View file

@ -181,14 +181,15 @@ private:
* @param c cursor to result set
* @param msgs messages retrieved from cursor are stored here
*/
void locked_retrieveMessages(RetroCursor* c, std::vector<RsNxsMsg*>& msgs);
void locked_retrieveMessages(RetroCursor* c, std::vector<RsNxsMsg*>& msgs, int metaOffset);
/*!
* Retrieves all the grp results from a cursor
* @param c cursor to result set
* @param grps groups retrieved from cursor are stored here
* @param withMeta this initialise the metaData member of the nxsgroups retrieved
*/
void locked_retrieveGroups(RetroCursor* c, std::vector<RsNxsGrp*>& grps);
void locked_retrieveGroups(RetroCursor* c, std::vector<RsNxsGrp*>& grps, int metaOffset);
/*!
* Retrieves all the msg meta results from a cursor
@ -201,13 +202,13 @@ private:
* extracts a msg meta item from a cursor at its
* current position
*/
RsGxsMsgMetaData* locked_getMsgMeta(RetroCursor& c);
RsGxsMsgMetaData* locked_getMsgMeta(RetroCursor& c, int colOffset);
/*!
* extracts a grp meta item from a cursor at its
* current position
*/
RsGxsGrpMetaData* locked_getGrpMeta(RetroCursor& c);
RsGxsGrpMetaData* locked_getGrpMeta(RetroCursor& c, int colOffset);
/*!
* extracts a msg item from a cursor at its
@ -257,10 +258,12 @@ private:
std::list<std::string> mMsgColumns;
std::list<std::string> mMsgMetaColumns;
std::list<std::string> mMsgColumnsWithMeta;
std::list<std::string> mMsgIdColumn;
std::list<std::string> mGrpColumns;
std::list<std::string> mGrpMetaColumns;
std::list<std::string> mGrpColumnsWithMeta;
std::list<std::string> mGrpIdColumn;
// Message meta column
@ -287,6 +290,9 @@ private:
int mColMsg_MetaData;
int mColMsg_MsgId;
// Message columns with meta
int mColMsg_WithMetaOffset;
// Group meta columns
int mColGrpMeta_GrpId;
int mColGrpMeta_TimeStamp;
@ -319,6 +325,9 @@ private:
int mColGrp_NxsData;
int mColGrp_MetaData;
// Group columns with meta
int mColGrp_WithMetaOffset;
// Group id columns
int mColGrpId_GrpId;

View file

@ -33,6 +33,8 @@
#include "retroshare/rsgxsflags.h"
#include "retroshare/rsgxscircles.h"
#include "retroshare/rsgrouter.h"
#include "retroshare/rsidentity.h"
#include "retroshare/rspeers.h"
#include "rsgixs.h"
#include "rsgxsutil.h"
#include "rsserver/p3face.h"
@ -49,6 +51,14 @@
#define PRIV_GRP_OFFSET 16
#define GRP_OPTIONS_OFFSET 24
// Authentication key indices. Used to store them in a map
// these where originally flags, but used as indexes. Still, we need
// to keep their old values to ensure backward compatibility.
static const uint32_t INDEX_AUTHEN_IDENTITY = 0x00000010; // identity
static const uint32_t INDEX_AUTHEN_PUBLISH = 0x00000020; // publish key
static const uint32_t INDEX_AUTHEN_ADMIN = 0x00000040; // admin key
#define GXS_MASK "GXS_MASK_HACK"
//#define GEN_EXCH_DEBUG 1
@ -68,10 +78,10 @@ RsGenExchange::RsGenExchange(RsGeneralDataService *gds, RsNetworkExchangeService
mAuthenPolicy(authenPolicy),
MESSAGE_STORE_PERIOD(messageStorePeriod),
mCleaning(false),
mLastClean(time(NULL)),
mLastClean((int)time(NULL) - (int)(RSRandom::random_u32() % MSG_CLEANUP_PERIOD)), // this helps unsynchronising the checks for the different services
mMsgCleanUp(NULL),
mChecking(false),
mLastCheck(time(NULL)),
mLastCheck((int)time(NULL) - (int)(RSRandom::random_u32() % INTEGRITY_CHECK_PERIOD)), // this helps unsynchronising the checks for the different services
mIntegrityCheck(NULL),
CREATE_FAIL(0),
CREATE_SUCCESS(1),
@ -243,7 +253,7 @@ void RsGenExchange::tick()
}
else
{
mIntegrityCheck = new RsGxsIntegrityCheck(mDataStore);
mIntegrityCheck = new RsGxsIntegrityCheck(mDataStore,mGixs);
mIntegrityCheck->start();
mChecking = true;
}
@ -401,12 +411,12 @@ uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& privateKe
// group is self signing
// for the creation of group signature
// only public admin and publish keys are present in meta
uint32_t metaDataLen = meta->serial_size();
uint32_t metaDataLen = meta->serial_size(RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
uint32_t allGrpDataLen = metaDataLen + grp->grp.bin_len;
char* metaData = new char[metaDataLen];
char* allGrpData = new char[allGrpDataLen]; // msgData + metaData
meta->serialise(metaData, metaDataLen);
meta->serialise(metaData, metaDataLen,RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
// copy msg data and meta in allMsgData buffer
memcpy(allGrpData, grp->grp.bin_data, grp->grp.bin_len);
@ -416,7 +426,7 @@ uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& privateKe
bool ok = GxsSecurity::getSignature(allGrpData, allGrpDataLen, privAdminKey, adminSign);
// add admin sign to grpMeta
meta->signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_ADMIN] = adminSign;
meta->signSet.keySignSet[INDEX_AUTHEN_ADMIN] = adminSign;
RsTlvBinaryData grpData(mServType);
grpData.setBinData(allGrpData, allGrpDataLen);
@ -462,8 +472,10 @@ int RsGenExchange::createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBin
if ((!grpMeta.mAuthorId.isNull()) || checkAuthenFlag(pos, author_flag))
{
needIdentitySign = true;
#ifdef GEN_EXCH_DEBUG
std::cerr << "Needs Identity sign! (Service Flags)";
std::cerr << std::endl;
#endif
}
if (needIdentitySign)
@ -488,31 +500,33 @@ int RsGenExchange::createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBin
authorKey, sign))
{
id_ret = SIGN_SUCCESS;
mGixs->timeStampKey(grpMeta.mAuthorId) ;
signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign;
}
else
{
id_ret = SIGN_FAIL;
}
signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY] = sign;
}
else
{
mGixs->requestPrivateKey(grpMeta.mAuthorId);
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::createGroupSignatures(): ";
std::cerr << " ERROR AUTHOR KEY: " << grpMeta.mAuthorId
<< " is not Cached / available for Message Signing\n";
std::cerr << "RsGenExchange::createGroupSignatures(): Requestiong AUTHOR KEY";
std::cerr << std::endl;
#endif
id_ret = SIGN_FAIL_TRY_LATER;
}
}
else
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::createGroupSignatures()";
std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl;
#endif
id_ret = SIGN_FAIL;
}
}
@ -532,8 +546,10 @@ int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinar
bool publishSignSuccess = false;
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::createMsgSignatures() for Msg.mMsgName: " << msgMeta.mMsgName;
std::cerr << std::endl;
#endif
// publish signature is determined by whether group is public or not
@ -568,23 +584,29 @@ int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinar
if (checkAuthenFlag(pos, publish_flag))
{
needPublishSign = true;
#ifdef GEN_EXCH_DEBUG
std::cerr << "Needs Publish sign! (Service Flags)";
std::cerr << std::endl;
#endif
}
// Check required permissions, and allow them to sign it - if they want too - as well!
if (checkAuthenFlag(pos, author_flag))
{
needIdentitySign = true;
#ifdef GEN_EXCH_DEBUG
std::cerr << "Needs Identity sign! (Service Flags)";
std::cerr << std::endl;
#endif
}
if (!msgMeta.mAuthorId.isNull())
{
needIdentitySign = true;
#ifdef GEN_EXCH_DEBUG
std::cerr << "Needs Identity sign! (AuthorId Exists)";
std::cerr << std::endl;
#endif
}
if(needPublishSign)
@ -609,12 +631,12 @@ int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinar
// private publish key
publishKey = &(mit->second);
RsTlvKeySignature publishSign = signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH];
RsTlvKeySignature publishSign = signSet.keySignSet[INDEX_AUTHEN_PUBLISH];
publishSignSuccess = GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len, *publishKey, publishSign);
//place signature in msg meta
signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH] = publishSign;
signSet.keySignSet[INDEX_AUTHEN_PUBLISH] = publishSign;
}else
{
std::cerr << "RsGenExchange::createMsgSignatures()";
@ -643,35 +665,36 @@ int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinar
mGixs->getPrivateKey(msgMeta.mAuthorId, authorKey);
RsTlvKeySignature sign;
if(GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len,
authorKey, sign))
if(GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len, authorKey, sign))
{
id_ret = SIGN_SUCCESS;
mGixs->timeStampKey(msgMeta.mAuthorId) ;
signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign;
}
else
{
id_ret = SIGN_FAIL;
}
signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY] = sign;
}
else
{
mGixs->requestPrivateKey(msgMeta.mAuthorId);
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::createMsgSignatures(): ";
std::cerr << " ERROR AUTHOR KEY: " << msgMeta.mAuthorId
<< " is not Cached / available for Message Signing\n";
std::cerr << "RsGenExchange::createMsgSignatures(): Requestiong AUTHOR KEY";
std::cerr << std::endl;
#endif
id_ret = SIGN_FAIL_TRY_LATER;
}
}
else
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::createMsgSignatures()";
std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl;
#endif
id_ret = SIGN_FAIL;
}
}
@ -763,7 +786,7 @@ int RsGenExchange::createMessage(RsNxsMsg* msg)
}
}
int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecurityKeySet& grpKeySet)
int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uint32_t& signFlag, RsTlvSecurityKeySet& grpKeySet)
{
bool needIdentitySign = false;
bool needPublishSign = false;
@ -796,12 +819,16 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecu
if ((checkAuthenFlag(pos, author_flag)) || (!msg->metaData->mAuthorId.isNull()))
needIdentitySign = true;
#ifdef GEN_EXCH_DEBUG
std::cerr << "Validate message: msgId=" << msg->msgId << ", grpId=" << msg->grpId << " grpFlags=" << std::hex << grpFlag << std::dec
<< ". Need publish=" << needPublishSign << ", needIdentitySign=" << needIdentitySign ;
#endif
RsGxsMsgMetaData& metaData = *(msg->metaData);
if(needPublishSign)
{
RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH];
RsTlvKeySignature sign = metaData.signSet.keySignSet[INDEX_AUTHEN_PUBLISH];
std::map<RsGxsId, RsTlvSecurityKey>& keys = grpKeySet.keys;
std::map<RsGxsId, RsTlvSecurityKey>::iterator mit = keys.begin();
@ -856,8 +883,7 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecu
if (auth_key_fetched)
{
RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY];
RsTlvKeySignature sign = metaData.signSet.keySignSet[INDEX_AUTHEN_IDENTITY];
idValidate &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey);
mGixs->timeStampKey(metaData.mAuthorId) ;
}
@ -869,11 +895,48 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecu
idValidate = false;
}
}else
if(idValidate)
{
// get key data and check that the key is actually PGP-linked. If not, reject the post.
RsIdentityDetails details ;
if(!mGixs->getIdDetails(metaData.mAuthorId,details))
{
// the key cannot ke reached, although it's in cache. Weird situation.
std::cerr << "RsGenExchange::validateMsg(): cannot get key data for ID=" << metaData.mAuthorId << ", although it's supposed to be already in cache. Cannot validate." << std::endl;
idValidate = false ;
}
else
{
// now check reputation of the message author
float reputation_threshold = ( (signFlag & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) && !(details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED)) ? (RsReputations::REPUTATION_THRESHOLD_ANTI_SPAM): (RsReputations::REPUTATION_THRESHOLD_DEFAULT) ;
if(details.mReputation.mOverallReputationScore < reputation_threshold)
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation score (" << details.mReputation.mOverallReputationScore <<") is below the accepted threshold (" << reputation_threshold << ")" << std::endl;
#endif
idValidate = false ;
}
#ifdef GEN_EXCH_DEBUG
else
std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", accepted. Reputation score (" << details.mReputation.mOverallReputationScore <<") is above accepted threshold (" << reputation_threshold << ")" << std::endl;
#endif
}
}
}
else
{
std::list<RsPeerId> peers;
peers.push_back(msg->PeerId());
mGixs->requestKey(metaData.mAuthorId, peers);
#ifdef GEN_EXCH_DEBUG
std::cerr << ", Key missing. Retry later." << std::endl;
#endif
return VALIDATE_FAIL_TRY_LATER;
}
}
@ -890,6 +953,10 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecu
idValidate = true;
}
#ifdef GEN_EXCH_DEBUG
std::cerr << ", publish val=" << publishValidate << ", idValidate=" << idValidate << ". Result=" << (publishValidate && idValidate) << std::endl;
#endif
if(publishValidate && idValidate)
return VALIDATE_SUCCESS;
else
@ -899,7 +966,6 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecu
int RsGenExchange::validateGrp(RsNxsGrp* grp)
{
bool needIdentitySign = false, idValidate = false;
RsGxsGrpMetaData& metaData = *(grp->metaData);
@ -907,12 +973,16 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp)
PrivacyBitPos pos = GRP_OPTION_BITS;
#ifdef GEN_EXCH_DEBUG
std::cerr << "Validating group " << grp->grpId << ", authorId = " << metaData.mAuthorId << std::endl;
#endif
// Check required permissions, and allow them to sign it - if they want too - as well!
if ((!metaData.mAuthorId.isNull()) || checkAuthenFlag(pos, author_flag))
{
needIdentitySign = true;
std::cerr << "Needs Identity sign! (Service Flags)";
std::cerr << std::endl;
#ifdef GEN_EXCH_DEBUG
std::cerr << " Needs Identity sign! (Service Flags). Identity signing key is " << metaData.mAuthorId << std::endl;
#endif
}
if(needIdentitySign)
@ -923,6 +993,9 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp)
if(haveKey)
{
#ifdef GEN_EXCH_DEBUG
std::cerr << " have ID key in cache: yes" << std::endl;
#endif
RsTlvSecurityKey authorKey;
bool auth_key_fetched = mGixs->getKey(metaData.mAuthorId, authorKey) ;
@ -930,9 +1003,12 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp)
if (auth_key_fetched)
{
RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY];
RsTlvKeySignature sign = metaData.signSet.keySignSet[INDEX_AUTHEN_IDENTITY];
idValidate = GxsSecurity::validateNxsGrp(*grp, sign, authorKey);
#ifdef GEN_EXCH_DEBUG
std::cerr << " key ID validation result: " << idValidate << std::endl;
#endif
mGixs->timeStampKey(metaData.mAuthorId) ;
}
else
@ -945,6 +1021,10 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp)
}else
{
#ifdef GEN_EXCH_DEBUG
std::cerr << " have key in cache: no. Return VALIDATE_LATER" << std::endl;
std::cerr << " requesting key " << metaData.mAuthorId << " to origin peer " << grp->PeerId() << std::endl;
#endif
std::list<RsPeerId> peers;
peers.push_back(grp->PeerId());
mGixs->requestKey(metaData.mAuthorId, peers);
@ -954,7 +1034,7 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp)
else
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl;
std::cerr << " (EE) Gixs not enabled while request identity signature validation!" << std::endl;
#endif
idValidate = false;
}
@ -1135,7 +1215,6 @@ bool RsGenExchange::getGroupMeta(const uint32_t &token, std::list<RsGroupMetaDat
return ok;
}
bool RsGenExchange::getMsgMeta(const uint32_t &token,
GxsMsgMetaMap &msgInfo)
{
@ -1152,7 +1231,6 @@ bool RsGenExchange::getMsgMeta(const uint32_t &token,
{
std::vector<RsGxsMsgMetaData*>& metaV = mit->second;
msgInfo[mit->first] = std::vector<RsMsgMetaData>();
std::vector<RsMsgMetaData>& msgInfoV = msgInfo[mit->first];
std::vector<RsGxsMsgMetaData*>::iterator vit = metaV.begin();
@ -1181,7 +1259,6 @@ bool RsGenExchange::getMsgRelatedMeta(const uint32_t &token, GxsMsgRelatedMetaMa
{
std::vector<RsGxsMsgMetaData*>& metaV = mit->second;
msgMeta[mit->first] = std::vector<RsMsgMetaData>();
std::vector<RsMsgMetaData>& msgInfoV = msgMeta[mit->first];
std::vector<RsGxsMsgMetaData*>::iterator vit = metaV.begin();
@ -1265,14 +1342,14 @@ bool RsGenExchange::getMsgData(const uint32_t &token, GxsMsgDataMap &msgItems)
RS_STACK_MUTEX(mGenMtx) ;
NxsMsgDataResult msgResult;
bool ok = mDataAccess->getMsgData(token, msgResult);
NxsMsgDataResult::iterator mit = msgResult.begin();
if(ok)
{
NxsMsgDataResult::iterator mit = msgResult.begin();
for(; mit != msgResult.end(); ++mit)
{
std::vector<RsGxsMsgItem*> gxsMsgItems;
const RsGxsGroupId& grpId = mit->first;
std::vector<RsGxsMsgItem*>& gxsMsgItems = msgItems[grpId];
std::vector<RsNxsMsg*>& nxsMsgsV = mit->second;
std::vector<RsNxsMsg*>::iterator vit = nxsMsgsV.begin();
for(; vit != nxsMsgsV.end(); ++vit)
@ -1305,7 +1382,6 @@ bool RsGenExchange::getMsgData(const uint32_t &token, GxsMsgDataMap &msgItems)
}
delete msg;
}
msgItems[grpId] = gxsMsgItems;
}
}
return ok;
@ -1317,17 +1393,15 @@ bool RsGenExchange::getMsgRelatedData(const uint32_t &token, GxsMsgRelatedDataMa
NxsMsgRelatedDataResult msgResult;
bool ok = mDataAccess->getMsgRelatedData(token, msgResult);
if(ok)
{
NxsMsgRelatedDataResult::iterator mit = msgResult.begin();
for(; mit != msgResult.end(); ++mit)
{
std::vector<RsGxsMsgItem*> gxsMsgItems;
const RsGxsGrpMsgIdPair& msgId = mit->first;
std::vector<RsGxsMsgItem*> &gxsMsgItems = msgItems[msgId];
std::vector<RsNxsMsg*>& nxsMsgsV = mit->second;
std::vector<RsNxsMsg*>::iterator vit
= nxsMsgsV.begin();
std::vector<RsNxsMsg*>::iterator vit = nxsMsgsV.begin();
for(; vit != nxsMsgsV.end(); ++vit)
{
RsNxsMsg*& msg = *vit;
@ -1360,15 +1434,11 @@ bool RsGenExchange::getMsgRelatedData(const uint32_t &token, GxsMsgRelatedDataMa
delete msg;
}
msgItems[msgId] = gxsMsgItems;
}
}
return ok;
}
RsTokenService* RsGenExchange::getTokenService()
{
return mDataAccess;
@ -1467,6 +1537,9 @@ void RsGenExchange::notifyNewMessages(std::vector<RsNxsMsg *>& messages)
}
else
{
#ifdef GEN_EXCH_DEBUG
std::cerr << " message is already in pending validation list. dropping." << std::endl;
#endif
delete msg;
}
}
@ -1763,8 +1836,10 @@ bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpC
grpMeta = mit->second;
if (!grpMeta)
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::processGrpMask() Ignore update for not existing grp id " << grpId.toStdString();
std::cerr << std::endl;
#endif
return false;
}
ok = true;
@ -1937,6 +2012,10 @@ void RsGenExchange::publishMsgs()
msgId = msg->msgId;
grpId = msg->grpId;
msg->metaData->recvTS = time(NULL);
mRoutingClues[msg->metaData->mAuthorId].insert(rsPeers->getOwnId()) ;
mTrackingClues.push_back(std::make_pair(msg->msgId,rsPeers->getOwnId())) ;
computeHash(msg->msg, msg->metaData->mHash);
mDataAccess->addMsgData(msg);
msgChangeMap[grpId].push_back(msgId);
@ -2074,9 +2153,14 @@ void RsGenExchange::processRoutingClues()
for(std::map<RsGxsId,std::set<RsPeerId> >::const_iterator it = mRoutingClues.begin();it!=mRoutingClues.end();++it)
for(std::set<RsPeerId>::const_iterator it2(it->second.begin());it2!=it->second.end();++it2)
rsGRouter->addRoutingClue(GRouterKeyId(it->first),(*it2)) ;
rsGRouter->addRoutingClue(GRouterKeyId(it->first),(*it2) ) ;
mRoutingClues.clear() ;
for(std::list<std::pair<RsGxsMessageId,RsPeerId> >::const_iterator it = mTrackingClues.begin();it!=mTrackingClues.end();++it)
rsGRouter->addTrackingInfo((*it).first,(*it).second) ;
mTrackingClues.clear() ;
}
void RsGenExchange::processGroupDelete()
{
@ -2263,9 +2347,9 @@ void RsGenExchange::publishGrps()
if(create == CREATE_SUCCESS)
{
uint32_t mdSize = grp->metaData->serial_size();
uint32_t mdSize = grp->metaData->serial_size(RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
char* metaData = new char[mdSize];
serialOk = grp->metaData->serialise(metaData, mdSize);
serialOk = grp->metaData->serialise(metaData, mdSize,RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
grp->meta.setBinData(metaData, mdSize);
delete[] metaData;
@ -2291,6 +2375,12 @@ void RsGenExchange::publishGrps()
}
else if(ret == SERVICE_CREATE_FAIL_TRY_LATER)
{
// if the service is not ready yet, reset the start timestamp to give the service more time
// the service should have it's own timeout mechanism
// services should return SERVICE_CREATE_FAIL if the action timed out
// at the moment this is only important for the idservice:
// the idservice may ask the user for a password, and the user needs time
ggps.mStartTS = now;
create = CREATE_FAIL_TRY_LATER;
}
else if(ret == SERVICE_CREATE_FAIL)
@ -2525,14 +2615,18 @@ void RsGenExchange::processRecvdMessages()
#ifdef GEN_EXCH_DEBUG
std::cerr << " msg info : grp id=" << msg->grpId << ", msg id=" << msg->msgId << std::endl;
#endif
RsGxsGrpMetaData* grpMeta = NULL ;
// validate msg
if(mit != grpMetas.end())
{
RsGxsGrpMetaData* grpMeta = mit->second;
validateReturn = validateMsg(msg, grpMeta->mGroupFlags, grpMeta->keys);
grpMeta = mit->second;
validateReturn = validateMsg(msg, grpMeta->mGroupFlags, grpMeta->mSignFlags, grpMeta->keys);
#ifdef GEN_EXCH_DEBUG
std::cerr << " message validation result: " << validateReturn << std::endl;
std::cerr << " grpMeta.mSignFlags: " << std::hex << grpMeta->mSignFlags << std::dec << std::endl;
std::cerr << " grpMeta.mAuthFlags: " << std::hex << grpMeta->mAuthenFlags << std::dec << std::endl;
std::cerr << " message validation result: " << (int)validateReturn << std::endl;
#endif
}
@ -2562,6 +2656,19 @@ void RsGenExchange::processRecvdMessages()
if(!msg->metaData->mAuthorId.isNull())
mRoutingClues[msg->metaData->mAuthorId].insert(msg->PeerId()) ;
if(grpMeta->mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES)
mTrackingClues.push_back(std::make_pair(msg->msgId,msg->PeerId())) ;
}
if(validateReturn == VALIDATE_FAIL)
{
// In this case, we notify the network exchange service not to DL the message again, at least not yet.
#ifdef GEN_EXCH_DEBUG
std::cerr << "Notifying the network service to not download this message again." << std::endl;
#endif
mNetService->rejectMessage(msg->msgId) ;
}
}
else
@ -2576,7 +2683,7 @@ void RsGenExchange::processRecvdMessages()
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "failed to deserialise incoming meta, msgId: "
std::cerr << "Validation failed for message id "
<< "msg->grpId: " << msg->grpId << ", msgId: " << msg->msgId << std::endl;
#endif
@ -2669,10 +2776,12 @@ void RsGenExchange::processRecvdGroups()
if(deserialOk)
{
#ifdef GEN_EXCH_DEBUG
std::cerr << " processing validation for group " << meta->mGroupId << ", attempts number " << gpsi.mAttempts << std::endl;
#endif
grp->metaData = meta;
uint8_t ret = validateGrp(grp);
if(ret == VALIDATE_SUCCESS)
{
meta->mGroupStatus = GXS_SERV::GXS_GRP_STATUS_UNPROCESSED | GXS_SERV::GXS_GRP_STATUS_UNREAD;
@ -2710,8 +2819,7 @@ void RsGenExchange::processRecvdGroups()
else if(ret == VALIDATE_FAIL)
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "failed to deserialise incoming meta, grpId: "
<< grp->grpId << std::endl;
std::cerr << " failed to validate incoming meta, grpId: " << grp->grpId << ": wrong signature" << std::endl;
#endif
delete grp;
erase = true;
@ -2720,14 +2828,16 @@ void RsGenExchange::processRecvdGroups()
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "failed to validate incoming grp, trying again. grpId: "
<< grp->grpId << std::endl;
std::cerr << " failed to validate incoming grp, trying again. grpId: " << grp->grpId << std::endl;
#endif
if(gpsi.mAttempts == VALIDATE_MAX_ATTEMPTS)
{
delete grp;
erase = true;
#ifdef GEN_EXCH_DEBUG
std::cerr << " max attempts " << VALIDATE_MAX_ATTEMPTS << " reached. Will delete group " << grp->grpId << std::endl;
#endif
}
else
{
@ -2737,6 +2847,7 @@ void RsGenExchange::processRecvdGroups()
}
else
{
std::cerr << "(EE) deserialise error in group meta data" << std::endl;
delete grp;
delete meta;
erase = true;
@ -2821,7 +2932,7 @@ void RsGenExchange::performUpdateValidation()
bool RsGenExchange::updateValid(RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp) const
{
std::map<SignType, RsTlvKeySignature>& signSet = newGrp.metaData->signSet.keySignSet;
std::map<SignType, RsTlvKeySignature>::iterator mit = signSet.find(GXS_SERV::FLAG_AUTHEN_ADMIN);
std::map<SignType, RsTlvKeySignature>::iterator mit = signSet.find(INDEX_AUTHEN_ADMIN);
if(mit == signSet.end())
{
@ -2900,7 +3011,9 @@ void RsGenExchange::removeDeleteExistingMessages( RsGeneralDataService::MsgStore
{
const RsGxsMessageId::std_vector& msgIds = msgIdReq[cit2->second->mGroupId];
#ifdef GEN_EXCH_DEBUG
std::cerr << " grpid=" << cit2->second->mGroupId << ", msgid=" << cit2->second->mMsgId ;
#endif
// Avoid storing messages that are already in the database, as well as messages that are too old (or generally do not pass the database storage test)
//

View file

@ -739,12 +739,13 @@ private:
/*!
* Attempts to validate msg signatures
* @param msg message to be validated
* @param grpFlag the flag for the group the message belongs to
* @param grpFlag the distribution flag for the group the message belongs to
* @param grpFlag the signature flag for the group the message belongs to
* @param grpKeySet the key set user has for the message's group
* @return VALIDATE_SUCCESS for success, VALIDATE_FAIL for fail,
* VALIDATE_ID_SIGN_NOT_AVAIL for Id sign key not avail (but requested)
*/
int validateMsg(RsNxsMsg* msg, const uint32_t& grpFlag, RsTlvSecurityKeySet& grpKeySet);
int validateMsg(RsNxsMsg* msg, const uint32_t& grpFlag, const uint32_t &signFlag, RsTlvSecurityKeySet& grpKeySet);
/*!
* Attempts to validate group signatures
@ -862,7 +863,7 @@ private:
std::vector<GroupDeletePublish> mGroupDeletePublish;
std::map<RsGxsId,std::set<RsPeerId> > mRoutingClues ;
std::list<std::pair<RsGxsMessageId,RsPeerId> > mTrackingClues ;
};
#endif // RSGENEXCHANGE_H

View file

@ -162,6 +162,7 @@ public:
*/
virtual bool getKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0;
virtual bool getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0; // For signing outgoing messages.
virtual bool getIdDetails(const RsGxsId& id, RsIdentityDetails& details) = 0 ; // Proxy function so that we get p3Identity info from Gxs
};
class GixsReputation

View file

@ -33,7 +33,7 @@ RsGxsGrpMetaData::RsGxsGrpMetaData()
clear();
}
uint32_t RsGxsGrpMetaData::serial_size()
uint32_t RsGxsGrpMetaData::serial_size(uint32_t api_version)
{
uint32_t s = 8; // header size
@ -49,7 +49,12 @@ uint32_t RsGxsGrpMetaData::serial_size()
s += 4; // for mCircleType
s += mCircleId.serial_size();
s += 4; // mAuthenFlag
s += mParentGrpId.serial_size();
s += mParentGrpId.serial_size(); // mParentGroupId
if(api_version == RS_GXS_GRP_META_DATA_VERSION_ID_0002)
s += 4; // mSignFlag
else if(api_version != RS_GXS_GRP_META_DATA_VERSION_ID_0001)
std::cerr << "(EE) wrong/unknown API version " << api_version << " requested in RsGxsGrpMetaData::serial_size()" << std::endl;
return s;
}
@ -91,10 +96,9 @@ void RsGxsGrpMetaData::clear(){
mHash.clear() ;
}
bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize)
bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize,uint32_t api_version)
{
uint32_t tlvsize = serial_size() ;
uint32_t tlvsize = serial_size(api_version) ;
uint32_t offset = 0;
if (pktsize < tlvsize)
@ -104,7 +108,7 @@ bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize)
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, 0, tlvsize);
ok &= setRsItemHeader(data, tlvsize, api_version, tlvsize);
#ifdef GXS_DEBUG
std::cerr << "RsGxsGrpMetaData serialise()" << std::endl;
@ -130,6 +134,8 @@ bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize)
ok &= signSet.SetTlv(data, tlvsize, &offset);
ok &= keys.SetTlv(data, tlvsize, &offset);
if(api_version == RS_GXS_GRP_META_DATA_VERSION_ID_0002)
ok &= setRawUInt32(data, tlvsize, &offset, mSignFlags); // new in API v2. Was previously missing. Kept in the end for backward compatibility
return ok;
}
@ -154,12 +160,31 @@ bool RsGxsGrpMetaData::deserialise(void *data, uint32_t &pktsize)
ok &= getRawUInt32(data, pktsize, &offset, &mPublishTs);
ok &= getRawUInt32(data, pktsize, &offset, &mCircleType);
ok &= getRawUInt32(data, pktsize, &offset, &mAuthenFlags);
ok &= mAuthorId.deserialise(data, pktsize, offset);
ok &= GetTlvString(data, pktsize, &offset, 0, mServiceString);
ok &= mCircleId.deserialise(data, pktsize, offset);
ok &= signSet.GetTlv(data, pktsize, &offset);
ok &= keys.GetTlv(data, pktsize, &offset);
switch(getRsItemId(data))
{
case RS_GXS_GRP_META_DATA_VERSION_ID_0002: ok &= getRawUInt32(data, pktsize, &offset, &mSignFlags); // current API
break ;
case RS_GXS_GRP_META_DATA_VERSION_ID_0001: mSignFlags = 0; // old API. Do not leave this uninitialised!
break ;
default:
std::cerr << "(EE) RsGxsGrpMetaData::deserialise(): ERROR: unknown API version " << std::hex << getRsItemId(data) << std::dec << std::endl;
}
if(offset != pktsize)
{
std::cerr << "(EE) RsGxsGrpMetaData::deserialise(): ERROR: unmatched size " << offset << ", expected: " << pktsize << std::dec << std::endl;
return false ;
}
#ifdef DROP_NON_CANONICAL_ITEMS
if(mGroupName.length() > RsGxsGrpMetaData::MAX_ALLOWED_STRING_SIZE)
{
@ -202,8 +227,8 @@ uint32_t RsGxsMsgMetaData::serial_size()
s += signSet.TlvSize();
s += GetTlvStringSize(mMsgName);
s += 4;
s += 4;
s += 4; // mPublishTS
s += 4; // mMsgFlags
return s;
}
@ -239,7 +264,7 @@ bool RsGxsMsgMetaData::serialise(void *data, uint32_t *size)
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, 0, tlvsize);
ok &= setRsItemHeader(data, tlvsize, RS_GXS_MSG_META_DATA_VERSION_ID_0002, tlvsize);
#ifdef GXS_DEBUG
std::cerr << "RsGxsGrpMetaData serialise()" << std::endl;

View file

@ -37,6 +37,13 @@
class RsGroupMetaData;
class RsMsgMetaData;
static const uint32_t RS_GXS_GRP_META_DATA_VERSION_ID_0001 = 0x0000 ; // change this, and keep old values if the content changes
static const uint32_t RS_GXS_GRP_META_DATA_VERSION_ID_0002 = 0xaf01 ; // current API
static const uint32_t RS_GXS_MSG_META_DATA_VERSION_ID_0002 = 0x0000 ; // current API
static const uint32_t RS_GXS_GRP_META_DATA_CURRENT_API_VERSION = RS_GXS_GRP_META_DATA_VERSION_ID_0002;
class RsGxsGrpMetaData
{
public:
@ -44,15 +51,15 @@ public:
RsGxsGrpMetaData();
bool deserialise(void *data, uint32_t &pktsize);
bool serialise(void* data, uint32_t &pktsize);
uint32_t serial_size();
bool serialise(void* data, uint32_t &pktsize, uint32_t api_version);
uint32_t serial_size(uint32_t api_version);
void clear();
void operator =(const RsGroupMetaData& rMeta);
RsGxsGroupId mGroupId;
RsGxsGroupId mOrigGrpId;
std::string mGroupName;
uint32_t mGroupFlags;
uint32_t mGroupFlags; // GXS_SERV::FLAG_PRIVACY_RESTRICTED | GXS_SERV::FLAG_PRIVACY_PRIVATE | GXS_SERV::FLAG_PRIVACY_PUBLIC
uint32_t mPublishTs;
uint32_t mSignFlags;
RsGxsId mAuthorId;
@ -123,7 +130,6 @@ public:
uint32_t recvTS;
RsFileHash mHash;
bool validated;
};

View file

@ -448,7 +448,7 @@ bool RsGxsDataAccess::getGroupData(const uint32_t& token, std::list<RsNxsGrp*>&
if(gmreq)
{
grpData = gmreq->mGroupData;
grpData.swap(gmreq->mGroupData);
gmreq->mGroupData.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
}else{
@ -480,7 +480,7 @@ bool RsGxsDataAccess::getMsgData(const uint32_t& token, NxsMsgDataResult& msgDat
if(mdreq)
{
msgData = mdreq->mMsgData;
msgData.swap(mdreq->mMsgData);
mdreq->mMsgData.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
}
@ -517,7 +517,7 @@ bool RsGxsDataAccess::getMsgRelatedData(const uint32_t &token, NxsMsgRelatedData
if(mrireq)
{
msgData = mrireq->mMsgDataResult;
msgData.swap(mrireq->mMsgDataResult);
mrireq->mMsgDataResult.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
}
@ -551,7 +551,7 @@ bool RsGxsDataAccess::getMsgSummary(const uint32_t& token, GxsMsgMetaResult& msg
if(mmreq)
{
msgInfo = mmreq->mMsgMetaData;
msgInfo.swap(mmreq->mMsgMetaData);
mmreq->mMsgMetaData.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
@ -591,7 +591,7 @@ bool RsGxsDataAccess::getMsgRelatedSummary(const uint32_t &token, MsgRelatedMeta
if(mrireq)
{
msgMeta = mrireq->mMsgMetaResult;
msgMeta.swap(mrireq->mMsgMetaResult);
mrireq->mMsgMetaResult.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
}
@ -630,7 +630,7 @@ bool RsGxsDataAccess::getMsgRelatedList(const uint32_t &token, MsgRelatedIdResul
if(mrireq)
{
msgIds = mrireq->mMsgIdResult;
msgIds.swap(mrireq->mMsgIdResult);
mrireq->mMsgIdResult.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
}
@ -664,7 +664,7 @@ bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds)
if(mireq)
{
msgIds = mireq->mMsgIdResult;
msgIds.swap(mireq->mMsgIdResult);
mireq->mMsgIdResult.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
}
@ -697,7 +697,7 @@ bool RsGxsDataAccess::getGroupList(const uint32_t& token, std::list<RsGxsGroupId
if(gireq)
{
groupIds = gireq->mGroupIdResult;
groupIds.swap(gireq->mGroupIdResult);
gireq->mGroupIdResult.clear();
locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE);
@ -1032,31 +1032,25 @@ bool RsGxsDataAccess::getGroupList(const std::list<RsGxsGroupId>& grpIdsIn, cons
bool RsGxsDataAccess::getMsgData(MsgDataReq* req)
{
GxsMsgResult result;
GxsMsgReq msgIdOut;
// filter based on options
getMsgList(req->mMsgIds, req->Options, msgIdOut);
mDataStore->retrieveNxsMsgs(msgIdOut, result, true, true);
mDataStore->retrieveNxsMsgs(msgIdOut, req->mMsgData, true, true);
req->mMsgData = result;
return true;
}
bool RsGxsDataAccess::getMsgSummary(MsgMetaReq* req)
{
GxsMsgMetaResult result;
GxsMsgReq msgIdOut;
// filter based on options
getMsgList(req->mMsgIds, req->Options, msgIdOut);
mDataStore->retrieveGxsMsgMetaData(msgIdOut, result);
req->mMsgMetaData = result;
mDataStore->retrieveGxsMsgMetaData(msgIdOut, req->mMsgMetaData);
return true;
}
@ -1558,7 +1552,7 @@ bool RsGxsDataAccess::getGroupStatistic(GroupStatisticRequest *req)
req->mGroupStatistic.mNumChildMsgsNew = 0;
req->mGroupStatistic.mNumChildMsgsUnread = 0;
for(int i = 0; i < msgMetaV.size(); ++i)
for(uint32_t i = 0; i < msgMetaV.size(); ++i)
{
RsGxsMsgMetaData* m = msgMetaV[i];
req->mGroupStatistic.mTotalSizeOfMsgs += m->mMsgSize + m->serial_size();
@ -1609,7 +1603,7 @@ bool RsGxsDataAccess::getServiceStatistic(ServiceStatisticRequest *req)
for(; mit != grpMeta.end(); ++mit)
{
RsGxsGrpMetaData* m = mit->second;
req->mServiceStatistic.mSizeOfGrps += m->mGrpSize + m->serial_size();
req->mServiceStatistic.mSizeOfGrps += m->mGrpSize + m->serial_size(RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
if (IS_GROUP_SUBSCRIBED(m->mSubscribeFlags))
{

File diff suppressed because it is too large Load diff

View file

@ -55,6 +55,7 @@ class RsGroupNetworkStatsRecord
std::set<RsPeerId> suppliers ;
uint32_t max_visible_count ;
time_t update_TS ;
};
/*!
@ -151,6 +152,8 @@ public:
*/
virtual void subscribeStatusChanged(const RsGxsGroupId& id,bool subscribed) ;
virtual void rejectMessage(const RsGxsMessageId& msg_id) ;
/* p3Config methods */
public:
@ -317,6 +320,12 @@ private:
*/
void handleRecvSyncGroup(RsNxsSyncGrpReqItem* item);
/*!
* Handles an nxs item for group statistics
* @param item contaims update time stamp and number of messages
*/
void handleRecvSyncGrpStatistics(RsNxsSyncGrpStatsItem *grs);
/*!
* Handles an nxs item for msgs synchronisation
* @param item contaims msg sync info
@ -357,6 +366,7 @@ private:
void locked_pushGrpRespFromList(std::list<RsNxsItem*>& respList, const RsPeerId& peer, const uint32_t& transN);
void locked_pushMsgRespFromList(std::list<RsNxsItem*>& itemL, const RsPeerId& sslId, const uint32_t& transN);
void syncWithPeers();
void syncGrpStatistics();
void addGroupItemToList(NxsTransaction*& tr,
const RsGxsGroupId& grpId, uint32_t& transN,
std::list<RsNxsItem*>& reqList);
@ -368,6 +378,7 @@ private:
void locked_doMsgUpdateWork(const RsNxsTransacItem* nxsTrans, const RsGxsGroupId& grpId);
void updateServerSyncTS();
void updateClientSyncTS();
bool locked_CanReceiveUpdate(const RsNxsSyncGrpReqItem *item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem* item);
@ -442,6 +453,10 @@ private:
*/
bool encryptTransaction(NxsTransaction *tr);
bool decryptTransaction(NxsTransaction *tr);
void cleanRejectedMessages();
void processObserverNotifications();
private:
@ -480,6 +495,7 @@ private:
uint32_t mSyncTs;
uint32_t mLastKeyPublishTs;
uint32_t mLastCleanRejectedMessages;
const uint32_t mSYNC_PERIOD;
int mUpdateCounter ;
@ -517,6 +533,11 @@ private:
RsGxsServerGrpUpdateItem* mGrpServerUpdateItem;
RsServiceInfo mServiceInfo;
std::map<RsGxsMessageId,time_t> mRejectedMessages;
std::vector<RsNxsGrp*> mNewGroupsToNotify ;
std::vector<RsNxsMsg*> mNewMessagesToNotify ;
void debugDump();
};
#endif // RSGXSNETSERVICE_H

View file

@ -99,7 +99,7 @@ bool MsgRespPending::accepted()
GixsReputation rep;
if(getAuthorRep(rep, entry.mAuthorId, mPeerId))
{
if(rep.score > mCutOff)
if(rep.score >= mCutOff)
{
entry.mPassedVetting = true;
count++;
@ -134,7 +134,7 @@ bool GrpRespPending::accepted()
if(getAuthorRep(rep, entry.mAuthorId, mPeerId))
{
if(rep.score > mCutOff)
if(rep.score >= mCutOff)
{
entry.mPassedVetting = true;
count++;

View file

@ -27,8 +27,13 @@
#include "rsgxsutil.h"
#include "retroshare/rsgxsflags.h"
#include "retroshare/rspeers.h"
#include "pqi/pqihash.h"
#include "gxs/rsgixs.h"
static const uint32_t MAX_GXS_IDS_REQUESTS_NET = 10 ; // max number of requests from cache/net (avoids killing the system!)
//#define GXSUTIL_DEBUG 1
RsGxsMessageCleanUp::RsGxsMessageCleanUp(RsGeneralDataService* const dataService, uint32_t messageStorePeriod, uint32_t chunkSize)
: mDs(dataService), MESSAGE_STORE_PERIOD(messageStorePeriod), CHUNK_SIZE(chunkSize)
@ -106,9 +111,8 @@ bool RsGxsMessageCleanUp::clean()
return mGrpMeta.empty();
}
RsGxsIntegrityCheck::RsGxsIntegrityCheck(
RsGeneralDataService* const dataService) :
mDs(dataService), mDone(false), mIntegrityMutex("integrity")
RsGxsIntegrityCheck::RsGxsIntegrityCheck(RsGeneralDataService* const dataService, RsGixs *gixs) :
mDs(dataService), mDone(false), mIntegrityMutex("integrity"),mGixs(gixs)
{ }
void RsGxsIntegrityCheck::run()
@ -118,7 +122,6 @@ void RsGxsIntegrityCheck::run()
bool RsGxsIntegrityCheck::check()
{
// first take out all the groups
std::map<RsGxsGroupId, RsNxsGrp*> grp;
mDs->retrieveNxsGrps(grp, true, true);
@ -126,6 +129,9 @@ bool RsGxsIntegrityCheck::check()
GxsMsgReq msgIds;
GxsMsgReq grps;
std::set<RsGxsId> used_gxs_ids ;
std::set<RsGxsGroupId> subscribed_groups ;
// compute hash and compare to stored value, if it fails then simply add it
// to list
std::map<RsGxsGroupId, RsNxsGrp*>::iterator git = grp.begin();
@ -144,12 +150,27 @@ bool RsGxsIntegrityCheck::check()
{
// store the group for retrieveNxsMsgs
grps[grp->grpId];
if(grp->metaData->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
{
subscribed_groups.insert(git->first) ;
if(!grp->metaData->mAuthorId.isNull())
{
#ifdef GXSUTIL_DEBUG
std::cerr << "TimeStamping group authors' key ID " << grp->metaData->mAuthorId << " in group ID " << grp->grpId << std::endl;
#endif
used_gxs_ids.insert(grp->metaData->mAuthorId) ;
}
}
}
else
{
msgIds.erase(msgIds.find(grp->grpId));
// grpsToDel.push_back(grp->grpId);
// grpsToDel.push_back(grp->grpId);
}
}
else
{
@ -216,6 +237,13 @@ bool RsGxsIntegrityCheck::check()
std::cerr << "(EE) deleting message data with wrong hash or null meta data. meta=" << (void*)msg->metaData << std::endl;
msgsToDel[msg->grpId].push_back(msg->msgId);
}
else if(!msg->metaData->mAuthorId.isNull() && subscribed_groups.find(msg->metaData->mGroupId)!=subscribed_groups.end())
{
#ifdef GXSUTIL_DEBUG
std::cerr << "TimeStamping message authors' key ID " << msg->metaData->mAuthorId << " in message " << msg->msgId << ", group ID " << msg->grpId<< std::endl;
#endif
used_gxs_ids.insert(msg->metaData->mAuthorId) ;
}
delete msg;
}
@ -233,6 +261,66 @@ bool RsGxsIntegrityCheck::check()
}
mDeletedMsgs = msgsToDel;
#ifdef GXSUTIL_DEBUG
std::cerr << "At end of pass, this is the list used GXS ids: " << std::endl;
std::cerr << " requesting them to GXS identity service to enforce loading." << std::endl;
#endif
std::list<RsPeerId> connected_friends ;
rsPeers->getOnlineList(connected_friends) ;
std::vector<RsGxsId> gxs_ids ;
for(std::set<RsGxsId>::const_iterator it(used_gxs_ids.begin());it!=used_gxs_ids.end();++it)
{
gxs_ids.push_back(*it) ;
#ifdef GXSUTIL_DEBUG
std::cerr << " " << *it << std::endl;
#endif
}
int nb_requested_not_in_cache = 0;
#ifdef GXSUTIL_DEBUG
std::cerr << " issuing random get on friends for non existing IDs" << std::endl;
#endif
// now request a cache update for them, which triggers downloading from friends, if missing.
for(;nb_requested_not_in_cache<MAX_GXS_IDS_REQUESTS_NET && gxs_ids.size()>0;)
{
uint32_t n = RSRandom::random_u32() % gxs_ids.size() ;
#ifdef GXSUTIL_DEBUG
std::cerr << " requesting ID " << gxs_ids[n] ;
#endif
if(!mGixs->haveKey(gxs_ids[n])) // checks if we have it already in the cache (conservative way to ensure that we atually have it)
{
mGixs->requestKey(gxs_ids[n],connected_friends);
++nb_requested_not_in_cache ;
#ifdef GXSUTIL_DEBUG
std::cerr << " ... from cache/net" << std::endl;
#endif
}
else
{
#ifdef GXSUTIL_DEBUG
std::cerr << " ... already in cache" << std::endl;
#endif
// Note: we could time_stamp even in the case where the id is not cached. Anyway, it's not really a problem here, since IDs have a high chance of
// behing eventually stamped.
mGixs->timeStampKey(gxs_ids[n]) ;
}
gxs_ids[n] = gxs_ids[gxs_ids.size()-1] ;
gxs_ids.pop_back() ;
}
#ifdef GXSUTIL_DEBUG
std::cerr << " total actual cache requests: "<< nb_requested_not_in_cache << std::endl;
#endif
return true;
}

View file

@ -30,6 +30,8 @@
#include "serialiser/rsnxsitems.h"
#include "rsgds.h"
class RsGixs ;
/*!
* Handy function for cleaning out meta result containers
* @param container
@ -40,10 +42,9 @@ void freeAndClearContainerResource(Container container)
typename Container::iterator meta_it = container.begin();
for(; meta_it != container.end(); ++meta_it)
{
if(meta_it->second != NULL)
delete meta_it->second;
}
container.clear();
}
@ -112,7 +113,7 @@ public:
* @param chunkSize
* @param sleepPeriod
*/
RsGxsIntegrityCheck(RsGeneralDataService* const dataService);
RsGxsIntegrityCheck(RsGeneralDataService* const dataService, RsGixs *gixs);
bool check();
@ -129,6 +130,8 @@ private:
RsMutex mIntegrityMutex;
std::list<RsGxsGroupId> mDeletedGrps;
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > mDeletedMsgs;
RsGixs *mGixs ;
};
class GroupUpdate

View file

@ -127,6 +127,13 @@ public:
*/
virtual int sharePublishKey(const RsGxsGroupId& grpId,const std::set<RsPeerId>& peers)=0 ;
/*!
* \brief rejectMessage
* Tells the network exchange service to not download this message again, at least for some time (maybe 24h or more)
* in order to avoid cluttering the network pipe with copied of this rejected message.
* \param msgId
*/
virtual void rejectMessage(const RsGxsMessageId& msgId) =0;
};
#endif // RSGNP_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,261 @@
/*
* libretroshare/src/chat: distantchat.h
*
* Services for RetroShare.
*
* Copyright 2015 by Cyril Soler
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "csoler@users.sourceforge.net".
*
*/
#pragma once
// Generic tunnel service
//
// Preconditions:
// * the secured tunnel service takes care of:
// - tunnel health: tunnels are kept alive using special items, re-openned when necessary, etc.
// - transport: items are ACK-ed and re-sent if never received
// - encryption: items are all encrypted and authenticated using PFS(DH)+HMAC(sha1)+AES(128)
// * each tunnel is associated to a specific GXS id on both sides. Consequently, services that request tunnels from different IDs to a
// server for the same GXS id need to be handled correctly.
// * client services must register to the secured tunnel service if they want to use it.
// * multiple services can use the same tunnel. Items contain a service Id that is obtained when registering to the secured tunnel service.
//
// GUI
// * the GUI should show for each tunnel:
// - starting and ending GXS ids
// - tunnel status (DH ok, closed from distant peer, locally closed, etc)
// - amount of data that is transferred in the tunnel
// - number of pending items (and total size)
// - number ACKed items both ways.
//
// We can use an additional tab "Authenticated tunnels" in the statistics->turtle window for that purpose.
//
// Interaction with services:
//
// Services request tunnels from a given GXS id and to a given GXS id. When ready, they get a handle (type = RsGxsTunnelId)
//
// Services send data in the tunnel using the virtual peer id
//
// Data is send to a service ID (could be any existing service ID). The endpoint of the tunnel must register each service, in order to
// allow the data to be transmitted/sent from/to that service. Otherwise an error is issued.
//
// Encryption
// * the whole tunnel traffic is encrypted using AES-128 with random IV
// * a random key is established using DH key exchange for each connection (establishment of a new virtual peer)
// * encrypted items are authenticated with HMAC(sha1).
// * DH public keys are the only chunks of data that travel un-encrypted along the tunnel. They are
// signed to avoid any MITM interactions. No time-stamp is used in DH exchange since a replay attack would not work.
//
// Algorithms
//
// * we need two layers: the turtle layer, and the GXS id layer.
// - for each pair of GXS ids talking, a single turtle tunnel is used
// - that tunnel can be shared by multiple services using it.
// - services are responsoble for asking tunnels and also droppping them when unused.
// - at the turtle layer, the tunnel will be effectively closed only when no service uses it.
// * IDs
// TurtleVirtualPeerId:
// - Used by tunnel service for each turtle tunnel
// - one virtual peer ID per GXS tunnel
//
// GxsTunnelId:
// - one GxsTunnelId per couple of GXS ids. But we also need to allow multiple services to use the tunnel.
//
// * at the turtle layer:
// - accept virtual peers from turtle tunnel service. The hash for that VP only depends on the server GXS id at server side, which is our
// own ID at server side, and destination ID at client side. What happens if two different clients request to talk to the same GXS id? (same hash)
// They should use different virtual peers, so it should be ok.
//
// Turtle hash: [ 0 ---------------15 16---19 ]
// Destination Random
//
// We Use 16 bytes to target the exact destination of the hash. The source part is just 4 arbitrary bytes that need to be different for all source
// IDs that come from the same peer, which is quite likely to be sufficient. The real source of the tunnel will make itself known when sending the
// DH key.
//
// * at the GXS layer
// - we should be able to have as many tunnels as they are different couples of GXS ids to interact. That means the tunnel should be determined
// by a mix between our own GXS id and the GXS id we're talking to. That is what the TunnelVirtualPeer is.
//
//
// RequestTunnel(source_own_id,destination_id) -
// | |
// +---------------------------> p3Turtle::monitorTunnels( hash(destination_id) ) |
// | |
// [Turtle async work] -------------------+ | Turtle layer: one virtual peer id
// | | |
// handleTunnelRequest() <-----------------------------------------------+ | |
// | | |
// +---------------- keep record in _gxs_tunnel_virtual_peer_id, initiate DH exchange | -
// | |
// handleDHPublicKey() <-----------------------------------------------------------------------------+ |
// | |
// +---------------- update _gxs_tunnel_contacts[ tunnel_hash = hash(own_id, destination_id) ] | GxsTunnelId level
// | |
// +---------------- notify client service that Peer(destination_id, tunnel_hash) is ready to talk to |
// -
#include <turtle/turtleclientservice.h>
#include <retroshare/rsgxstunnel.h>
#include <services/p3service.h>
#include <gxstunnel/rsgxstunnelitems.h>
class RsGixs ;
static const uint32_t GXS_TUNNEL_AES_KEY_SIZE = 16 ;
class p3GxsTunnelService: public RsGxsTunnelService, public RsTurtleClientService, public p3Service
{
public:
p3GxsTunnelService(RsGixs *pids) ;
virtual void connectToTurtleRouter(p3turtle *) ;
// Creates the invite if the public key of the distant peer is available.
// Om success, stores the invite in the map above, so that we can respond to tunnel requests.
//
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t service_id,uint32_t& error_code) ;
virtual bool closeExistingTunnel(const RsGxsTunnelId &tunnel_id,uint32_t service_id) ;
virtual bool getTunnelsInfo(std::vector<GxsTunnelInfo>& infos);
virtual bool getTunnelInfo(const RsGxsTunnelId& tunnel_id,GxsTunnelInfo& info);
virtual bool sendData(const RsGxsTunnelId& tunnel_id,uint32_t service_id,const uint8_t *data,uint32_t size) ;
virtual bool registerClientService(uint32_t service_id,RsGxsTunnelClientService *service) ;
// derived from p3service
virtual int tick();
virtual RsServiceInfo getServiceInfo();
private:
void flush() ;
virtual void handleIncomingItem(const RsGxsTunnelId &tunnel_id, RsGxsTunnelItem *) ;
class GxsTunnelPeerInfo
{
public:
GxsTunnelPeerInfo() : last_contact(0), last_keep_alive_sent(0), status(0), direction(0)
{
memset(aes_key, 0, GXS_TUNNEL_AES_KEY_SIZE);
total_sent = 0 ;
total_received = 0 ;
}
time_t last_contact ; // used to keep track of working connexion
time_t last_keep_alive_sent ; // last time we sent a keep alive packet.
unsigned char aes_key[GXS_TUNNEL_AES_KEY_SIZE] ;
uint32_t status ; // info: do we have a tunnel ?
RsPeerId virtual_peer_id; // given by the turtle router. Identifies the tunnel.
RsGxsId to_gxs_id; // gxs id we're talking to
RsGxsId own_gxs_id ; // gxs id we're using to talk.
RsTurtleGenericTunnelItem::Direction direction ; // specifiec wether we are client(managing the tunnel) or server.
TurtleFileHash hash ; // hash that is last used. This is necessary for handling tunnel establishment
std::set<uint32_t> client_services ;// services that used this tunnel
uint32_t total_sent ;
uint32_t total_received ;
};
class GxsTunnelDHInfo
{
public:
GxsTunnelDHInfo() : dh(0), direction(0), status(0) {}
DH *dh ;
RsGxsId gxs_id ;
RsGxsId own_gxs_id ;
RsGxsTunnelId tunnel_id ; // this is a proxy, since we cna always recompute that from the two previous values.
RsTurtleGenericTunnelItem::Direction direction ;
uint32_t status ;
TurtleFileHash hash ;
};
struct GxsTunnelData
{
RsGxsTunnelDataItem *data_item ;
time_t last_sending_attempt ;
};
// This maps contains the current peers to talk to with distant chat.
//
std::map<RsGxsTunnelId,GxsTunnelPeerInfo> _gxs_tunnel_contacts ; // current peers we can talk to
std::map<TurtleVirtualPeerId,GxsTunnelDHInfo> _gxs_tunnel_virtual_peer_ids ; // current virtual peers. Used to figure out tunnels, etc.
// List of items to be sent asap. Used to store items that we cannot pass directly to
// sendTurtleData(), because of Mutex protection.
std::map<uint64_t,GxsTunnelData> pendingGxsTunnelDataItems ; // items that need provable transport and encryption
std::list<RsGxsTunnelItem*> pendingGxsTunnelItems ; // items that do not need provable transport, yet need encryption
std::list<RsGxsTunnelDHPublicKeyItem*> pendingDHItems ;
// Overloaded from RsTurtleClientService
virtual bool handleTunnelRequest(const RsFileHash &hash,const RsPeerId& peer_id) ;
virtual void receiveTurtleData(RsTurtleGenericTunnelItem *item,const RsFileHash& hash,const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction) ;
void addVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&,RsTurtleGenericTunnelItem::Direction dir) ;
void removeVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&) ;
// session handling handles
void startClientGxsTunnelConnection(const RsGxsId &to_gxs_id, const RsGxsId& from_gxs_id, uint32_t service_id, RsGxsTunnelId &tunnel_id) ;
void locked_restartDHSession(const RsPeerId &virtual_peer_id, const RsGxsId &own_gxs_id) ;
// utility functions
static TurtleFileHash randomHashFromDestinationGxsId(const RsGxsId& destination) ;
static RsGxsId destinationGxsIdFromHash(const TurtleFileHash& sum) ;
// Cryptography management
void handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item) ;
bool locked_sendDHPublicKey(const DH *dh, const RsGxsId& own_gxs_id, const RsPeerId& virtual_peer_id) ;
bool locked_initDHSessionKey(DH *&dh);
TurtleVirtualPeerId virtualPeerIdFromHash(const TurtleFileHash& hash) ; // ... and to a hash for p3turtle
RsGxsTunnelId makeGxsTunnelId(const RsGxsId &own_id, const RsGxsId &distant_id) const; // creates a unique ID from two GXS ids.
// item handling
void handleRecvStatusItem(const RsGxsTunnelId& id,RsGxsTunnelStatusItem *item) ;
void handleRecvTunnelDataItem(const RsGxsTunnelId& id,RsGxsTunnelDataItem *item) ;
void handleRecvTunnelDataAckItem(const RsGxsTunnelId &id, RsGxsTunnelDataAckItem *item);
// Comunication with Turtle service
bool locked_sendEncryptedTunnelData(RsGxsTunnelItem *item) ;
bool locked_sendClearTunnelData(RsGxsTunnelDHPublicKeyItem *item); // this limits the usage to DH items. Others should be encrypted!
bool handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id) ;
// local data
p3turtle *mTurtle ;
RsGixs *mGixs ;
RsMutex mGxsTunnelMtx ;
uint64_t global_item_counter ;
std::map<uint32_t,RsGxsTunnelClientService*> mRegisteredServices ;
void debug_dump();
};

View file

@ -0,0 +1,486 @@
/*
* libretroshare/src/serialiser: rsbaseitems.cc
*
* RetroShare Serialiser.
*
* Copyright 2007-2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include <stdexcept>
#include <time.h>
#include "serialiser/rsbaseserial.h"
#include "serialiser/rstlvbase.h"
#include "util/rsprint.h"
#include "gxstunnel/rsgxstunnelitems.h"
//#define GXS_TUNNEL_ITEM_DEBUG 1
std::ostream& RsGxsTunnelDHPublicKeyItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsTunnelDHPublicKeyItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << " Signature Key ID: " << signature.keyId << std::endl ;
out << " Public Key ID: " << gxs_key.keyId << std::endl ;
printRsItemEnd(out, "RsGxsTunnelMsgItem", indent);
return out;
}
std::ostream& RsGxsTunnelDataItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsTunnelDataItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << " message id : " << std::hex << unique_item_counter << std::dec << std::endl ;
out << " service id : " << std::hex << service_id << std::dec << std::endl ;
out << " flags : " << std::hex << flags << std::dec << std::endl ;
out << " size : " << data_size << std::endl ;
out << " data : " << RsUtil::BinToHex(data,std::min(50u,data_size)) << ((data_size>50u)?"...":"") << std::endl ;
printRsItemEnd(out, "RsGxsTunnelDataItem", indent);
return out;
}
std::ostream& RsGxsTunnelDataAckItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsTunnelDataItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << " message id : " << std::hex << unique_item_counter << std::dec << std::endl ;
printRsItemEnd(out, "RsGxsTunnelDataAckItem", indent);
return out;
}
std::ostream& RsGxsTunnelStatusItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsTunnelDataItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << " flags : " << std::hex << status << std::dec << std::endl ;
printRsItemEnd(out, "RsGxsTunnelStatusItem", indent);
return out;
}
/*************************************************************************/
RsGxsTunnelDHPublicKeyItem::~RsGxsTunnelDHPublicKeyItem()
{
BN_free(public_key) ;
}
/*************************************************************************/
RsItem *RsGxsTunnelSerialiser::deserialise(void *data, uint32_t *pktsize)
{
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
#ifdef GXS_TUNNEL_ITEM_DEBUG
std::cerr << "deserializing packet..."<< std::endl ;
#endif
// look what we have...
if (*pktsize < rssize) /* check size */
{
std::cerr << "GxsTunnel deserialisation: not enough size: pktsize=" << *pktsize << ", rssize=" << rssize << std::endl ;
return NULL; /* not enough data */
}
/* set the packet length */
*pktsize = rssize;
/* ready to load */
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_GXS_TUNNEL != getRsItemService(rstype)))
{
#ifdef GXS_TUNNEL_ITEM_DEBUG
std::cerr << "GxsTunnel deserialisation: wrong type !" << std::endl ;
#endif
return NULL; /* wrong type */
}
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY: return deserialise_RsGxsTunnelDHPublicKeyItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA: return deserialise_RsGxsTunnelDataItem (data,*pktsize) ;
case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK: return deserialise_RsGxsTunnelDataAckItem (data,*pktsize) ;
case RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS: return deserialise_RsGxsTunnelStatusItem (data,*pktsize) ;
default:
std::cerr << "Unknown packet type in chat!" << std::endl ;
return NULL ;
}
}
/*************************************************************************/
uint32_t RsGxsTunnelDHPublicKeyItem::serial_size()
{
uint32_t s = 8 ; // header
s += 4 ; // BN size
s += BN_num_bytes(public_key) ; // public_key
s += signature.TlvSize() ; // signature
s += gxs_key.TlvSize() ; // gxs_key
return s ;
}
uint32_t RsGxsTunnelDataItem::serial_size()
{
uint32_t s = 8 ; // header
s += 8 ; // counter
s += 4 ; // flags
s += 4 ; // service id
s += 4 ; // data_size
s += data_size; // data
return s ;
}
uint32_t RsGxsTunnelDataAckItem::serial_size()
{
uint32_t s = 8 ; // header
s += 8 ; // counter
return s ;
}
uint32_t RsGxsTunnelStatusItem::serial_size()
{
uint32_t s = 8 ; // header
s += 4 ; // flags
return s ;
}
/*************************************************************************/
bool RsGxsTunnelDHPublicKeyItem::serialise(void *data,uint32_t& pktsize)
{
uint32_t tlvsize = serial_size() ;
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize);
/* skip the header */
offset += 8;
uint32_t s = BN_num_bytes(public_key) ;
ok &= setRawUInt32(data, tlvsize, &offset, s);
BN_bn2bin(public_key,&((unsigned char *)data)[offset]) ;
offset += s ;
ok &= signature.SetTlv(data, tlvsize, &offset);
ok &= gxs_key.SetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsGxsTunnelDHPublicKeyItem::serialiseItem() Size Error! offset=" << offset << ", tlvsize=" << tlvsize << std::endl;
}
return ok ;
}
bool RsGxsTunnelStatusItem::serialise(void *data, uint32_t& pktsize)
{
uint32_t tlvsize = serial_size() ;
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize);
#ifdef GXS_TUNNEL_ITEM_DEBUG
std::cerr << "RsGxsTunnelSerialiser serialising chat status item." << std::endl;
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Header: " << ok << std::endl;
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Size: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, status);
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Size Error! " << std::endl;
}
#ifdef GXS_TUNNEL_ITEM_DEBUG
std::cerr << "computed size: " << 256*((unsigned char*)data)[6]+((unsigned char*)data)[7] << std::endl ;
#endif
return ok;
}
bool RsGxsTunnelDataItem::serialise(void *dt, uint32_t& pktsize)
{
uint32_t tlvsize = serial_size() ;
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(dt, tlvsize, PacketId(), tlvsize);
#ifdef GXS_TUNNEL_ITEM_DEBUG
std::cerr << "RsGxsTunnelSerialiser serialising chat status item." << std::endl;
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Header: " << ok << std::endl;
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Size: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt64(dt, tlvsize, &offset, unique_item_counter);
ok &= setRawUInt32(dt, tlvsize, &offset, flags);
ok &= setRawUInt32(dt, tlvsize, &offset, service_id);
ok &= setRawUInt32(dt, tlvsize, &offset, data_size);
if(offset + data_size <= tlvsize)
{
memcpy(&((uint8_t*)dt)[offset],data,data_size) ;
offset += data_size ;
}
else
ok = false ;
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Size Error! " << std::endl;
}
return ok;
}
bool RsGxsTunnelDataAckItem::serialise(void *data, uint32_t& pktsize)
{
uint32_t tlvsize = serial_size() ;
uint32_t offset = 0;
if (pktsize < tlvsize)
return false; /* not enough space */
pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize);
#ifdef GXS_TUNNEL_ITEM_DEBUG
std::cerr << "RsGxsTunnelSerialiser serialising chat status item." << std::endl;
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Header: " << ok << std::endl;
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Size: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt64(data, tlvsize, &offset, unique_item_counter);
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsGxsTunnelSerialiser::serialiseItem() Size Error! " << std::endl;
}
return ok;
}
/*************************************************************************/
RsGxsTunnelDHPublicKeyItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelDHPublicKeyItem(void *data,uint32_t /*size*/)
{
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(data);
bool ok = true ;
RsGxsTunnelDHPublicKeyItem *item = new RsGxsTunnelDHPublicKeyItem() ;
uint32_t s=0 ;
/* get mandatory parts first */
ok &= getRawUInt32(data, rssize, &offset, &s);
item->public_key = BN_bin2bn(&((unsigned char *)data)[offset],s,NULL) ;
offset += s ;
ok &= item->signature.GetTlv(data, rssize, &offset) ;
ok &= item->gxs_key.GetTlv(data, rssize, &offset) ;
if (offset != rssize)
{
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Size error while deserializing." << std::endl ;
delete item ;
return NULL ;
}
if (!ok)
{
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Unknown error while deserializing." << std::endl ;
delete item ;
return NULL ;
}
return item ;
}
RsGxsTunnelDataItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelDataItem(void *dat,uint32_t size)
{
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(dat);
bool ok = true ;
RsGxsTunnelDataItem *item = new RsGxsTunnelDataItem();
/* get mandatory parts first */
ok &= getRawUInt64(dat, rssize, &offset, &item->unique_item_counter);
ok &= getRawUInt32(dat, rssize, &offset, &item->flags);
ok &= getRawUInt32(dat, rssize, &offset, &item->service_id);
ok &= getRawUInt32(dat, rssize, &offset, &item->data_size);
if(offset + item->data_size <= size)
{
item->data = (unsigned char*)malloc(item->data_size) ;
if(dat == NULL)
{
delete item ;
return NULL ;
}
memcpy(item->data,&((uint8_t*)dat)[offset],item->data_size) ;
offset += item->data_size ;
}
else
ok = false ;
if (offset != rssize)
{
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Size error while deserializing." << std::endl ;
delete item ;
return NULL ;
}
if (!ok)
{
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Unknown error while deserializing." << std::endl ;
delete item ;
return NULL ;
}
return item ;
}
RsGxsTunnelDataAckItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelDataAckItem(void *dat,uint32_t /* size */)
{
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(dat);
bool ok = true ;
RsGxsTunnelDataAckItem *item = new RsGxsTunnelDataAckItem();
/* get mandatory parts first */
ok &= getRawUInt64(dat, rssize, &offset, &item->unique_item_counter);
if (offset != rssize)
{
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Size error while deserializing." << std::endl ;
delete item ;
return NULL ;
}
if (!ok)
{
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Unknown error while deserializing." << std::endl ;
delete item ;
return NULL ;
}
return item ;
}
RsGxsTunnelStatusItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelStatusItem(void *dat,uint32_t size)
{
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(dat);
bool ok = true ;
RsGxsTunnelStatusItem *item = new RsGxsTunnelStatusItem();
/* get mandatory parts first */
ok &= getRawUInt32(dat, rssize, &offset, &item->status);
if (offset != rssize)
{
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Size error while deserializing." << std::endl ;
delete item ;
return NULL ;
}
if (!ok)
{
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Unknown error while deserializing." << std::endl ;
delete item ;
return NULL ;
}
return item ;
}

View file

@ -0,0 +1,177 @@
/*
* libretroshare/src/serialiser: rschatitems.h
*
* RetroShare Serialiser.
*
* Copyright 2007-2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#pragma once
#include <openssl/ssl.h>
#include "retroshare/rstypes.h"
#include "serialiser/rstlvkeys.h"
#include "serialiser/rsserviceids.h"
#include "serialiser/rsserial.h"
#include "serialiser/rstlvidset.h"
#include "serialiser/rstlvfileitem.h"
/* chat Flags */
const uint32_t RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION = 0x0400;
const uint32_t RS_GXS_TUNNEL_FLAG_ACK_DISTANT_CONNECTION = 0x0800;
const uint32_t RS_GXS_TUNNEL_FLAG_KEEP_ALIVE = 0x1000;
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DATA = 0x01 ;
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY = 0x02 ;
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS = 0x03 ;
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK = 0x04 ;
typedef uint64_t GxsTunnelDHSessionId ;
class RsGxsTunnelItem: public RsItem
{
public:
RsGxsTunnelItem(uint8_t item_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_GXS_TUNNEL,item_subtype)
{
setPriorityLevel(QOS_PRIORITY_RS_CHAT_ITEM) ;
}
virtual ~RsGxsTunnelItem() {}
virtual void clear() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) = 0 ;
virtual bool serialise(void *data,uint32_t& size) = 0 ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() = 0 ; // deserialise is handled using a constructor
};
/*!
* For sending distant communication data. The item is not encrypted after being serialised, but the data it.
* The MAC is computed over encrypted data using the PFS key. All other items (except DH keys) are serialised, encrypted, and
* sent as data in a RsGxsTunnelDataItem.
*
* @see p3GxsTunnelService
*/
class RsGxsTunnelDataItem: public RsGxsTunnelItem
{
public:
RsGxsTunnelDataItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DATA) { data=NULL ;data_size=0; }
RsGxsTunnelDataItem(uint8_t subtype) :RsGxsTunnelItem(subtype) { data=NULL ;data_size=0; }
virtual ~RsGxsTunnelDataItem() {}
virtual void clear() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
uint64_t unique_item_counter; // this allows to make the item unique
uint32_t flags; // mainly NEEDS_HACK?
uint32_t service_id ;
uint32_t data_size ; // encrypted data size
unsigned char *data ; // encrypted data
};
// Used to send status of connection. This can be closing orders, flushing orders, etc.
// These items are always sent encrypted.
class RsGxsTunnelStatusItem: public RsGxsTunnelItem
{
public:
RsGxsTunnelStatusItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS) {}
RsGxsTunnelStatusItem(void *data,uint32_t size) ; // deserialization
virtual ~RsGxsTunnelStatusItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
uint32_t status ;
};
// Used to confirm reception of an encrypted item.
class RsGxsTunnelDataAckItem: public RsGxsTunnelItem
{
public:
RsGxsTunnelDataAckItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK) {}
RsGxsTunnelDataAckItem(void *data,uint32_t size) ; // deserialization
virtual ~RsGxsTunnelDataAckItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
uint64_t unique_item_counter ; // unique identifier for that item
};
// This class contains the public Diffie-Hellman parameters to be sent
// when performing a DH agreement over a distant chat tunnel.
//
class RsGxsTunnelDHPublicKeyItem: public RsGxsTunnelItem
{
public:
RsGxsTunnelDHPublicKeyItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY) {}
RsGxsTunnelDHPublicKeyItem(void *data,uint32_t size) ; // deserialization
virtual ~RsGxsTunnelDHPublicKeyItem() ;
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
// Private data to DH public key item
//
BIGNUM *public_key ;
RsTlvKeySignature signature ; // signs the public key in a row.
RsTlvSecurityKey gxs_key ; // public key of the signer
private:
// make the object non copy-able
RsGxsTunnelDHPublicKeyItem(const RsGxsTunnelDHPublicKeyItem&) : RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY) {}
const RsGxsTunnelDHPublicKeyItem& operator=(const RsGxsTunnelDHPublicKeyItem&) { return *this ;}
};
class RsGxsTunnelSerialiser: public RsSerialType
{
public:
RsGxsTunnelSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_TUNNEL) {}
virtual uint32_t size (RsItem *item)
{
return static_cast<RsGxsTunnelItem *>(item)->serial_size() ;
}
virtual bool serialise(RsItem *item, void *data, uint32_t *size)
{
return static_cast<RsGxsTunnelItem *>(item)->serialise(data,*size) ;
}
RsItem *deserialise(void *data, uint32_t *pktsize);
private:
static RsGxsTunnelDataAckItem *deserialise_RsGxsTunnelDataAckItem (void *data, uint32_t size) ;
static RsGxsTunnelDataItem *deserialise_RsGxsTunnelDataItem (void *data, uint32_t size) ;
static RsGxsTunnelStatusItem *deserialise_RsGxsTunnelStatusItem (void *data, uint32_t size) ;
static RsGxsTunnelDHPublicKeyItem *deserialise_RsGxsTunnelDHPublicKeyItem(void *data, uint32_t size) ;
};

View file

@ -6,11 +6,7 @@ CONFIG += create_prl
CONFIG -= qt
TARGET = retroshare
TARGET_PRL = libretroshare
#GXS Stuff.
# This should be disabled for releases until further notice.
CONFIG += gxs
DESTDIR = lib
#CONFIG += dsdv
@ -77,15 +73,13 @@ SOURCES += tcponudp/udppeer.cc \
tcponudp/udpstunner.cc \
tcponudp/udprelay.cc \
DEFINES *= RS_USE_BITDHT
BITDHT_DIR = ../../libbitdht/src
DEPENDPATH += . $${BITDHT_DIR}
INCLUDEPATH += . $${BITDHT_DIR}
# The next line is for compliance with debian packages. Keep it!
INCLUDEPATH += ../libbitdht
DEFINES *= RS_USE_BITDHT
PRE_TARGETDEPS *= ../../libbitdht/src/lib/libbitdht.a
LIBS += ../../libbitdht/src/lib/libbitdht.a
PRE_TARGETDEPS *= $${BITDHT_DIR}/lib/libbitdht.a
LIBS *= $${BITDHT_DIR}/lib/libbitdht.a
}
@ -125,25 +119,14 @@ HEADERS += $$PUBLIC_HEADERS
################################# Linux ##########################################
linux-* {
# These two lines fixe compilation on ubuntu natty. Probably a ubuntu packaging error.
INCLUDEPATH += $$system(pkg-config --cflags glib-2.0 | sed -e "s/-I//g")
CONFIG += link_pkgconfig
OPENPGPSDK_DIR = ../../openpgpsdk/src
DEPENDPATH *= $${OPENPGPSDK_DIR} ../openpgpsdk
INCLUDEPATH *= $${OPENPGPSDK_DIR} ../openpgpsdk
DESTDIR = lib
QMAKE_CXXFLAGS *= -Wall -D_FILE_OFFSET_BITS=64
QMAKE_CC = g++
SSL_DIR = /usr/include/openssl
UPNP_DIR = /usr/include/upnp
DEPENDPATH += . $${SSL_DIR} $${UPNP_DIR}
INCLUDEPATH += . $${SSL_DIR} $${UPNP_DIR}
contains(CONFIG, NO_SQLCIPHER) {
DEFINES *= NO_SQLCIPHER
LIBS *= -lsqlite3
PKGCONFIG *= sqlite3
} else {
SQLCIPHER_OK = $$system(pkg-config --exists sqlcipher && echo yes)
isEmpty(SQLCIPHER_OK) {
@ -156,19 +139,21 @@ linux-* {
error("libsqlcipher is not installed and libsqlcipher.a not found. SQLCIPHER is necessary for encrypted database, to build with unencrypted database, run: qmake CONFIG+=NO_SQLCIPHER")
}
} else {
# Workaround for broken sqlcipher packages, e.g. Ubuntu 14.04
# https://bugs.launchpad.net/ubuntu/+source/sqlcipher/+bug/1493928
# PKGCONFIG *= sqlcipher
LIBS *= -lsqlcipher
}
}
#CONFIG += version_detail_bash_script
# linux/bsd can use either - libupnp is more complete and packaged.
#CONFIG += upnp_miniupnpc
CONFIG += upnp_libupnp
# Check if the systems libupnp has been Debian-patched
system(grep -E 'char[[:space:]]+PublisherUrl' $${UPNP_DIR}/upnp.h >/dev/null 2>&1) {
system(grep -E 'char[[:space:]]+PublisherUrl' /usr/include/upnp/upnp.h >/dev/null 2>&1) {
# Normal libupnp
} else {
# Patched libupnp or new unreleased version
@ -176,14 +161,14 @@ linux-* {
}
DEFINES *= UBUNTU
INCLUDEPATH += /usr/include/glib-2.0/ /usr/lib/glib-2.0/include
LIBS *= -lgnome-keyring
LIBS *= -lssl -lupnp -lixml
LIBS *= -lcrypto -lz -lpthread
PKGCONFIG *= gnome-keyring-1
PKGCONFIG *= libssl libupnp
PKGCONFIG *= libcrypto zlib
LIBS *= -lpthread -ldl
}
unix {
DEFINES *= LIB_DIR=\"\\\"$${LIB_DIR}\\\"\"
DEFINES *= PLUGIN_DIR=\"\\\"$${PLUGIN_DIR}\\\"\"
DEFINES *= DATA_DIR=\"\\\"$${DATA_DIR}\\\"\"
## where to put the librarys interface
@ -221,7 +206,6 @@ version_detail_bash_script {
win32-x-g++ {
OBJECTS_DIR = temp/win32xgcc/obj
DESTDIR = lib.win32xgcc
DEFINES *= WINDOWS_SYS WIN32 WIN_CROSS_UBUNTU
QMAKE_CXXFLAGS *= -Wmissing-include-dirs
QMAKE_CC = i586-mingw32msvc-g++
@ -245,10 +229,8 @@ win32 {
OBJECTS_DIR = temp/obj
MOC_DIR = temp/moc
DEFINES *= WINDOWS_SYS WIN32 STATICLIB MINGW WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T
DEFINES *= MINIUPNPC_VERSION=13
# This defines the platform to be WinXP or later and is needed for getaddrinfo (_WIN32_WINNT_WINXP)
DEFINES *= WINVER=0x0501
DESTDIR = lib
# Switch on extra warnings
QMAKE_CFLAGS += -Wextra
@ -268,11 +250,10 @@ win32 {
CONFIG += upnp_miniupnpc
LIBS_DIR = $$PWD/../../../libs
OPENPGPSDK_DIR = $$PWD/../../openpgpsdk/src
LIBS += -lsqlcipher
DEPENDPATH += . $$LIBS_DIR/include $$LIBS_DIR/include/miniupnpc $$OPENPGPSDK_DIR
INCLUDEPATH += . $$LIBS_DIR/include $$LIBS_DIR/include/miniupnpc $$OPENPGPSDK_DIR
DEPENDPATH += . $$INC_DIR
INCLUDEPATH += . $$INC_DIR
}
################################# MacOSX ##########################################
@ -282,29 +263,30 @@ mac {
OBJECTS_DIR = temp/obj
MOC_DIR = temp/moc
#DEFINES = WINDOWS_SYS WIN32 STATICLIB MINGW
#DEFINES *= MINIUPNPC_VERSION=13
DESTDIR = lib
DEFINES *= MINIUPNPC_VERSION=13
CONFIG += upnp_miniupnpc
CONFIG += c+11
# zeroconf disabled at the end of libretroshare.pro (but need the code)
CONFIG += zeroconf
CONFIG += zcnatassist
#CONFIG += zeroconf
#CONFIG += zcnatassist
# Beautiful Hack to fix 64bit file access.
QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dfopen64=fopen -Dvstatfs64=vstatfs
UPNPC_DIR = ../../../miniupnpc-1.0
#GPG_ERROR_DIR = ../../../../libgpg-error-1.7
#GPGME_DIR = ../../../../gpgme-1.1.8
OPENPGPSDK_DIR = ../../openpgpsdk/src
for(lib, LIB_DIR):LIBS += -L"$$lib"
for(bin, BIN_DIR):LIBS += -L"$$bin"
INCLUDEPATH += . $${UPNPC_DIR}
INCLUDEPATH += $${OPENPGPSDK_DIR}
DEPENDPATH += . $$INC_DIR
INCLUDEPATH += . $$INC_DIR
#../openpgpsdk
#INCLUDEPATH += . $${UPNPC_DIR} $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src
# We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database.
LIBS += /usr/local/lib/libsqlcipher.a
#LIBS += -lsqlite3
}
################################# FreeBSD ##########################################
@ -318,8 +300,6 @@ freebsd-* {
# linux/bsd can use either - libupnp is more complete and packaged.
#CONFIG += upnp_miniupnpc
CONFIG += upnp_libupnp
DESTDIR = lib
}
################################# OpenBSD ##########################################
@ -328,21 +308,32 @@ openbsd-* {
INCLUDEPATH *= /usr/local/include
INCLUDEPATH += $$system(pkg-config --cflags glib-2.0 | sed -e "s/-I//g")
OPENPGPSDK_DIR = ../../openpgpsdk/src
INCLUDEPATH *= $${OPENPGPSDK_DIR} ../openpgpsdk
QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dstat64=stat -Dstatvfs64=statvfs -Dfopen64=fopen
CONFIG += upnp_libupnp
}
################################# Haiku ##########################################
haiku-* {
QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dstat64=stat -Dstatvfs64=statvfs -Dfopen64=fopen
OPENPGPSDK_DIR = ../../openpgpsdk/src
INCLUDEPATH *= $${OPENPGPSDK_DIR} ../openpgpsdk
DEFINES *= NO_SQLCIPHER
CONFIG += release
CONFIG += upnp_libupnp
DESTDIR = lib
}
################################### COMMON stuff ##################################
# openpgpsdk
PRE_TARGETDEPS *= ../../openpgpsdk/src/lib/libops.a
LIBS *= ../../openpgpsdk/src/lib/libops.a -lbz2
OPENPGPSDK_DIR = ../../openpgpsdk/src
DEPENDPATH *= $${OPENPGPSDK_DIR}
INCLUDEPATH *= $${OPENPGPSDK_DIR}
PRE_TARGETDEPS *= $${OPENPGPSDK_DIR}/lib/libops.a
LIBS *= $${OPENPGPSDK_DIR}/lib/libops.a -lbz2
HEADERS += dbase/cachestrapper.h \
dbase/fimonitor.h \
@ -503,7 +494,8 @@ HEADERS += util/folderiterator.h \
util/rsmemcache.h \
util/rstickevent.h \
util/rsrecogn.h \
util/rsscopetimer.h
util/rsscopetimer.h \
util/stacktrace.h
SOURCES += dbase/cachestrapper.cc \
dbase/fimonitor.cc \
@ -696,12 +688,11 @@ SOURCES += zeroconf/p3zcnatassist.cc \
# new gxs cache system
# this should be disabled for releases until further notice.
gxs {
DEFINES *= RS_ENABLE_GXS
DEFINES *= SQLITE_HAS_CODEC
DEFINES *= GXS_ENABLE_SYNC_MSGS
HEADERS += serialiser/rsnxsitems.h \
DEFINES *= SQLITE_HAS_CODEC
DEFINES *= GXS_ENABLE_SYNC_MSGS
HEADERS += serialiser/rsnxsitems.h \
gxs/rsgds.h \
gxs/rsgxs.h \
gxs/rsdataservice.h \
@ -727,7 +718,7 @@ gxs {
gxs/rsgxsrequesttypes.h
SOURCES += serialiser/rsnxsitems.cc \
SOURCES += serialiser/rsnxsitems.cc \
gxs/rsdataservice.cc \
gxs/rsgenexchange.cc \
gxs/rsgxsnetservice.cc \
@ -743,48 +734,56 @@ gxs {
gxs/rsgxsutil.cc \
gxs/rsgxsrequesttypes.cc
# gxs tunnels
HEADERS += gxstunnel/p3gxstunnel.h \
gxstunnel/rsgxstunnelitems.h \
retroshare/rsgxstunnel.h
# Identity Service
HEADERS += retroshare/rsidentity.h \
SOURCES += gxstunnel/p3gxstunnel.cc \
gxstunnel/rsgxstunnelitems.cc
# Identity Service
HEADERS += retroshare/rsidentity.h \
gxs/rsgixs.h \
services/p3idservice.h \
serialiser/rsgxsiditems.h \
services/p3gxsreputation.h \
serialiser/rsgxsreputationitems.h \
SOURCES += services/p3idservice.cc \
SOURCES += services/p3idservice.cc \
serialiser/rsgxsiditems.cc \
services/p3gxsreputation.cc \
serialiser/rsgxsreputationitems.cc \
# GxsCircles Service
HEADERS += services/p3gxscircles.h \
# GxsCircles Service
HEADERS += services/p3gxscircles.h \
serialiser/rsgxscircleitems.h \
retroshare/rsgxscircles.h \
SOURCES += services/p3gxscircles.cc \
SOURCES += services/p3gxscircles.cc \
serialiser/rsgxscircleitems.cc \
# GxsForums Service
HEADERS += retroshare/rsgxsforums.h \
# GxsForums Service
HEADERS += retroshare/rsgxsforums.h \
services/p3gxsforums.h \
serialiser/rsgxsforumitems.h
SOURCES += services/p3gxsforums.cc \
SOURCES += services/p3gxsforums.cc \
serialiser/rsgxsforumitems.cc \
# GxsChannels Service
HEADERS += retroshare/rsgxschannels.h \
# GxsChannels Service
HEADERS += retroshare/rsgxschannels.h \
services/p3gxschannels.h \
services/p3gxscommon.h \
serialiser/rsgxscommentitems.h \
serialiser/rsgxschannelitems.h \
SOURCES += services/p3gxschannels.cc \
SOURCES += services/p3gxschannels.cc \
services/p3gxscommon.cc \
serialiser/rsgxscommentitems.cc \
serialiser/rsgxschannelitems.cc \
wikipoos {
# Wiki Service
HEADERS += retroshare/rswiki.h \
services/p3wiki.h \
@ -792,7 +791,9 @@ gxs {
SOURCES += services/p3wiki.cc \
serialiser/rswikiitems.cc \
}
gxsthewire {
# Wire Service
HEADERS += retroshare/rswire.h \
services/p3wire.h \
@ -800,17 +801,19 @@ gxs {
SOURCES += services/p3wire.cc \
serialiser/rswireitems.cc \
}
# Posted Service
HEADERS += services/p3postbase.h \
# Posted Service
HEADERS += services/p3postbase.h \
services/p3posted.h \
retroshare/rsposted.h \
serialiser/rsposteditems.h
SOURCES += services/p3postbase.cc \
SOURCES += services/p3postbase.cc \
services/p3posted.cc \
serialiser/rsposteditems.cc
gxsphotoshare {
#Photo Service
HEADERS += services/p3photoservice.h \
retroshare/rsphoto.h \
@ -859,5 +862,3 @@ test_bitdht {
# ENABLED UDP NOW.
}

View file

@ -125,7 +125,7 @@ std::string PGPKeyManagement::makeArmouredKey(const unsigned char *keydata,size_
uint32_t crc = compute24bitsCRC((unsigned char *)keydata,key_size) ;
unsigned char tmp[3] = { (crc >> 16) & 0xff, (crc >> 8) & 0xff, crc & 0xff } ;
unsigned char tmp[3] = { uint8_t((crc >> 16) & 0xff), uint8_t((crc >> 8) & 0xff), uint8_t(crc & 0xff) } ;
std::string crc_string ;
Radix64::encode((const char *)tmp,3,crc_string) ;

View file

@ -20,8 +20,8 @@ class RsCacheService: public CacheSource, public CacheStore, public p3Config
// Functions from p3config
//
virtual RsSerialiser *setupSerialiser() { return NULL ; }
virtual bool saveList(bool&, std::list<RsItem*>&) { return false ;}
virtual bool loadList(std::list<RsItem*>&) { return false ;}
virtual bool saveList(bool&, std::list<RsItem*>&) =0;
virtual bool loadList(std::list<RsItem*>&) =0;
private:
uint32_t _tick_delay_in_seconds ;

View file

@ -17,8 +17,8 @@ class RsPQIService: public p3Service, public p3Config
// Functions from p3config
//
virtual RsSerialiser *setupSerialiser() { return NULL ; }
virtual bool saveList(bool&, std::list<RsItem*>&) { return false ;}
virtual bool loadList(std::list<RsItem*>&) { return false ;}
virtual bool saveList(bool&, std::list<RsItem*>&) =0 ;
virtual bool loadList(std::list<RsItem*>&) =0 ;
private:
uint32_t _tick_delay_in_seconds ;

View file

@ -1,77 +0,0 @@
RS_TOP_DIR = ..
##### Define any flags that are needed for this section #######
###############################################################
###############################################################
include $(RS_TOP_DIR)/scripts/config.mk
###############################################################
BASE_OBJ = pqisecurity.o pqinetwork.o
#pqi_base.o
LOOP_OBJ = pqiloopback.o
STREAM_OBJ = pqistreamer.o pqiarchive.o pqistore.o pqibin.o
MGR_OBJ = pqimonitor.o p3dhtmgr.o p3connmgr.o p3cfgmgr.o p3authmgr.o
GRP_OBJ = pqiperson.o pqihandler.o pqiservice.o pqipersongrp.o
SSL_OBJ = pqissl.o pqissllistener.o pqisslpersongrp.o cleanupxpgp.o
UDP_OBJ = pqissludp.o
OTHER_OBJ = p3notify.o
TESTOBJ = net_test.o dht_test.o net_test1.o netiface_test.o
#conn_test.o
TESTS = net_test dht_test net_test1 netiface_test
#conn_test
ifdef PQI_USE_XPGP
SSL_OBJ += authxpgp.o
TESTOBJ += xpgp_id.o
TESTS += xpgp_id
else
ifdef PQI_USE_SSLONLY
SSL_OBJ += authssl.o
else
SSL_OBJ += authssl.o authgpg.o
TESTOBJ += gpgme_tst.o
TESTS += gpgme_tst
endif
endif
RSOBJ = $(BASE_OBJ) $(LOOP_OBJ) \
$(STREAM_OBJ) \
$(MGR_OBJ) \
$(SSL_OBJ) \
$(UDP_OBJ) \
$(GRP_OBJ) \
$(OTHER_OBJ)
all: librs tests
gpgme_tst: gpgme_tst.o
$(CC) $(CFLAGS) -o gpgme_tst gpgme_tst.o $(LIBS)
xpgp_id: xpgp_id.o
$(CC) $(CFLAGS) -o xpgp_id xpgp_id.o $(LIBS)
dht_test: dht_test.o
$(CC) $(CFLAGS) -o dht_test dht_test.o $(LIBS)
conn_test: conn_test.o
$(CC) $(CFLAGS) -o conn_test conn_test.o $(LIBS)
net_test: net_test.o
$(CC) $(CFLAGS) -o net_test net_test.o $(LIBS)
net_test1: net_test1.o
$(CC) $(CFLAGS) -o net_test1 net_test1.o $(LIBS)
netiface_test: netiface_test.o
$(CC) $(CFLAGS) -o netiface_test netiface_test.o $(LIBS)
###############################################################
include $(RS_TOP_DIR)/scripts/rules.mk
###############################################################

View file

@ -715,6 +715,7 @@ bool AuthGPG::loadList(std::list<RsItem*>& load)
}
delete (*it);
}
load.clear() ;
return true;
}

View file

@ -198,7 +198,7 @@ void tls_cleanup()
CRYPTO_set_locking_callback(NULL);
CRYPTO_set_id_callback(NULL);
if (mutex_buf == NULL) {
if (mutex_buf != NULL) {
for (int i = 0; i < CRYPTO_num_locks(); i++) {
pthread_mutex_destroy(&mutex_buf[i]);
}
@ -1705,6 +1705,7 @@ bool AuthSSLimpl::loadList(std::list<RsItem*>& load)
}
delete (*it);
}
load.clear() ;
return true;
}

View file

@ -208,7 +208,7 @@ p3Config::p3Config()
}
bool p3Config::loadConfiguration(RsFileHash &loadHash)
bool p3Config::loadConfiguration(RsFileHash& /* loadHash */)
{
return loadConfig();
}
@ -304,7 +304,11 @@ bool p3Config::loadAttempt(const std::string& cfgFname,const std::string& signFn
/* set hash */
setHash(bio->gethash());
BinMemInterface *signbio = new BinMemInterface(1000, BIN_FLAGS_READABLE);
std::string signatureRead;
RsFileHash strHash(Hash());
AuthSSL::getAuthSSL()->SignData(strHash.toByteArray(), RsFileHash::SIZE_IN_BYTES, signatureRead);
BinMemInterface *signbio = new BinMemInterface(signatureRead.size(), BIN_FLAGS_READABLE);
if(!signbio->readfromfile(signFname.c_str()))
{
@ -314,10 +318,6 @@ bool p3Config::loadAttempt(const std::string& cfgFname,const std::string& signFn
std::string signatureStored((char *) signbio->memptr(), signbio->memsize());
std::string signatureRead;
RsFileHash strHash(Hash());
AuthSSL::getAuthSSL()->SignData(strHash.toByteArray(), RsFileHash::SIZE_IN_BYTES, signatureRead);
delete signbio;
if(signatureRead != signatureStored)

View file

@ -34,6 +34,10 @@
#include "rsserver/p3face.h"
#include "util/rsstring.h"
/****
* #define HISTMGR_DEBUG 1
***/
// clean too old messages every 5 minutes
//
#define MSG_HISTORY_CLEANING_PERIOD 300
@ -99,15 +103,12 @@ void p3HistoryMgr::addMessage(const ChatMessage& cm)
enabled = true;
}
if (cm.chat_id.isGxsId() && mPrivateEnable == true) {
if (cm.incoming) {
peerName = cm.chat_id.toGxsId().toStdString();
} else {
if(cm.chat_id.isDistantChatId())
{
uint32_t status;
RsGxsId from_gxs_id;
if (rsMsgs->getDistantChatStatus(cm.chat_id.toGxsId(), status, &from_gxs_id))
peerName = from_gxs_id.toStdString();
}
DistantChatPeerInfo dcpinfo;
if (rsMsgs->getDistantChatStatus(cm.chat_id.toDistantChatId(), dcpinfo))
peerName = cm.chat_id.toPeerId().toStdString();
enabled = true;
}
@ -171,7 +172,9 @@ void p3HistoryMgr::cleanOldMessages()
{
RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/
#ifdef HISTMGR_DEBUG
std::cerr << "****** cleaning old messages." << std::endl;
#endif
time_t now = time(NULL) ;
bool changed = false ;
@ -185,7 +188,9 @@ void p3HistoryMgr::cleanOldMessages()
std::map<uint32_t, RsHistoryMsgItem*>::iterator lit2 = lit ;
++lit2 ;
#ifdef HISTMGR_DEBUG
std::cerr << " removing msg id " << lit->first << ", for peer id " << mit->first << std::endl;
#endif
delete lit->second ;
mit->second.erase(lit) ;
@ -201,7 +206,9 @@ void p3HistoryMgr::cleanOldMessages()
{
std::map<RsPeerId, std::map<uint32_t, RsHistoryMsgItem*> >::iterator mit2 = mit ;
++mit2 ;
#ifdef HISTMGR_DEBUG
std::cerr << " removing peer id " << mit->first << ", since it has no messages" << std::endl;
#endif
mMessages.erase(mit) ;
mit = mit2 ;
@ -300,13 +307,16 @@ bool p3HistoryMgr::loadList(std::list<RsItem*>& load)
RsHistoryMsgItem *msgItem;
std::list<RsItem*>::iterator it;
for (it = load.begin(); it != load.end(); ++it) {
for (it = load.begin(); it != load.end(); ++it)
{
if (NULL != (msgItem = dynamic_cast<RsHistoryMsgItem*>(*it))) {
std::map<RsPeerId, std::map<uint32_t, RsHistoryMsgItem*> >::iterator mit = mMessages.find(msgItem->chatPeerId);
msgItem->msgId = nextMsgId++;
#ifdef HISTMGR_DEBUG
std::cerr << "Loading msg history item: peer id=" << msgItem->chatPeerId << "), msg id =" << msgItem->msgId << std::endl;
#endif
if (mit != mMessages.end()) {
mit->second.insert(std::make_pair(msgItem->msgId, msgItem));
@ -344,7 +354,9 @@ bool p3HistoryMgr::loadList(std::list<RsItem*>& load)
if (sscanf(kit->value.c_str(), "%d", &val) == 1)
mMaxStorageDurationSeconds = val ;
#ifdef HISTMGR_DEBUG
std::cerr << "Loaded max storage time for history = " << val << " seconds" << std::endl;
#endif
continue;
}
@ -370,6 +382,7 @@ bool p3HistoryMgr::loadList(std::list<RsItem*>& load)
delete (*it);
}
load.clear() ;
return true;
}
@ -397,8 +410,8 @@ bool p3HistoryMgr::chatIdToVirtualPeerId(ChatId chat_id, RsPeerId &peer_id)
return true;
}
if (chat_id.isGxsId()) {
peer_id = RsPeerId(chat_id.toGxsId());
if (chat_id.isDistantChatId()) {
peer_id = RsPeerId(chat_id.toDistantChatId());
return true;
}
@ -436,7 +449,7 @@ bool p3HistoryMgr::getMessages(const ChatId &chatId, std::list<HistoryMsg> &msgs
if (chatId.isLobbyId() && mLobbyEnable == true) {
enabled = true;
}
if (chatId.isGxsId() && mPrivateEnable == true) {
if (chatId.isDistantChatId() && mPrivateEnable == true) {
enabled = true;
}
@ -446,7 +459,9 @@ bool p3HistoryMgr::getMessages(const ChatId &chatId, std::list<HistoryMsg> &msgs
if(!chatIdToVirtualPeerId(chatId, chatPeerId))
return false;
#ifdef HISTMGR_DEBUG
std::cerr << "Getting history for virtual peer " << chatPeerId << std::endl;
#endif
uint32_t foundCount = 0;
@ -467,7 +482,9 @@ bool p3HistoryMgr::getMessages(const ChatId &chatId, std::list<HistoryMsg> &msgs
}
}
}
#ifdef HISTMGR_DEBUG
std::cerr << msgs.size() << " messages added." << std::endl;
#endif
return true;
}
@ -497,7 +514,9 @@ void p3HistoryMgr::clear(const ChatId &chatId)
if(!chatIdToVirtualPeerId(chatId, chatPeerId))
return;
#ifdef HISTMGR_DEBUG
std::cerr << "********** p3History::clear()called for virtual peer id " << chatPeerId << std::endl;
#endif
std::map<RsPeerId, std::map<uint32_t, RsHistoryMsgItem*> >::iterator mit = mMessages.find(chatPeerId);
if (mit == mMessages.end()) {
@ -523,7 +542,9 @@ void p3HistoryMgr::removeMessages(const std::list<uint32_t> &msgIds)
std::list<uint32_t> removedIds;
std::list<uint32_t>::iterator iit;
#ifdef HISTMGR_DEBUG
std::cerr << "********** p3History::removeMessages called()" << std::endl;
#endif
{
RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/
@ -536,7 +557,9 @@ void p3HistoryMgr::removeMessages(const std::list<uint32_t> &msgIds)
std::map<uint32_t, RsHistoryMsgItem*>::iterator lit = mit->second.find(*iit);
if (lit != mit->second.end())
{
#ifdef HISTMGR_DEBUG
std::cerr << "**** Removing " << mit->first << " msg id = " << lit->first << std::endl;
#endif
delete(lit->second);
mit->second.erase(lit);

View file

@ -964,24 +964,25 @@ bool p3LinkMgrIMPL::connectResult(const RsPeerId &id, bool success, bool isIncom
if (flags == RS_NET_CONN_UDP_ALL)
{
#ifdef LINKMGR_DEBUG
#endif
std::cerr << "p3LinkMgrIMPL::connectResult() Sending Feedback for UDP connection";
std::cerr << std::endl;
#endif
if (success)
{
#ifdef LINKMGR_DEBUG
#endif
std::cerr << "p3LinkMgrIMPL::connectResult() UDP Update CONNECTED to: " << id;
std::cerr << std::endl;
#endif
mNetMgr->netAssistStatusUpdate(id, NETMGR_DHT_FEEDBACK_CONNECTED);
}
else
{
#ifdef LINKMGR_DEBUG
#endif
std::cerr << "p3LinkMgrIMPL::connectResult() UDP Update FAILED to: " << id;
std::cerr << std::endl;
#endif
/* have no differentiation between failure and closed? */
mNetMgr->netAssistStatusUpdate(id, NETMGR_DHT_FEEDBACK_CONN_FAILED);
@ -1570,129 +1571,90 @@ bool p3LinkMgrIMPL::tryConnectUDP(const RsPeerId &id, const struct sockaddr_st
/* push all available addresses onto the connect addr stack...
* with the following exceptions:
* - id is our own
* - id is not our friend
* - id is already connected
* - id is hidden but of an unkown type
* - we are hidden but id is not
*/
bool p3LinkMgrIMPL::retryConnectTCP(const RsPeerId &id)
{
/* Check if we should retry first */
{
RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/
/* push all available addresses onto the connect addr stack...
* with the following exceptions:
* - check local address, see if it is the same network as us
- check address age. don't add old ones
*/
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::retryConnectTCP() id: " << id << std::endl;
#endif
if (id == getOwnId())
if (id == getOwnId()) return false;
{
#ifdef LINKMGR_DEBUG
rslog(RSL_WARNING, p3connectzone, "p3LinkMgrIMPL::retryConnectTCP() Failed, connecting to own id: ");
#endif
return false;
RS_STACK_MUTEX(mLinkMtx);
std::map<RsPeerId, peerConnectState>::iterator it = mFriendList.find(id);
if ( it == mFriendList.end() ) return false;
if ( it->second.state & RS_PEER_S_CONNECTED ) return false;
}
/* look up the id */
std::map<RsPeerId, peerConnectState>::iterator it;
if (mFriendList.end() == (it = mFriendList.find(id)))
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::retryConnectTCP() Peer is not Friend" << std::endl;
#endif
return false;
}
// Extract the required info from p3PeerMgr
/* if already connected -> done */
if (it->second.state & RS_PEER_S_CONNECTED)
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::retryConnectTCP() Peer Already Connected" << std::endl;
#endif
return false;
}
} /****** END of LOCKED ******/
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::retryConnectTCP() Getting Address from PeerMgr for : " << id;
std::cerr << std::endl;
#endif
/* If we reach here, must retry .... extract the required info from p3PeerMgr */
/* first possibility - is it a hidden peer */
// first possibility - is it a hidden peer
if (mPeerMgr->isHiddenPeer(id))
{
/* check for valid hidden type */
uint32_t type = mPeerMgr->getHiddenType(id);
if ( type & (~RS_HIDDEN_TYPE_MASK) ) return false;
/* then we just have one connect attempt via the Proxy */
struct sockaddr_storage proxy_addr;
std::string domain_addr;
uint16_t domain_port;
/* then we just have one connect attempt via the Proxy */
if (mPeerMgr->getProxyAddress(id, proxy_addr, domain_addr, domain_port))
if ( mPeerMgr->getProxyAddress(id, proxy_addr, domain_addr, domain_port) )
{
RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/
std::map<RsPeerId, peerConnectState>::iterator it;
if (mFriendList.end() != (it = mFriendList.find(id)))
RS_STACK_MUTEX(mLinkMtx);
std::map<RsPeerId, peerConnectState>::iterator it = mFriendList.find(id);
if (it != mFriendList.end())
{
locked_ConnectAttempt_ProxyAddress(&(it->second), proxy_addr, domain_addr, domain_port);
locked_ConnectAttempt_ProxyAddress(&(it->second), type, proxy_addr, domain_addr, domain_port);
return locked_ConnectAttempt_Complete(&(it->second));
}
}
return false;
}
if (mPeerMgr->isHidden())
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::retryConnectTCP() isHidden(): no connection attempts for : " << id;
std::cerr << std::endl;
#endif
return false;
}
if (mPeerMgr->isHidden()) return false;
struct sockaddr_storage lAddr;
struct sockaddr_storage eAddr;
pqiIpAddrSet histAddrs;
std::string dyndns;
if (mPeerMgr->getConnectAddresses(id, lAddr, eAddr, histAddrs, dyndns))
{
RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/
RS_STACK_MUTEX(mLinkMtx);
std::map<RsPeerId, peerConnectState>::iterator it;
if (mFriendList.end() != (it = mFriendList.find(id)))
std::map<RsPeerId, peerConnectState>::iterator it = mFriendList.find(id);
if ( it != mFriendList.end() )
{
locked_ConnectAttempt_CurrentAddresses(&(it->second), lAddr, eAddr);
uint16_t dynPort = sockaddr_storage_port(eAddr);
if (!dynPort)
uint16_t dynPort = 0;
if (!sockaddr_storage_isnull(eAddr)) dynPort = sockaddr_storage_port(eAddr);
if (!dynPort && !sockaddr_storage_isnull(lAddr))
dynPort = sockaddr_storage_port(lAddr);
if (dynPort)
{
locked_ConnectAttempt_AddDynDNS(&(it->second), dyndns, dynPort);
}
locked_ConnectAttempt_HistoricalAddresses(&(it->second), histAddrs);
/* finish it off */
// finish it off
return locked_ConnectAttempt_Complete(&(it->second));
}
else
{
std::cerr << "p3LinkMgrIMPL::retryConnectTCP() ERROR failed to find friend data : " << id;
std::cerr << std::endl;
}
std::cerr << "p3LinkMgrIMPL::retryConnectTCP() ERROR failed to find friend data : " << id << std::endl;
}
else
{
std::cerr << "p3LinkMgrIMPL::retryConnectTCP() ERROR failed to addresses from PeerMgr for: " << id;
std::cerr << std::endl;
}
std::cerr << "p3LinkMgrIMPL::retryConnectTCP() ERROR failed to get addresses from PeerMgr for: " << id << std::endl;
return false;
}
@ -1719,13 +1681,8 @@ bool p3LinkMgrIMPL::locked_CheckPotentialAddr(const struct sockaddr_storage &ad
return false;
}
bool isValid = sockaddr_storage_isValidNet(addr);
bool isLoopback = sockaddr_storage_isLoopbackNet(addr);
// bool isPrivate = sockaddr_storage_isPrivateNet(addr);
bool isExternal = sockaddr_storage_isExternalNet(addr);
/* if invalid - quick rejection */
if (!isValid)
if ( ! sockaddr_storage_isValidNet(addr) )
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr() REJECTING - INVALID";
@ -1760,60 +1717,7 @@ bool p3LinkMgrIMPL::locked_CheckPotentialAddr(const struct sockaddr_storage &ad
return false ;
}
/* if it is an external address, we'll accept it.
* - even it is meant to be a local address.
*/
if (isExternal)
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr() ACCEPTING - EXTERNAL";
std::cerr << std::endl;
#endif
return true;
}
/* if loopback, then okay - probably proxy connection (or local testing).
*/
if (isLoopback)
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr() ACCEPTING - LOOPBACK";
std::cerr << std::endl;
#endif
return true;
}
/* get here, it is private or loopback
* - can only connect to these addresses if we are on the same subnet.
- check net against our local address.
*/
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr() Checking sameNet against: ";
std::cerr << sockaddr_storage_iptostring(mLocalAddress);
std::cerr << ")";
std::cerr << std::endl;
#endif
if (sockaddr_storage_samenet(mLocalAddress, addr))
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr() ACCEPTING - PRIVATE & sameNET";
std::cerr << std::endl;
#endif
return true;
}
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr() REJECTING - PRIVATE & !sameNET";
std::cerr << std::endl;
#endif
/* else it fails */
return false;
}
@ -2018,7 +1922,7 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_AddDynDNS(peerConnectState *peer, std
}
void p3LinkMgrIMPL::locked_ConnectAttempt_ProxyAddress(peerConnectState *peer, const struct sockaddr_storage &proxy_addr, const std::string &domain_addr, uint16_t domain_port)
void p3LinkMgrIMPL::locked_ConnectAttempt_ProxyAddress(peerConnectState *peer, const uint32_t type, const struct sockaddr_storage &proxy_addr, const std::string &domain_addr, uint16_t domain_port)
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_ProxyAddress() trying address: " << domain_addr << ":" << domain_port << std::endl;
@ -2026,7 +1930,22 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_ProxyAddress(peerConnectState *peer,
peerConnectAddress pca;
pca.addr = proxy_addr;
pca.type = RS_NET_CONN_TCP_HIDDEN;
switch (type) {
case RS_HIDDEN_TYPE_TOR:
pca.type = RS_NET_CONN_TCP_HIDDEN_TOR;
break;
case RS_HIDDEN_TYPE_I2P:
pca.type = RS_NET_CONN_TCP_HIDDEN_I2P;
break;
case RS_HIDDEN_TYPE_UNKNOWN:
default:
/**** THIS CASE SHOULD NOT BE TRIGGERED - since this function is called with a valid hidden type only ****/
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_ProxyAddress() hidden type of addr: " << domain_addr << " is unkown -> THIS SHOULD NEVER HAPPEN!" << std::endl;
std::cerr << " - peer : " << peer->id << "(" << peer->name << ")" << std::endl;
std::cerr << " - proxy: " << sockaddr_storage_tostring(proxy_addr) << std::endl;
std::cerr << " - addr : " << domain_addr << ":" << domain_port << std::endl;
pca.type = RS_NET_CONN_TCP_UNKNOW_TOPOLOGY;
}
//for the delay, we add a random time and some more time when the friend list is big
pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY;

View file

@ -40,16 +40,17 @@ class DNSResolver ;
/* order of attempts ... */
const uint32_t RS_NET_CONN_TCP_ALL = 0x000f;
const uint32_t RS_NET_CONN_UDP_ALL = 0x00f0;
const uint32_t RS_NET_CONN_TCP_ALL = 0x00ff;
const uint32_t RS_NET_CONN_UDP_ALL = 0x0f00;
const uint32_t RS_NET_CONN_TCP_LOCAL = 0x0001;
const uint32_t RS_NET_CONN_TCP_EXTERNAL = 0x0002;
const uint32_t RS_NET_CONN_TCP_UNKNOW_TOPOLOGY = 0x0004;
const uint32_t RS_NET_CONN_TCP_HIDDEN = 0x0008;
const uint32_t RS_NET_CONN_TCP_HIDDEN_TOR = 0x0008;
const uint32_t RS_NET_CONN_TCP_HIDDEN_I2P = 0x0010;
const uint32_t RS_NET_CONN_UDP_DHT_SYNC = 0x0010;
const uint32_t RS_NET_CONN_UDP_PEER_SYNC = 0x0020; /* coming soon */
const uint32_t RS_NET_CONN_UDP_DHT_SYNC = 0x0100;
const uint32_t RS_NET_CONN_UDP_PEER_SYNC = 0x0200; /* coming soon */
// These are set in pqipersongroup.
const uint32_t RS_TCP_STD_TIMEOUT_PERIOD = 5; /* 5 seconds! */
@ -302,7 +303,7 @@ void locked_ConnectAttempt_CurrentAddresses(peerConnectState *peer, const struc
void locked_ConnectAttempt_HistoricalAddresses(peerConnectState *peer, const pqiIpAddrSet &ipAddrs);
void locked_ConnectAttempt_AddDynDNS(peerConnectState *peer, std::string dyndns, uint16_t dynPort);
void locked_ConnectAttempt_AddTunnel(peerConnectState *peer);
void locked_ConnectAttempt_ProxyAddress(peerConnectState *peer, const struct sockaddr_storage &proxy_addr, const std::string &domain_addr, uint16_t domain_port);
void locked_ConnectAttempt_ProxyAddress(peerConnectState *peer, const uint32_t type, const struct sockaddr_storage &proxy_addr, const std::string &domain_addr, uint16_t domain_port);
bool locked_ConnectAttempt_Complete(peerConnectState *peer);

View file

@ -718,14 +718,16 @@ void p3NetMgrIMPL::netExtCheck()
{
// must be stable???
isStable = true;
mNetFlags.mExtAddr = tmpip;
//mNetFlags.mExtAddr = tmpip;
mNetFlags.mExtAddrOk = true;
mNetFlags.mExtAddrStableOk = isStable;
address_votes[tmpip].n++ ;
std::cerr << "NetAssistAddress reported external address " << sockaddr_storage_iptostring(tmpip) << std::endl;
}
else
std::cerr << "(SS) netAssisExternalAddress returned wrong own IP " << sockaddr_storage_iptostring(tmpip) << " (banned). Rejecting." << std::endl;
std::cerr << "(SS) netAssisExternalAddress returned banned own IP " << sockaddr_storage_iptostring(tmpip) << " (banned). Rejecting." << std::endl;
}
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
else
@ -737,6 +739,10 @@ void p3NetMgrIMPL::netExtCheck()
}
#ifdef ALLOW_DHT_STUNNER
// (cyril) I disabled this because it's pretty dangerous. The DHT can report a wrong address quite easily
// if the other DHT peers are not collaborating.
/* Next ask the DhtStunner */
{
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
@ -755,7 +761,7 @@ void p3NetMgrIMPL::netExtCheck()
{
// must be stable???
isStable = (isstable == 1);
mNetFlags.mExtAddr = tmpaddr;
//mNetFlags.mExtAddr = tmpaddr;
mNetFlags.mExtAddrOk = true;
mNetFlags.mExtAddrStableOk = isStable;
@ -772,6 +778,7 @@ void p3NetMgrIMPL::netExtCheck()
}
}
}
#endif
/* otherwise ask ExtAddrFinder */
{
@ -796,7 +803,7 @@ void p3NetMgrIMPL::netExtCheck()
std::cerr << std::endl;
#endif
mNetFlags.mExtAddr = tmpip;
//mNetFlags.mExtAddr = tmpip;
mNetFlags.mExtAddrOk = true;
address_votes[tmpip].n++ ;
@ -805,10 +812,50 @@ void p3NetMgrIMPL::netExtCheck()
#warning "ALLOWING ExtAddrFinder -> ExtAddrStableOk = true (which it is not normally)"
mNetFlags.mExtAddrStableOk = true;
std::cerr << "ExtAddrFinder reported external address " << sockaddr_storage_iptostring(tmpip) << std::endl;
}
}
}
/* also ask peer mgr. */
if (mPeerMgr)
{
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() checking mPeerMgr" << std::endl;
#endif
uint8_t isstable ; // unused
sockaddr_storage tmpaddr ;
if (mPeerMgr->getExtAddressReportedByFriends(tmpaddr, isstable))
{
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() Ext supplied by ExtAddrFinder" << std::endl;
#endif
/* best guess at port */
sockaddr_storage_setport(tmpaddr, sockaddr_storage_port(mLocalAddr));
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() ";
std::cerr << "ExtAddr: " << sockaddr_storage_tostring(tmpip);
std::cerr << std::endl;
#endif
//mNetFlags.mExtAddr = tmpaddr;
mNetFlags.mExtAddrOk = true;
mNetFlags.mExtAddrStableOk = isstable;
address_votes[tmpaddr].n++ ;
std::cerr << "PeerMgr reported external address " << sockaddr_storage_iptostring(tmpaddr) << std::endl;
}
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
else
std::cerr << " No reliable address returned." << std::endl;
#endif
}
/* any other sources ??? */
/* finalise address */
@ -969,7 +1016,19 @@ bool p3NetMgrIMPL::checkNetAddress()
}
else
{
validAddr = getPreferredInterface(mLocalAddr, prefAddr);
// TODO: Sat Oct 24 15:51:24 CEST 2015 The fact of having just one local address is a flawed assumption, this should be redesigned soon.
std::list<sockaddr_storage> addrs;
std::list<sockaddr_storage>::iterator it;
if (getLocalAddresses(addrs))
for(it = addrs.begin(); (it != addrs.end() && !validAddr); ++it)
if(sockaddr_storage_isValidNet(*it) && !sockaddr_storage_isLoopbackNet(*it))
{
prefAddr = *it;
validAddr = true;
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cout << "p3NetMgrIMPL::checkNetAddress() prefAddr: " << sockaddr_storage_iptostring(prefAddr) << std::endl;
#endif
}
}
@ -978,7 +1037,6 @@ bool p3NetMgrIMPL::checkNetAddress()
{
#ifdef NETMGR_DEBUG_RESET
std::cerr << "p3NetMgrIMPL::checkNetAddress() no Valid Network Address, resetting network." << std::endl;
std::cerr << std::endl;
#endif
rslog(RSL_WARNING, p3netmgrzone, "p3NetMgr::checkNetAddress() No Valid Network Address, resetting network");
netReset();

View file

@ -326,6 +326,7 @@ private:
void netStatusReset_locked();
// TODO: Sat Oct 24 15:51:24 CEST 2015 The fact of having just two possible address is a flawed assumption, this should be redesigned soon.
struct sockaddr_storage mLocalAddr;
struct sockaddr_storage mExtAddr;

View file

@ -74,17 +74,20 @@ const uint32_t PEER_IP_CONNECT_STATE_MAX_LIST_SIZE = 4;
#define MIN_RETRY_PERIOD 140
static const std::string kConfigDefaultProxyServerIpAddr = "127.0.0.1";
static const uint16_t kConfigDefaultProxyServerPort = 9050; // standard port.
static const uint16_t kConfigDefaultProxyServerPortTor = 9050; // standard port.
static const uint16_t kConfigDefaultProxyServerPortI2P = 10; // there is no standard port though
static const std::string kConfigKeyExtIpFinder = "USE_EXTR_IP_FINDER";
static const std::string kConfigKeyProxyServerIpAddr = "PROXY_SERVER_IPADDR";
static const std::string kConfigKeyProxyServerPort = "PROXY_SERVER_PORT";
static const std::string kConfigKeyProxyServerIpAddrTor = "PROXY_SERVER_IPADDR";
static const std::string kConfigKeyProxyServerPortTor = "PROXY_SERVER_PORT";
static const std::string kConfigKeyProxyServerIpAddrI2P = "PROXY_SERVER_IPADDR_I2P";
static const std::string kConfigKeyProxyServerPortI2P = "PROXY_SERVER_PORT_I2P";
void printConnectState(std::ostream &out, peerState &peer);
peerState::peerState()
:netMode(RS_NET_MODE_UNKNOWN), vs_disc(RS_VS_DISC_FULL), vs_dht(RS_VS_DHT_FULL), lastcontact(0),
hiddenNode(false), hiddenPort(0)
hiddenNode(false), hiddenPort(0), hiddenType(RS_HIDDEN_TYPE_NONE)
{
sockaddr_storage_clear(localaddr);
sockaddr_storage_clear(serveraddr);
@ -130,13 +133,21 @@ p3PeerMgrIMPL::p3PeerMgrIMPL(const RsPeerId& ssl_own_id, const RsPgpId& gpg_own_
lastGroupId = 1;
// setup default ProxyServerAddress.
sockaddr_storage_clear(mProxyServerAddress);
sockaddr_storage_ipv4_aton(mProxyServerAddress,
// Tor
sockaddr_storage_clear(mProxyServerAddressTor);
sockaddr_storage_ipv4_aton(mProxyServerAddressTor,
kConfigDefaultProxyServerIpAddr.c_str());
sockaddr_storage_ipv4_setport(mProxyServerAddress,
kConfigDefaultProxyServerPort);
sockaddr_storage_ipv4_setport(mProxyServerAddressTor,
kConfigDefaultProxyServerPortTor);
// I2P
sockaddr_storage_clear(mProxyServerAddressI2P);
sockaddr_storage_ipv4_aton(mProxyServerAddressI2P,
kConfigDefaultProxyServerIpAddr.c_str());
sockaddr_storage_ipv4_setport(mProxyServerAddressI2P,
kConfigDefaultProxyServerPortI2P);
mProxyServerStatus = RS_NET_PROXY_STATUS_UNKNOWN ;
mProxyServerStatusTor = RS_NET_PROXY_STATUS_UNKNOWN ;
mProxyServerStatusI2P = RS_NET_PROXY_STATUS_UNKNOWN;
}
#ifdef PEER_DEBUG
@ -169,6 +180,7 @@ bool p3PeerMgrIMPL::setupHiddenNode(const std::string &hiddenAddress, const uint
mOwnState.hiddenNode = true;
mOwnState.hiddenPort = hiddenPort;
mOwnState.hiddenDomain = hiddenAddress;
mOwnState.hiddenType = hiddenDomainToHiddenType(hiddenAddress);
}
forceHiddenNode();
@ -188,6 +200,7 @@ bool p3PeerMgrIMPL::forceHiddenNode()
#endif
}
mOwnState.hiddenNode = true;
mOwnState.hiddenType = hiddenDomainToHiddenType(mOwnState.hiddenDomain);
// force external address - otherwise its invalid.
sockaddr_storage_clear(mOwnState.serveraddr);
@ -368,12 +381,47 @@ bool p3PeerMgrIMPL::getGpgId(const RsPeerId &ssl_id, RsPgpId &gpgId)
bool p3PeerMgrIMPL::isHidden()
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
RS_STACK_MUTEX(mPeerMtx);
return mOwnState.hiddenNode;
}
/**
* @brief checks the hidden type of the own peer.
* @param type type to check
* @return true when the peer has the same hidden type than type
*/
bool p3PeerMgrIMPL::isHidden(const uint32_t type)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
switch (type) {
case RS_HIDDEN_TYPE_TOR:
return mOwnState.hiddenType == RS_HIDDEN_TYPE_TOR;
break;
case RS_HIDDEN_TYPE_I2P:
return mOwnState.hiddenType == RS_HIDDEN_TYPE_I2P;
break;
default:
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::isHidden(" << type << ") unkown type -> false";
std::cerr << std::endl;
#endif
return false;
break;
}
}
bool p3PeerMgrIMPL::isHiddenPeer(const RsPeerId &ssl_id)
{
return isHiddenPeer(ssl_id, RS_HIDDEN_TYPE_NONE);
}
/**
* @brief checks the hidden type of a given ssl id. When type RS_HIDDEN_TYPE_NONE is choosen it returns the 'hiddenNode' value instead
* @param ssl_id to check
* @param type type to check. Use RS_HIDDEN_TYPE_NONE to check 'hiddenNode' value
* @return true when the peer has the same hidden type than type
*/
bool p3PeerMgrIMPL::isHiddenPeer(const RsPeerId &ssl_id, const uint32_t type)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
@ -394,9 +442,91 @@ bool p3PeerMgrIMPL::isHiddenPeer(const RsPeerId &ssl_id)
std::cerr << "p3PeerMgrIMPL::isHiddenPeer(" << ssl_id << ") = " << (it->second).hiddenNode;
std::cerr << std::endl;
#endif
switch (type) {
case RS_HIDDEN_TYPE_TOR:
return (it->second).hiddenType == RS_HIDDEN_TYPE_TOR;
break;
case RS_HIDDEN_TYPE_I2P:
return (it->second).hiddenType == RS_HIDDEN_TYPE_I2P;
break;
default:
return (it->second).hiddenNode;
break;
}
}
bool hasEnding (std::string const &fullString, std::string const &ending) {
if (fullString.length() < ending.length())
return false;
return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
}
/**
* @brief resolves the hidden type (tor or i2p) from a domain
* @param domain to check
* @return RS_HIDDEN_TYPE_TOR, RS_HIDDEN_TYPE_I2P or RS_HIDDEN_TYPE_NONE
*
* Tor: ^[a-z2-7]{16}\.onion$
*
* I2P: There is more than one address:
* - pub. key in base64
* - hash in base32 ( ^[a-z2-7]{52}\.b32\.i2p$ )
* - "normal" .i2p domains
*/
uint32_t p3PeerMgrIMPL::hiddenDomainToHiddenType(const std::string &domain)
{
if(hasEnding(domain, ".onion"))
return RS_HIDDEN_TYPE_TOR;
if(hasEnding(domain, ".i2p"))
return RS_HIDDEN_TYPE_I2P;
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::hiddenDomainToHiddenType() unknown hidden type: " << domain;
std::cerr << std::endl;
#endif
return RS_HIDDEN_TYPE_UNKNOWN;
}
/**
* @brief returns the hidden type of a peer
* @param ssl_id peer id
* @return hidden type
*/
uint32_t p3PeerMgrIMPL::getHiddenType(const RsPeerId &ssl_id)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
if (ssl_id == AuthSSL::getAuthSSL()->OwnId())
return mOwnState.hiddenType;
/* check for existing */
std::map<RsPeerId, peerState>::iterator it;
it = mFriendList.find(ssl_id);
if (it == mFriendList.end())
{
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::getHiddenType(" << ssl_id << ") Missing Peer => false";
std::cerr << std::endl;
#endif
return false;
}
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::getHiddenType(" << ssl_id << ") = " << (it->second).hiddenType;
std::cerr << std::endl;
#endif
return (it->second).hiddenType;
}
/**
* @brief sets hidden domain and port for a given ssl ID
* @param ssl_id peer to set domain and port for
* @param domain_addr
* @param domain_port
* @return true on success
*/
bool p3PeerMgrIMPL::setHiddenDomainPort(const RsPeerId &ssl_id, const std::string &domain_addr, const uint16_t domain_port)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
@ -426,6 +556,7 @@ bool p3PeerMgrIMPL::setHiddenDomainPort(const RsPeerId &ssl_id, const std::strin
mOwnState.hiddenNode = true;
mOwnState.hiddenDomain = domain;
mOwnState.hiddenPort = domain_port;
mOwnState.hiddenType = hiddenDomainToHiddenType(domain);
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::setHiddenDomainPort() Set own State";
std::cerr << std::endl;
@ -448,6 +579,7 @@ bool p3PeerMgrIMPL::setHiddenDomainPort(const RsPeerId &ssl_id, const std::strin
it->second.hiddenDomain = domain;
it->second.hiddenPort = domain_port;
it->second.hiddenNode = true;
it->second.hiddenType = hiddenDomainToHiddenType(domain);
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::setHiddenDomainPort() Set Peers State";
std::cerr << std::endl;
@ -456,15 +588,40 @@ bool p3PeerMgrIMPL::setHiddenDomainPort(const RsPeerId &ssl_id, const std::strin
return true;
}
bool p3PeerMgrIMPL::setProxyServerAddress(const struct sockaddr_storage &proxy_addr)
/**
* @brief sets the proxy server address for a hidden service
* @param type hidden service type
* @param proxy_addr proxy address
* @return true on success
*/
bool p3PeerMgrIMPL::setProxyServerAddress(const uint32_t type, const struct sockaddr_storage &proxy_addr)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
if (!sockaddr_storage_same(mProxyServerAddress,proxy_addr))
switch (type) {
case RS_HIDDEN_TYPE_I2P:
if (!sockaddr_storage_same(mProxyServerAddressI2P, proxy_addr))
{
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
mProxyServerAddress = proxy_addr;
mProxyServerAddressI2P = proxy_addr;
}
break;
case RS_HIDDEN_TYPE_TOR:
if (!sockaddr_storage_same(mProxyServerAddressTor, proxy_addr))
{
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
mProxyServerAddressTor = proxy_addr;
}
break;
case RS_HIDDEN_TYPE_UNKNOWN:
default:
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::setProxyServerAddress() unknown hidden type " << type << " -> false";
std::cerr << std::endl;
#endif
return false;
}
return true;
}
@ -480,21 +637,71 @@ bool p3PeerMgrIMPL::resetOwnExternalAddressList()
return true ;
}
bool p3PeerMgrIMPL::getProxyServerStatus(uint32_t& proxy_status)
/**
* @brief returs proxy server status for a hidden service proxy
* @param type hidden service type
* @param proxy_status
* @return true on success
*/
bool p3PeerMgrIMPL::getProxyServerStatus(const uint32_t type, uint32_t& proxy_status)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
proxy_status = mProxyServerStatus;
switch (type) {
case RS_HIDDEN_TYPE_I2P:
proxy_status = mProxyServerStatusI2P;
break;
case RS_HIDDEN_TYPE_TOR:
proxy_status = mProxyServerStatusTor;
break;
case RS_HIDDEN_TYPE_UNKNOWN:
default:
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::getProxyServerStatus() unknown hidden type " << type << " -> false";
std::cerr << std::endl;
#endif
return false;
}
return true;
}
bool p3PeerMgrIMPL::getProxyServerAddress(struct sockaddr_storage &proxy_addr)
/**
* @brief returs proxy server address for a hidden service proxy
* @param type hidden service type
* @param proxy_addr
* @return true on success
*/
bool p3PeerMgrIMPL::getProxyServerAddress(const uint32_t type, struct sockaddr_storage &proxy_addr)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
proxy_addr = mProxyServerAddress;
switch (type) {
case RS_HIDDEN_TYPE_I2P:
proxy_addr = mProxyServerAddressI2P;
break;
case RS_HIDDEN_TYPE_TOR:
proxy_addr = mProxyServerAddressTor;
break;
case RS_HIDDEN_TYPE_UNKNOWN:
default:
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::getProxyServerAddress() unknown hidden type " << type << " -> false";
std::cerr << std::endl;
#endif
return false;
}
return true;
}
/**
* @brief looks up the proxy address and domain/port that have to be used when connecting to a peer
* @param ssl_id peer to connect to
* @param proxy_addr proxy address to be used
* @param domain_addr domain to connect to
* @param domain_port port to connect to
* @return true on success
*/
bool p3PeerMgrIMPL::getProxyAddress(const RsPeerId &ssl_id, struct sockaddr_storage &proxy_addr, std::string &domain_addr, uint16_t &domain_port)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
@ -515,7 +722,21 @@ bool p3PeerMgrIMPL::getProxyAddress(const RsPeerId &ssl_id, struct sockaddr_stor
domain_addr = it->second.hiddenDomain;
domain_port = it->second.hiddenPort;
proxy_addr = mProxyServerAddress;
switch (it->second.hiddenType) {
case RS_HIDDEN_TYPE_I2P:
proxy_addr = mProxyServerAddressI2P;
break;
case RS_HIDDEN_TYPE_TOR:
proxy_addr = mProxyServerAddressTor;
break;
case RS_HIDDEN_TYPE_UNKNOWN:
default:
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::getProxyAddress() no valid hidden type (" << it->second.hiddenType << ") for peer id " << ssl_id << " -> false";
std::cerr << std::endl;
#endif
return false;
}
return true;
}
@ -805,7 +1026,7 @@ bool p3PeerMgrIMPL::removeFriend(const RsPgpId &id)
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
/* move to othersList */
bool success = false;
//bool success = false;
std::map<RsPeerId, peerState>::iterator it;
//remove ssl and gpg_ids
for(it = mFriendList.begin(); it != mFriendList.end(); ++it)
@ -822,7 +1043,7 @@ bool p3PeerMgrIMPL::removeFriend(const RsPgpId &id)
mOthersList[it->second.id] = peer;
mStatusChanged = true;
success = true;
//success = true;
}
}
@ -878,7 +1099,7 @@ bool p3PeerMgrIMPL::removeFriend(const RsPeerId &id, bool removePgpId)
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
/* move to othersList */
bool success = false;
//bool success = false;
std::map<RsPeerId, peerState>::iterator it;
//remove ssl and gpg_ids
for(it = mFriendList.begin(); it != mFriendList.end(); ++it)
@ -897,7 +1118,7 @@ bool p3PeerMgrIMPL::removeFriend(const RsPeerId &id, bool removePgpId)
mOthersList[id] = peer;
mStatusChanged = true;
success = true;
//success = true;
}
}
@ -1247,6 +1468,7 @@ bool p3PeerMgrIMPL::addCandidateForOwnExternalAddress(const RsPeerId &from, cons
// * if multiple peers report the same address => notify the LinkMgr that the external address had changed.
sockaddr_storage addr_filtered ;
sockaddr_storage_clear(addr_filtered) ;
sockaddr_storage_copyip(addr_filtered,addr) ;
#ifdef PEER_DEBUG
@ -1261,6 +1483,36 @@ bool p3PeerMgrIMPL::addCandidateForOwnExternalAddress(const RsPeerId &from, cons
return false ;
}
// Update a list of own IPs:
// - remove old values for that same peer
// - remove values for non connected peers
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
mReportedOwnAddresses[from] = addr_filtered ;
for(std::map<RsPeerId,sockaddr_storage>::iterator it(mReportedOwnAddresses.begin());it!=mReportedOwnAddresses.end();)
if(!mLinkMgr->isOnline(it->first))
{
std::map<RsPeerId,sockaddr_storage>::iterator tmp(it) ;
++tmp ;
mReportedOwnAddresses.erase(it) ;
it=tmp ;
}
else
++it ;
sockaddr_storage current_best_ext_address_guess ;
uint32_t count ;
locked_computeCurrentBestOwnExtAddressCandidate(current_best_ext_address_guess,count) ;
std::cerr << "p3PeerMgr:: Current external address is calculated to be: " << sockaddr_storage_iptostring(current_best_ext_address_guess) << " (simultaneously reported by " << count << " peers)." << std::endl;
}
// now current
sockaddr_storage own_addr ;
if(!mNetMgr->getExtAddress(own_addr))
@ -1283,9 +1535,55 @@ bool p3PeerMgrIMPL::addCandidateForOwnExternalAddress(const RsPeerId &from, cons
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_IP_WRONG_EXTERNAL_IP_REPORTED, from.toStdString(), sockaddr_storage_iptostring(own_addr), sockaddr_storage_iptostring(addr));
}
// we could also sweep over all connected friends and see if some report a different address.
return true ;
}
bool p3PeerMgrIMPL::locked_computeCurrentBestOwnExtAddressCandidate(sockaddr_storage& addr, uint32_t& count)
{
std::map<sockaddr_storage,ZeroedInt> addr_counts ;
for(std::map<RsPeerId,sockaddr_storage>::iterator it(mReportedOwnAddresses.begin());it!=mReportedOwnAddresses.end();++it)
++addr_counts[it->second].n ;
#ifdef PEER_DEBUG
std::cerr << "Current ext addr statistics:" << std::endl;
#endif
count = 0 ;
for(std::map<sockaddr_storage,ZeroedInt>::const_iterator it(addr_counts.begin());it!=addr_counts.end();++it)
{
if(uint32_t(it->second.n) > count)
{
addr = it->first ;
count = it->second.n ;
}
#ifdef PEER_DEBUG
std::cerr << sockaddr_storage_iptostring(it->first) << " : " << it->second.n << std::endl;
#endif
}
return true ;
}
bool p3PeerMgrIMPL::getExtAddressReportedByFriends(sockaddr_storage &addr, uint8_t& isstable)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
uint32_t count ;
locked_computeCurrentBestOwnExtAddressCandidate(addr,count) ;
#ifdef PEER_DEBUG
std::cerr << "Estimation count = " << count << ". Trusted? = " << (count>=2) << std::endl;
#endif
return count >= 2 ;// 2 is not conservative enough. 3 should be probably better.
}
static bool cleanIpList(std::list<pqiIpAddress>& lst,const RsPeerId& pid,p3LinkMgr *link_mgr)
{
bool changed = false ;
@ -1620,9 +1918,10 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
cleanup = false;
bool useExtAddrFinder = mNetMgr->getIPServersEnabled();
// Store Proxy Server.
struct sockaddr_storage proxy_addr;
getProxyServerAddress(proxy_addr);
/* gather these information before mPeerMtx is locked! */
struct sockaddr_storage proxy_addr_tor, proxy_addr_i2p;
getProxyServerAddress(RS_HIDDEN_TYPE_TOR, proxy_addr_tor);
getProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy_addr_i2p);
mPeerMtx.lock(); /****** MUTEX LOCKED *******/
@ -1733,17 +2032,33 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
vitem->tlvkvs.pairs.push_back(kv) ;
// Store Proxy Server.
// Tor
#ifdef PEER_DEBUG
std::cerr << "Saving proxyServerAddress: " << sockaddr_storage_tostring(proxy_addr);
std::cerr << "Saving proxyServerAddress for Tor: " << sockaddr_storage_tostring(proxy_addr_tor);
std::cerr << std::endl;
#endif
kv.key = kConfigKeyProxyServerIpAddr;
kv.value = sockaddr_storage_iptostring(proxy_addr);
kv.key = kConfigKeyProxyServerIpAddrTor;
kv.value = sockaddr_storage_iptostring(proxy_addr_tor);
vitem->tlvkvs.pairs.push_back(kv) ;
kv.key = kConfigKeyProxyServerPort;
kv.value = sockaddr_storage_porttostring(proxy_addr);
kv.key = kConfigKeyProxyServerPortTor;
kv.value = sockaddr_storage_porttostring(proxy_addr_tor);
vitem->tlvkvs.pairs.push_back(kv) ;
// I2P
#ifdef PEER_DEBUG
std::cerr << "Saving proxyServerAddress for I2P: " << sockaddr_storage_tostring(proxy_addr_i2p);
std::cerr << std::endl;
#endif
kv.key = kConfigKeyProxyServerIpAddrI2P;
kv.value = sockaddr_storage_iptostring(proxy_addr_i2p);
vitem->tlvkvs.pairs.push_back(kv) ;
kv.key = kConfigKeyProxyServerPortI2P;
kv.value = sockaddr_storage_porttostring(proxy_addr_i2p);
vitem->tlvkvs.pairs.push_back(kv) ;
saveData.push_back(vitem);
@ -1779,8 +2094,10 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
// DEFAULTS.
bool useExtAddrFinder = true;
std::string proxyIpAddress = kConfigDefaultProxyServerIpAddr;
uint16_t proxyPort = kConfigDefaultProxyServerPort;
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;
@ -1876,20 +2193,38 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
std::cerr << "setting use_extr_addr_finder to " << useExtAddrFinder << std::endl ;
#endif
}
else if (kit->key == kConfigKeyProxyServerIpAddr)
// Tor
else if (kit->key == kConfigKeyProxyServerIpAddrTor)
{
proxyIpAddress = kit->value;
proxyIpAddressTor = kit->value;
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyIpAddress: " << proxyIpAddress;
std::cerr << "Loaded proxyIpAddress for Tor: " << proxyIpAddressTor;
std::cerr << std::endl ;
#endif
}
else if (kit->key == kConfigKeyProxyServerPort)
else if (kit->key == kConfigKeyProxyServerPortTor)
{
proxyPort = atoi(kit->value.c_str());
proxyPortTor = atoi(kit->value.c_str());
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyPort: " << proxyPort;
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
}
@ -2005,15 +2340,27 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
// Configure Proxy Server.
struct sockaddr_storage proxy_addr;
// Tor
sockaddr_storage_clear(proxy_addr);
sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddress.c_str());
sockaddr_storage_ipv4_setport(proxy_addr, proxyPort);
sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressTor.c_str());
sockaddr_storage_ipv4_setport(proxy_addr, proxyPortTor);
if (sockaddr_storage_isValidNet(proxy_addr))
{
setProxyServerAddress(proxy_addr);
setProxyServerAddress(RS_HIDDEN_TYPE_TOR, proxy_addr);
}
// 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

@ -90,6 +90,7 @@ class peerState
bool hiddenNode; /* all IP addresses / dyndns must be blank */
std::string hiddenDomain;
uint16_t hiddenPort;
uint32_t hiddenType;
std::string location;
std::string name;
@ -153,6 +154,7 @@ virtual bool setLocalAddress(const RsPeerId &id, const struct sockaddr_storage
virtual bool setExtAddress(const RsPeerId &id, const struct sockaddr_storage &addr) = 0;
virtual bool setDynDNS(const RsPeerId &id, const std::string &dyndns) = 0;
virtual bool addCandidateForOwnExternalAddress(const RsPeerId& from, const struct sockaddr_storage &addr) = 0;
virtual bool getExtAddressReportedByFriends(struct sockaddr_storage& addr,uint8_t& isstable) = 0;
virtual bool setNetworkMode(const RsPeerId &id, uint32_t netMode) = 0;
virtual bool setVisState(const RsPeerId &id, uint16_t vs_disc, uint16_t vs_dht) = 0;
@ -185,12 +187,16 @@ virtual bool getPeerName(const RsPeerId &ssl_id, std::string &name) = 0;
virtual bool getGpgId(const RsPeerId &sslId, RsPgpId &gpgId) = 0;
virtual uint32_t getConnectionType(const RsPeerId &sslId) = 0;
virtual bool setProxyServerAddress(const struct sockaddr_storage &proxy_addr) = 0;
virtual bool getProxyServerAddress(struct sockaddr_storage &proxy_addr) = 0;
virtual bool getProxyServerStatus(uint32_t& status) = 0;
virtual bool setProxyServerAddress(const uint32_t type, const struct sockaddr_storage &proxy_addr) = 0;
virtual bool getProxyServerAddress(const uint32_t type, struct sockaddr_storage &proxy_addr) = 0;
virtual bool getProxyServerStatus(const uint32_t type, uint32_t& status) = 0;
virtual bool isHidden() = 0;
virtual bool isHidden(const uint32_t type) = 0;
virtual bool isHiddenPeer(const RsPeerId &ssl_id) = 0;
virtual bool isHiddenPeer(const RsPeerId &ssl_id, const uint32_t type) = 0;
virtual bool getProxyAddress(const RsPeerId &ssl_id, struct sockaddr_storage &proxy_addr, std::string &domain_addr, uint16_t &domain_port) = 0;
virtual uint32_t hiddenDomainToHiddenType(const std::string &domain) = 0;
virtual uint32_t getHiddenType(const RsPeerId &ssl_id) = 0;
virtual int getFriendCount(bool ssl, bool online) = 0;
@ -200,6 +206,7 @@ virtual int getFriendCount(bool ssl, bool online) = 0;
// Single Use Function... shouldn't be here. used by p3serverconfig.cc
virtual bool haveOnceConnected() = 0;
virtual bool locked_computeCurrentBestOwnExtAddressCandidate(sockaddr_storage &addr, uint32_t &count)=0;
/*************************************************************************************************/
/*************************************************************************************************/
@ -256,6 +263,7 @@ virtual bool setLocalAddress(const RsPeerId &id, const struct sockaddr_storage
virtual bool setExtAddress(const RsPeerId &id, const struct sockaddr_storage &addr);
virtual bool setDynDNS(const RsPeerId &id, const std::string &dyndns);
virtual bool addCandidateForOwnExternalAddress(const RsPeerId& from, const struct sockaddr_storage &addr) ;
virtual bool getExtAddressReportedByFriends(struct sockaddr_storage& addr, uint8_t &isstable) ;
virtual bool setNetworkMode(const RsPeerId &id, uint32_t netMode);
virtual bool setVisState(const RsPeerId &id, uint16_t vs_disc, uint16_t vs_dht);
@ -288,12 +296,16 @@ virtual bool getPeerName(const RsPeerId& ssl_id, std::string& name);
virtual bool getGpgId(const RsPeerId& sslId, RsPgpId& gpgId);
virtual uint32_t getConnectionType(const RsPeerId& sslId);
virtual bool setProxyServerAddress(const struct sockaddr_storage &proxy_addr);
virtual bool getProxyServerAddress(struct sockaddr_storage &proxy_addr);
virtual bool getProxyServerStatus(uint32_t &proxy_status);
virtual bool setProxyServerAddress(const uint32_t type, const struct sockaddr_storage &proxy_addr);
virtual bool getProxyServerAddress(const uint32_t type, struct sockaddr_storage &proxy_addr);
virtual bool getProxyServerStatus(const uint32_t type, uint32_t &proxy_status);
virtual bool isHidden();
virtual bool isHiddenPeer(const RsPeerId& ssl_id);
virtual bool isHidden(const uint32_t type);
virtual bool isHiddenPeer(const RsPeerId &ssl_id);
virtual bool isHiddenPeer(const RsPeerId &ssl_id, const uint32_t type);
virtual bool getProxyAddress(const RsPeerId& ssl_id, struct sockaddr_storage &proxy_addr, std::string &domain_addr, uint16_t &domain_port);
virtual uint32_t hiddenDomainToHiddenType(const std::string &domain);
virtual uint32_t getHiddenType(const RsPeerId &ssl_id);
virtual int getFriendCount(bool ssl, bool online);
@ -327,6 +339,7 @@ int getConnectAddresses(const RsPeerId &id,
struct sockaddr_storage &lAddr, struct sockaddr_storage &eAddr,
pqiIpAddrSet &histAddrs, std::string &dyndns);
protected:
/* Internal Functions */
@ -335,6 +348,8 @@ bool removeBannedIps();
void printPeerLists(std::ostream &out);
virtual bool locked_computeCurrentBestOwnExtAddressCandidate(sockaddr_storage &addr, uint32_t &count);
protected:
/*****************************************************************/
/*********************** p3config ******************************/
@ -362,6 +377,8 @@ private:
std::map<RsPeerId, peerState> mFriendList; // <SSLid , peerState>
std::map<RsPeerId, peerState> mOthersList;
std::map<RsPeerId,sockaddr_storage> mReportedOwnAddresses ;
std::list<RsPeerGroupItem *> groupList;
uint32_t lastGroupId;
@ -369,8 +386,10 @@ private:
std::map<RsPgpId, ServicePermissionFlags> mFriendsPermissionFlags ; // permission flags for each gpg key
struct sockaddr_storage mProxyServerAddress;
uint32_t mProxyServerStatus ;
struct sockaddr_storage mProxyServerAddressTor;
struct sockaddr_storage mProxyServerAddressI2P;
uint32_t mProxyServerStatusTor ;
uint32_t mProxyServerStatusI2P ;
};

View file

@ -148,7 +148,7 @@ public:
uint32_t tmp ;
ok &= getRawUInt32(data, rssize, &offset, &tmp);
for(int i=0;i<tmp && offset < rssize;++i)
for(uint32_t i=0;i<tmp && offset < rssize;++i)
{
RsPeerId peer_id ;
ok &= peer_id.deserialise(data,rssize,offset) ;
@ -157,7 +157,7 @@ public:
ok &= getRawUInt32(data, rssize, &offset, &tmp);
for(int i=0;i<tmp && offset < rssize;++i)
for(uint32_t i=0;i<tmp && offset < rssize;++i)
{
RsPeerId peer_id ;
ok &= peer_id.deserialise(data,rssize,offset) ;
@ -1180,12 +1180,13 @@ bool p3ServiceControl::loadList(std::list<RsItem *>& loadList)
{
RsServicePermissionItem *item = dynamic_cast<RsServicePermissionItem*>(*it) ;
if(item == NULL)
continue ;
if(item != NULL)
mServicePermissionMap[item->mServiceId] = *item ;
delete *it ;
}
loadList.clear() ;
return true;
}

View file

@ -230,13 +230,9 @@ class PQInterface: public RateInterface
virtual const RsPeerId& PeerId() { return peerId; }
// the callback from NetInterface Connection Events.
virtual int notifyEvent(NetInterface *ni, int event, const struct sockaddr_storage &remote_peer_address)
{
(void) ni; /* remove unused parameter warnings */
(void) event; /* remove unused parameter warnings */
(void) remote_peer_address;
return 0;
}
virtual int notifyEvent(NetInterface * /*ni*/, int /*event*/,
const sockaddr_storage & /*remote_peer_address*/)
{ return 0; }
private:
@ -249,7 +245,8 @@ class PQInterface: public RateInterface
const uint32_t PQI_CONNECT_TCP = 0x0001;
const uint32_t PQI_CONNECT_UDP = 0x0002;
const uint32_t PQI_CONNECT_HIDDEN_TCP = 0x0004;
const uint32_t PQI_CONNECT_HIDDEN_TOR_TCP = 0x0004;
const uint32_t PQI_CONNECT_HIDDEN_I2P_TCP = 0x0008;
#define BIN_FLAGS_NO_CLOSE 0x0001
@ -266,57 +263,57 @@ const uint32_t PQI_CONNECT_HIDDEN_TCP = 0x0004;
class BinInterface
{
public:
BinInterface() { return; }
virtual ~BinInterface() { return; }
BinInterface() {}
virtual ~BinInterface() {}
/**
/**
* To be called loop, for updating state
*/
virtual int tick() = 0;
virtual int tick() = 0;
/**
/**
* Sends data to a prescribed location (implementation dependent)
*@param data what will be sent
*@param len the size of data pointed to in memory
*/
virtual int senddata(void *data, int len) = 0;
virtual int senddata(void *data, int len) = 0;
/**
/**
* reads data from a prescribed location (implementation dependent)
*@param data what will be sent
*@param len the size of data pointed to in memory
*/
virtual int readdata(void *data, int len) = 0;
virtual int readdata(void *data, int len) = 0;
/**
/**
* Is more particular the case of the sending data through a socket (internet)
* moretoread and candsend, take a microsec timeout argument.
*
*/
virtual int netstatus() = 0;
virtual int isactive() = 0;
virtual bool moretoread(uint32_t usec) = 0;
virtual bool cansend(uint32_t usec) = 0;
virtual int netstatus() = 0;
virtual int isactive() = 0;
virtual bool moretoread(uint32_t usec) = 0;
virtual bool cansend(uint32_t usec) = 0;
/**
/**
* method for streamer to shutdown bininterface
**/
virtual int close() = 0;
virtual int close() = 0;
/**
/**
* If hashing data
**/
virtual RsFileHash gethash() = 0;
virtual RsFileHash gethash() = 0;
/**
/**
* Number of bytes read/sent
*/
virtual uint64_t bytecount() { return 0; }
virtual uint64_t bytecount() { return 0; }
/**
/**
* used by pqistreamer to limit transfers
**/
virtual bool bandwidthLimited() { return true; }
virtual bool bandwidthLimited() { return true; }
};
@ -359,26 +356,30 @@ public:
/**
* @param p_in used to notify system of connect/disconnect events
*/
NetInterface(PQInterface *p_in, const RsPeerId& id)
:p(p_in), peerId(id) { return; }
NetInterface(PQInterface *p_in, const RsPeerId& id) : p(p_in), peerId(id) {}
virtual ~NetInterface()
{ return; }
virtual ~NetInterface() {}
virtual int connect(const struct sockaddr_storage &raddr) = 0;
virtual int listen() = 0;
virtual int stoplistening() = 0;
virtual int disconnect() = 0;
virtual int reset() = 0;
virtual const RsPeerId& PeerId() { return peerId; }
virtual int getConnectAddress(struct sockaddr_storage &raddr) = 0;
/* TODO
* The data entrypoint is connect(const struct sockaddr_storage &raddr)
* To generalize NetInterface we should have a more general type for raddr
* As an example a string containing an url or encoded like a domain name
*/
virtual int connect(const struct sockaddr_storage &raddr) = 0;
virtual bool connect_parameter(uint32_t type, uint32_t value) = 0;
virtual bool connect_parameter(uint32_t /* type */ , const std::string & /* value */ ) { return false; } // not generally used.
virtual bool connect_additional_address(uint32_t /*type*/, const struct sockaddr_storage & /*addr*/) { return false; } // only needed by udp.
virtual int listen() = 0;
virtual int stoplistening() = 0;
virtual int disconnect() = 0;
virtual int reset() = 0;
virtual const RsPeerId& PeerId() { return peerId; }
virtual int getConnectAddress(struct sockaddr_storage &raddr) = 0;
virtual bool connect_parameter(uint32_t type, uint32_t value) = 0;
virtual bool connect_parameter(uint32_t /* type */ , const std::string & /* value */ ) { return false; } // not generally used.
virtual bool connect_additional_address(uint32_t /*type*/, const struct sockaddr_storage & /*addr*/) { return false; } // only needed by udp.
protected:
PQInterface *parent() { return p; }
PQInterface *parent() { return p; }
private:
PQInterface *p;
@ -396,10 +397,9 @@ private:
class NetBinInterface: public NetInterface, public BinInterface
{
public:
NetBinInterface(PQInterface *parent, const RsPeerId& id)
:NetInterface(parent, id)
{ return; }
virtual ~NetBinInterface() { return; }
NetBinInterface(PQInterface *parent, const RsPeerId& id) :
NetInterface(parent, id) {}
virtual ~NetBinInterface() {}
};
#define CHAN_SIGN_SIZE 16

View file

@ -500,7 +500,7 @@ void printNetBinID(std::ostream &out, const RsPeerId& id, uint32_t t)
{
out << "TCP)";
}
else if (t == PQI_CONNECT_HIDDEN_TCP)
else if (t & (PQI_CONNECT_HIDDEN_TOR_TCP | PQI_CONNECT_HIDDEN_I2P_TCP))
{
out << "HTCP";
}
@ -544,7 +544,7 @@ int NetBinDummy::connect(const struct sockaddr_storage &raddr)
std::cerr << std::endl;
if (parent())
{
struct sockaddr_storage addr = raddr;
//struct sockaddr_storage addr = raddr;
parent()->notifyEvent(this, CONNECT_FAILED, raddr);
}
}

View file

@ -29,6 +29,34 @@
#include "util/rsstring.h"
#include <stdlib.h>
#include <time.h>
using std::dec;
#include <time.h>
#include <sys/time.h>
#ifdef WINDOWS_SYS
#include <sys/timeb.h>
#endif
//#define PQI_HDL_DEBUG_UR 1
#ifdef PQI_HDL_DEBUG_UR
static double getCurrentTS()
{
#ifndef WINDOWS_SYS
struct timeval cts_tmp;
gettimeofday(&cts_tmp, NULL);
double cts = (cts_tmp.tv_sec) + ((double) cts_tmp.tv_usec) / 1000000.0;
#else
struct _timeb timebuf;
_ftime( &timebuf);
double cts = (timebuf.time) + ((double) timebuf.millitm) / 1000.0;
#endif
return cts;
}
#endif
const int pqihandlerzone = 34283;
static const int PQI_HANDLER_NB_PRIORITY_LEVELS = 10 ;
@ -443,8 +471,11 @@ int pqihandler::ExtractRates(std::map<RsPeerId, RsBwRates> &ratemap, RsBwRat
// internal fn to send updates
int pqihandler::UpdateRates()
{
#ifdef PQI_HDL_DEBUG_UR
uint64_t t_now;
#endif
std::map<RsPeerId, SearchModule *>::iterator it;
int num_sm = mods.size();
float avail_in = getMaxRate(true);
float avail_out = getMaxRate(false);
@ -455,28 +486,124 @@ int pqihandler::UpdateRates()
/* Lock once rates have been retrieved */
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
int num_sm = mods.size();
float used_bw_in_table[num_sm]; /* table of in bandwidth currently used by each module */
float used_bw_out_table[num_sm]; /* table of out bandwidth currently used by each module */
int effectiveUploadsSm = 0;
int effectiveDownloadsSm = 0;
// loop through modules to get the used bandwith and the number of modules that are affectively transfering
//std::cerr << " Looping through modules" << std::endl;
#ifdef PQI_HDL_DEBUG_UR
std::cerr << " Looping through modules" << std::endl;
#endif
int index = 0;
for(it = mods.begin(); it != mods.end(); ++it)
{
SearchModule *mod = (it -> second);
float crate_in = mod -> pqi -> getRate(true);
if (crate_in > 0.01 * avail_in || crate_in > 0.1)
if ((crate_in > 0.01 * avail_in) || (crate_in > 0.1))
{
++effectiveDownloadsSm;
}
float crate_out = mod -> pqi -> getRate(false);
if (crate_out > 0.01 * avail_out || crate_out > 0.1)
if ((crate_out > 0.01 * avail_out) || (crate_out > 0.1))
{
++effectiveUploadsSm;
}
used_bw_in += crate_in;
used_bw_out += crate_out;
/* fill the table of bandwidth */
used_bw_in_table[index] = crate_in;
used_bw_out_table[index] = crate_out;
++index;
}
#ifdef PQI_HDL_DEBUG_UR
t_now = 1000 * getCurrentTS();
std::cerr << dec << t_now << " pqihandler::UpdateRates(): Sorting used_bw_out_table: " << num_sm << " entries" << std::endl;
#endif
/* Sort the used bw in/out table in ascending order */
std::sort(used_bw_in_table, used_bw_in_table + num_sm);
std::sort(used_bw_out_table, used_bw_out_table + num_sm);
#ifdef PQI_HDL_DEBUG_UR
t_now = 1000 * getCurrentTS();
std::cerr << dec << t_now << " pqihandler::UpdateRates(): Done." << std::endl;
std::cerr << dec << t_now << " pqihandler::UpdateRates(): used_bw_out " << used_bw_out << std::endl;
#endif
/* Calculate the optimal out_max value, taking into account avail_out and the out bw requested by modules */
float out_remaining_bw = avail_out;
float out_max_bw = 0;
bool keep_going = true;
int mod_index = 0;
while (keep_going && (mod_index < num_sm)) {
float result = (num_sm - mod_index) * (used_bw_out_table[mod_index] - out_max_bw);
if (result > out_remaining_bw) {
/* There is not enough remaining out bw to satisfy all modules,
distribute the remaining out bw among modules, then exit */
out_max_bw += out_remaining_bw / (num_sm - mod_index);
out_remaining_bw = 0;
keep_going = false;
} else {
/* Grant the requested out bandwidth to all modules,
then recalculate the remaining out bandwidth */
out_remaining_bw -= result;
out_max_bw = used_bw_out_table[mod_index];
++mod_index;
}
}
#ifdef PQI_HDL_DEBUG_UR
t_now = 1000 * getCurrentTS();
std::cerr << dec << t_now << " pqihandler::UpdateRates(): mod_index " << mod_index << " out_max_bw " << out_max_bw << " remaining out bw " << out_remaining_bw << std::endl;
#endif
/* Allocate only half the remaining out bw, if any, to make it smoother */
out_max_bw = out_max_bw + out_remaining_bw / 2;
/* Calculate the optimal in_max value, taking into account avail_in and the in bw requested by modules */
float in_remaining_bw = avail_in;
float in_max_bw = 0;
keep_going = true;
mod_index = 0;
while (keep_going && mod_index < num_sm) {
float result = (num_sm - mod_index) * (used_bw_in_table[mod_index] - in_max_bw);
if (result > in_remaining_bw) {
/* There is not enough remaining in bw to satisfy all modules,
distribute the remaining in bw among modules, then exit */
in_max_bw += in_remaining_bw / (num_sm - mod_index);
in_remaining_bw = 0;
keep_going = false;
} else {
/* Grant the requested in bandwidth to all modules,
then recalculate the remaining in bandwidth */
in_remaining_bw -= result;
in_max_bw = used_bw_in_table[mod_index];
++mod_index;
}
}
#ifdef PQI_HDL_DEBUG_UR
t_now = 1000 * getCurrentTS();
std::cerr << dec << t_now << " pqihandler::UpdateRates(): mod_index " << mod_index << " in_max_bw " << in_max_bw << " remaining in bw " << in_remaining_bw << std::endl;
#endif
/* Allocate only half the remaining in bw, if any, to make it smoother */
in_max_bw = in_max_bw + in_remaining_bw / 2;
#ifdef DEBUG_QOS
// std::cerr << "Totals (In) Used B/W " << used_bw_in;
// std::cerr << " Available B/W " << avail_in;
@ -498,35 +625,19 @@ int pqihandler::UpdateRates()
max_out_effective = avail_out / effectiveUploadsSm;
}
//modify the outgoing rates if bandwith is not used well
float rate_out_modifier = 0;
if (used_bw_out / avail_out < 0.95) {
rate_out_modifier = 0.001 * avail_out;
} else if (used_bw_out / avail_out > 1.05) {
rate_out_modifier = - 0.001 * avail_out;
}
if (rate_out_modifier != 0) {
//modify the in and out limit
#ifdef PQI_HDL_DEBUG_UR
t_now = 1000 * getCurrentTS();
std::cerr << dec << t_now << " pqihandler::UpdateRates(): setting new out_max " << out_max_bw << " in_max " << in_max_bw << std::endl;
#endif
for(it = mods.begin(); it != mods.end(); ++it)
{
SearchModule *mod = (it -> second);
mod -> pqi -> setMaxRate(false, mod -> pqi -> getMaxRate(false) + rate_out_modifier);
}
mod -> pqi -> setMaxRate(true, in_max_bw);
mod -> pqi -> setMaxRate(false, out_max_bw);
}
//modify the incoming rates if bandwith is not used well
float rate_in_modifier = 0;
if (used_bw_in / avail_in < 0.95) {
rate_in_modifier = 0.001 * avail_in;
} else if (used_bw_in / avail_in > 1.05) {
rate_in_modifier = - 0.001 * avail_in;
}
if (rate_in_modifier != 0) {
for(it = mods.begin(); it != mods.end(); ++it)
{
SearchModule *mod = (it -> second);
mod -> pqi -> setMaxRate(true, mod -> pqi -> getMaxRate(true) + rate_in_modifier);
}
}
//cap the rates
for(it = mods.begin(); it != mods.end(); ++it)

View file

@ -31,21 +31,14 @@
class pqilistener
{
public:
pqilistener() { return; }
virtual ~pqilistener() { return; }
virtual int tick() { return 1; }
virtual int status() { return 1; }
virtual int setListenAddr(const struct sockaddr_storage &addr)
{
(void) addr; /* suppress unused parameter warning */
return 1;
}
virtual int setuplisten() { return 1; }
virtual int resetlisten() { return 1; }
public:
pqilistener() {}
virtual ~pqilistener() {}
virtual int tick() { return 1; }
virtual int status() { return 1; }
virtual int setListenAddr(const sockaddr_storage & /*addr*/) { return 1; }
virtual int setuplisten() { return 1; }
virtual int resetlisten() { return 1; }
};

View file

@ -38,7 +38,8 @@
#include "util/rsdebug.h"
#include "util/rsstring.h"
#include <iomanip>
#include "util/rsnet.h"
static const int pqinetzone = 96184;
/*****
@ -55,6 +56,11 @@ int errno;
#endif
#ifdef __HAIKU__
#include <sys/sockio.h>
#define IFF_RUNNING 0x0001
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
@ -144,78 +150,6 @@ std::string socket_errorType(int err)
return std::string("UNKNOWN ERROR CODE - ASK RS-DEVS TO ADD IT!");
}
#include <net/if.h>
#include <sys/ioctl.h>
bool getLocalInterfaces_ipv4(struct in_addr &/*routeAddr*/, std::list<struct in_addr> &addrs)
{
int sock = 0;
struct ifreq ifreq;
struct if_nameindex *iflist = if_nameindex();
struct if_nameindex *ifptr = iflist;
//need a socket for ioctl()
if( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
pqioutput(PQL_ALERT, pqinetzone,
"Cannot Determine Local Addresses!");
return false;
}
if (!ifptr)
{
pqioutput(PQL_ALERT, pqinetzone,
"getLocalInterfaces(): ERROR if_nameindex == NULL");
return false;
}
// loop through the interfaces.
for(; ifptr->if_index != 0; ++ifptr)
{
//copy in the interface name to look up address of
strncpy(ifreq.ifr_name, ifptr->if_name, IF_NAMESIZE-1);// the -1 is here to ensure that there's enough room left to place a \0 termination byte
if(ioctl(sock, SIOCGIFADDR, &ifreq) != 0)
{
std::string out;
rs_sprintf(out, "Cannot Determine Address for Iface: %s", ifptr -> if_name);
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out);
}
else
{
struct sockaddr_in *aptr =
(struct sockaddr_in *) &ifreq.ifr_addr;
std::string astr =rs_inet_ntoa(aptr -> sin_addr);
std::string out;
rs_sprintf(out, "Iface: %s\n Address: %s", ifptr -> if_name, astr.c_str());
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out);
// Now check wether the interface is up and running. If not, we don't use it!!
//
if(ioctl(sock,SIOCGIFFLAGS,&ifreq) != 0)
{
std::cerr << "Could not get flags from interface " << ifptr -> if_name << std::endl ;
continue ;
}
#ifdef NET_DEBUG
std::cout << out.str() ;
std::cout << "flags = " << ifreq.ifr_flags << std::endl ;
#endif
if((ifreq.ifr_flags & IFF_UP) == 0) continue ;
if((ifreq.ifr_flags & IFF_RUNNING) == 0) continue ;
addrs.push_back(aptr->sin_addr);
}
}
// free socket -> or else run out of fds.
close(sock);
if_freenameindex(iflist);
return (addrs.size() > 0);
}
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#else
@ -322,80 +256,6 @@ std::string socket_errorType(int err)
return std::string("----WINDOWS OPERATING SYSTEM FAILURE----");
}
#include <iphlpapi.h>
//#include <iprtrmib.h>
// A function to determine the interfaces on your computer....
// No idea of how to do this in windows....
// see if it compiles.
bool getLocalInterfaces_ipv4(struct in_addr &routeAddr, std::list<struct in_addr> &addrs)
{
// Get the best interface for transport to routeAddr
// This interface should be first in list!
DWORD bestInterface;
if (GetBestInterface((IPAddr) routeAddr.s_addr, &bestInterface) != NO_ERROR)
{
bestInterface = 0;
}
/* USE MIB IPADDR Interface */
PMIB_IPADDRTABLE iptable = NULL;
DWORD dwSize = 0;
if (GetIpAddrTable(iptable, &dwSize, 0) != ERROR_INSUFFICIENT_BUFFER)
{
pqioutput(PQL_ALERT, pqinetzone, "Cannot Find Windoze Interfaces!");
exit(0);
}
iptable = (MIB_IPADDRTABLE *) malloc(dwSize);
GetIpAddrTable(iptable, &dwSize, 0);
struct in_addr addr;
for (unsigned int i = 0; i < iptable -> dwNumEntries; i++)
{
MIB_IPADDRROW &ipaddr = iptable->table[i];
std::string out;
addr.s_addr = ipaddr.dwAddr;
rs_sprintf(out, "Iface(%ld) => %s\n", ipaddr.dwIndex, rs_inet_ntoa(addr).c_str());
#if __MINGW_MAJOR_VERSION <= 3 && !defined(__MINGW64_VERSION_MAJOR)
unsigned short wType = ipaddr.unused2; // should be wType
#else
unsigned short wType = ipaddr.wType;
#endif
if (wType & MIB_IPADDR_DISCONNECTED)
{
pqioutput(PQL_DEBUG_BASIC, pqinetzone, "Interface disconnected, " + out);
continue;
}
if (wType & MIB_IPADDR_DELETED)
{
pqioutput(PQL_DEBUG_BASIC, pqinetzone, "Interface deleted, " + out);
continue;
}
if (ipaddr.dwIndex == bestInterface)
{
pqioutput(PQL_DEBUG_BASIC, pqinetzone, "Best address, " + out);
addrs.push_front(addr);
}
else
{
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out);
addrs.push_back(addr);
}
}
free (iptable);
return (addrs.size() > 0);
}
// implement the improved unix inet address fn.
// using old one.
int inet_aton(const char *name, struct in_addr *addr)
@ -403,478 +263,82 @@ int inet_aton(const char *name, struct in_addr *addr)
return (((*addr).s_addr = inet_addr(name)) != INADDR_NONE);
}
// This returns in Net Byte Order.
// NB: Linux man page claims it is in Host Byte order, but
// this is blatantly wrong!..... (for Debian anyway)
// Making this consistent with the Actual behavior (rather than documented).
in_addr_t inet_netof(struct in_addr addr)
{
return pqi_inet_netof(addr);
}
// This returns in Host Byte Order. (as the man page says)
// Again, to be consistent with Linux.
in_addr_t inet_network(const char *inet_name)
{
struct in_addr addr;
if (inet_aton(inet_name, &addr))
{
#ifdef NET_DEBUG
// std::cerr << "inet_network(" << inet_name << ") : ";
// std::cerr << rs_inet_ntoa(addr) << std::endl;
#endif
return ntohl(inet_netof(addr));
}
return 0xffffffff;
//return -1;
}
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#include <iostream>
#include <sys/types.h>
#ifdef WINDOWS_SYS
#include <winsock2.h>
#include <iphlpapi.h>
#pragma comment(lib, "IPHLPAPI.lib")
#else // WINDOWS_SYS
#include <ifaddrs.h>
#include <net/if.h>
#endif // WINDOWS_SYS
// This returns in Net Byte Order.
// NB: Linux man page claims it is in Host Byte order, but
// this is blatantly wrong!..... (for Debian anyway)
// Making this consistent with the Actual behavior (rather than documented).
in_addr_t pqi_inet_netof(struct in_addr addr)
void getLocalAddressesFailed()
{
// decide if A class address.
unsigned long haddr = ntohl(addr.s_addr);
unsigned long abit = haddr & 0xff000000UL;
unsigned long bbit = haddr & 0xffff0000UL;
unsigned long cbit = haddr & 0xffffff00UL;
#ifdef NET_DEBUG
std::cerr << "inet_netof(" << rs_inet_ntoa(addr) << ") ";
#endif
if (!((haddr >> 31) | 0x0UL)) // MSB = 0
{
#ifdef NET_DEBUG
std::cerr << " Type A " << std::endl;
std::cerr << "\tShifted(31): " << (haddr >> 31);
std::cerr << " Xord(0x0UL): " <<
!((haddr >> 31) | 0x0UL) << std::endl;
#endif
return htonl(abit);
}
else if (!((haddr >> 30) ^ 0x2UL)) // 2MSBs = 10
{
#ifdef NET_DEBUG
std::cerr << " Type B " << std::endl;
std::cerr << "\tShifted(30): " << (haddr >> 30);
std::cerr << " Xord(0x2UL): " <<
!((haddr >> 30) | 0x2UL) << std::endl;
#endif
return htonl(bbit);
}
else if (!((haddr >> 29) ^ 0x6UL)) // 3MSBs = 110
{
#ifdef NET_DEBUG
std::cerr << " Type C " << std::endl;
std::cerr << "\tShifted(29): " << (haddr >> 29);
std::cerr << " Xord(0x6UL): " <<
!((haddr >> 29) | 0x6UL) << std::endl;
#endif
return htonl(cbit);
}
else if (!((haddr >> 28) ^ 0xeUL)) // 4MSBs = 1110
{
#ifdef NET_DEBUG
std::cerr << " Type Multicast " << std::endl;
std::cerr << "\tShifted(28): " << (haddr >> 28);
std::cerr << " Xord(0xeUL): " <<
!((haddr >> 29) | 0xeUL) << std::endl;
#endif
return addr.s_addr; // return full address.
}
else if (!((haddr >> 27) ^ 0x1eUL)) // 5MSBs = 11110
{
#ifdef NET_DEBUG
std::cerr << " Type Reserved " << std::endl;
std::cerr << "\tShifted(27): " << (haddr >> 27);
std::cerr << " Xord(0x1eUL): " <<
!((haddr >> 27) | 0x1eUL) << std::endl;
#endif
return addr.s_addr; // return full address.
}
return htonl(abit);
std::cerr << "FATAL ERROR: getLocalAddresses failed!" << std::endl;
exit(1);
}
int sockaddr_cmp(struct sockaddr_in &addr1, struct sockaddr_in &addr2 )
bool getLocalAddresses(std::list<sockaddr_storage> & addrs)
{
if (addr1.sin_family != addr2.sin_family)
return addr1.sin_family - addr2.sin_family;
if (addr1.sin_addr.s_addr != addr2.sin_addr.s_addr)
return (addr1.sin_addr.s_addr - addr2.sin_addr.s_addr);
if (addr1.sin_port != addr2.sin_port)
return (addr1.sin_port - addr2.sin_port);
return 0;
}
addrs.clear();
int inaddr_cmp(struct sockaddr_in addr1, struct sockaddr_in addr2 )
{
#ifdef NET_DEBUG
std::string out;
rs_sprintf(out, "inaddr_cmp(%s-%lu,%s-%lu)", rs_inet_ntoa(addr1.sin_addr).c_str(), addr1.sin_addr.s_addr, rs_inet_ntoa(addr2.sin_addr).c_str(), addr2.sin_addr.s_addr);
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out);
#endif
#ifdef WINDOWS_SYS
// Seems strange to me but M$ documentation suggests to allocate this way...
DWORD bf_size = 16000;
IP_ADAPTER_ADDRESSES* adapter_addresses = (IP_ADAPTER_ADDRESSES*) malloc(bf_size);
DWORD error = GetAdaptersAddresses(AF_UNSPEC,
GAA_FLAG_SKIP_MULTICAST |
GAA_FLAG_SKIP_DNS_SERVER |
GAA_FLAG_SKIP_FRIENDLY_NAME,
NULL,
adapter_addresses,
&bf_size);
if (error != ERROR_SUCCESS) getLocalAddressesFailed();
if (addr1.sin_addr.s_addr == addr2.sin_addr.s_addr)
IP_ADAPTER_ADDRESSES* adapter(NULL);
for(adapter = adapter_addresses; NULL != adapter; adapter = adapter->Next)
{
return 0;
}
if (addr1.sin_addr.s_addr < addr2.sin_addr.s_addr)
return -1;
return 1;
}
int inaddr_cmp(struct sockaddr_in addr1, unsigned long addr2)
{
#ifdef NET_DEBUG
struct in_addr inaddr_tmp;
inaddr_tmp.s_addr = addr2;
std::string out;
rs_sprintf(out, "inaddr_cmp2(%s vs %s /or/ %10x vs %10x)", rs_inet_ntoa(addr1.sin_addr).c_str(), rs_inet_ntoa(inaddr_tmp).c_str(), addr1.sin_addr.s_addr, addr2);
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out);
#endif
if (addr1.sin_addr.s_addr == addr2)
IP_ADAPTER_UNICAST_ADDRESS* address;
for ( address = adapter->FirstUnicastAddress; address; address = address->Next)
{
return 0;
sockaddr_storage tmp;
sockaddr_storage_clear(tmp);
if (sockaddr_storage_copyip(tmp, * reinterpret_cast<sockaddr_storage*>(address->Address.lpSockaddr)))
addrs.push_back(tmp);
}
if (addr1.sin_addr.s_addr < addr2)
return -1;
return 1;
}
bool getPreferredInterface_ipv4(in_addr &routeAddr, struct in_addr &prefAddr) // returns best addr.
{
std::list<struct in_addr> addrs;
std::list<struct in_addr>::iterator it;
struct in_addr addr_zero, addr_loop, addr_priv, addr_ext;
#ifdef NET_DEBUG
struct in_addr addr;
#endif
bool found_zero = false;
bool found_loopback = false;
bool found_priv = false;
bool found_ext = false;
if (!getLocalInterfaces_ipv4(routeAddr, addrs))
}
free(adapter_addresses);
#else // WINDOWS_SYS
struct ifaddrs *ifsaddrs, *ifa;
if(getifaddrs(&ifsaddrs) != 0) getLocalAddressesFailed();
for ( ifa = ifsaddrs; ifa; ifa = ifa->ifa_next )
if ( ifa->ifa_addr && (ifa->ifa_flags & IFF_UP) )
{
return false;
sockaddr_storage tmp;
sockaddr_storage_clear(tmp);
if (sockaddr_storage_copyip(tmp, * reinterpret_cast<sockaddr_storage*>(ifa->ifa_addr)))
addrs.push_back(tmp);
}
memset(&addr_zero, 0, sizeof(addr_zero));
memset(&addr_loop, 0, sizeof(addr_loop));
memset(&addr_priv, 0, sizeof(addr_priv));
memset(&addr_ext, 0, sizeof(addr_ext));
freeifaddrs(ifsaddrs);
#endif // WINDOWS_SYS
#ifdef NET_DEBUG
memset(&addr, 0, sizeof(addr));
#endif
// find the first of each of these.
// if ext - take first.
// if no ext -> first priv
// if no priv -> first loopback.
#ifdef NET_DEBUG
std::cerr << "getPreferredInterface() " << addrs.size() << " interfaces." << std::endl;
#endif
std::list<sockaddr_storage>::iterator it;
std::cout << "getLocalAddresses(...) returning: <" ;
for(it = addrs.begin(); it != addrs.end(); ++it)
{
struct in_addr addr = *it;
#ifdef NET_DEBUG
std::cerr << "Examining addr: " << rs_inet_ntoa(addr);
std::cerr << " => " << (uint32_t) addr.s_addr << std::endl ;
std::cout << sockaddr_storage_iptostring(*it) << ", ";
std::cout << ">" << std::endl;
#endif
// for windows silliness (returning 0.0.0.0 as valid addr!).
if (addr.s_addr == 0)
{
if (!found_zero)
{
#ifdef NET_DEBUG
std::cerr << "\tFound Zero Address" << std::endl ;
#endif
found_zero = true;
addr_zero = addr;
}
}
else if (isLoopbackNet(&addr))
{
if (!found_loopback)
{
#ifdef NET_DEBUG
std::cerr << "\tFound Loopback Address" << std::endl ;
#endif
found_loopback = true;
addr_loop = addr;
}
}
else if (isPrivateNet(&addr))
{
if (!found_priv)
{
#ifdef NET_DEBUG
std::cerr << "\tFound Private Address" << std::endl ;
#endif
found_priv = true;
addr_priv = addr;
}
}
else
{
if (!found_ext)
{
#ifdef NET_DEBUG
std::cerr << "\tFound Other Address (Ext?) " << std::endl ;
#endif
found_ext = true;
addr_ext = addr;
}
}
}
if(found_ext) // external address is best.
{
prefAddr = addr_ext;
return true;
}
if (found_priv)
{
prefAddr = addr_priv;
return true;
}
// next bit can happen under windows,
// a general address is still
// preferable to a loopback device.
if (found_zero)
{
prefAddr = addr_zero;
return true;
}
if (found_loopback)
{
prefAddr = addr_loop;
return true;
}
// shound be 255.255.255.255 (error).
prefAddr.s_addr = 0xffffffff;
return false;
return !addrs.empty();
}
bool getPreferredInterface(struct sockaddr_storage &existAddr, struct sockaddr_storage &prefAddr)
{
struct in_addr existing_addr;
struct in_addr pref_addr;
{
struct sockaddr_in *eaddr = (sockaddr_in *) &existAddr;
if (eaddr->sin_family != AF_INET)
{
std::cerr << "getPreferredInterface() ERROR only valid for IPv4 for now";
abort();
return false;
}
existing_addr = eaddr->sin_addr;
}
if (getPreferredInterface_ipv4(existing_addr, pref_addr))
{
/* store into prefAddr */
sockaddr_storage_clear(prefAddr);
struct sockaddr_in *addr = (sockaddr_in *) &prefAddr;
addr->sin_family = AF_INET;
addr->sin_addr = pref_addr;
addr->sin_port = htons(0);
return true;
}
return false;
}
bool getLocalInterfaces(struct sockaddr_storage &existAddr, std::list<struct sockaddr_storage> &addrs)
{
struct in_addr existing_addr;
std::list<struct in_addr> local_addrs;
{
struct sockaddr_in *eaddr = (sockaddr_in *) &existAddr;
if (eaddr->sin_family != AF_INET)
{
std::cerr << "getLocalInterfaces() ERROR only valid for IPv4 for now";
abort();
return false;
}
existing_addr = eaddr->sin_addr;
}
if (getLocalInterfaces_ipv4(existing_addr, local_addrs))
{
std::list<struct in_addr>::iterator it;
for(it = local_addrs.begin(); it != local_addrs.end(); ++it)
{
/* store into prefAddr */
sockaddr_storage localAddr;
sockaddr_storage_clear(localAddr);
struct sockaddr_in *addr = (sockaddr_in *) &localAddr;
addr->sin_family = AF_INET;
addr->sin_addr = *it;
addr->sin_port = htons(0);
addrs.push_back(localAddr);
}
return true;
}
return false;
}
bool sameNet(const struct in_addr *addr, const struct in_addr *addr2)
{
#ifdef NET_DEBUG
std::cerr << "sameNet: " << rs_inet_ntoa(*addr);
std::cerr << " VS " << rs_inet_ntoa(*addr2);
std::cerr << std::endl;
#endif
struct in_addr addrnet, addrnet2;
addrnet.s_addr = inet_netof(*addr);
addrnet2.s_addr = inet_netof(*addr2);
#ifdef NET_DEBUG
std::cerr << " (" << rs_inet_ntoa(addrnet);
std::cerr << " =?= " << rs_inet_ntoa(addrnet2);
std::cerr << ")" << std::endl;
#endif
in_addr_t address1 = htonl(addr->s_addr);
in_addr_t address2 = htonl(addr2->s_addr);
// handle case for private net: 172.16.0.0/12
if (address1>>20 == (172<<4 | 16>>4))
{
return (address1>>20 == address2>>20);
}
return (inet_netof(*addr) == inet_netof(*addr2));
}
bool isSameSubnet(struct in_addr *addr1, struct in_addr *addr2)
{
/*
* check that the (addr1 & 255.255.255.0) == (addr2 & 255.255.255.0)
*/
unsigned long a1 = ntohl(addr1->s_addr);
unsigned long a2 = ntohl(addr2->s_addr);
return ((a1 & 0xffffff00) == (a2 & 0xffffff00));
}
/* This just might be portable!!! will see!!!
* Unfortunately this is usable on winXP+, determined by: (_WIN32_WINNT >= 0x0501)
* but not older platforms.... which must use gethostbyname.
*
* include it for now.....
*/
bool LookupDNSAddr(std::string name, struct sockaddr_in &addr)
{
#if 1
char service[100];
struct addrinfo hints_st;
struct addrinfo *hints = &hints_st;
struct addrinfo *res;
hints -> ai_flags = 0; // (cygwin don;t like these) AI_ADDRCONFIG | AI_NUMERICSERV;
hints -> ai_family = AF_INET;
hints -> ai_socktype = 0;
hints -> ai_protocol = 0;
hints -> ai_addrlen = 0;
hints -> ai_addr = NULL;
hints -> ai_canonname = NULL;
hints -> ai_next = NULL;
/* get the port number */
sprintf(service, "%d", ntohs(addr.sin_port));
/* set it to IPV4 */
#ifdef NET_DEBUG
std::cerr << "LookupDNSAddr() name: " << name << " service: " << service << std::endl;
#endif
int err = 0;
if (0 != (err = getaddrinfo(name.c_str(), service, hints, &res)))
{
#ifdef NET_DEBUG
std::cerr << "LookupDNSAddr() getaddrinfo failed!" << std::endl;
std::cerr << "Error: " << gai_strerror(err) << std::endl;
#endif
return false;
}
if (res)
{
if (res->ai_family == AF_INET)
{
addr = *((struct sockaddr_in *) res->ai_addr);
freeaddrinfo(res);
#ifdef NET_DEBUG
std::cerr << "LookupDNSAddr() getaddrinfo found address" << std::endl;
std::cerr << "addr: " << rs_inet_ntoa(addr.sin_addr) << std::endl;
std::cerr << "port: " << ntohs(addr.sin_port) << std::endl;
#endif
return true;
}
freeaddrinfo(res);
}
#ifdef NET_DEBUG
std::cerr << "getaddrinfo failed - no address" << std::endl;
#endif
#endif
#ifdef NET_DEBUG
//std::cerr << "getaddrinfo disabled" << std::endl;
#endif
return false;
}
/*************************************************************
* Socket Library Wrapper Functions
* to get over the crapness of the windows.
@ -899,16 +363,14 @@ int unix_close(int fd)
return ret;
}
int unix_socket(int /*domain*/, int /*type*/, int /*protocol*/)
int unix_socket(int domain, int type, int protocol)
{
int osock = socket(PF_INET, SOCK_STREAM, 0);
/******************* WINDOWS SPECIFIC PART ******************/
#ifdef WINDOWS_SYS // WINDOWS
int osock = socket(domain, type, protocol);
#ifdef WINDOWS_SYS
#ifdef NET_DEBUG
std::cerr << "unix_socket()" << std::endl;
#endif
#endif // NET_DEBUG
if ((unsigned) osock == INVALID_SOCKET)
{
@ -916,8 +378,8 @@ int unix_socket(int /*domain*/, int /*type*/, int /*protocol*/)
osock = -1;
errno = WinToUnixError(WSAGetLastError());
}
#endif
/******************* WINDOWS SPECIFIC PART ******************/
#endif // WINDOWS_SYS
return osock;
}

View file

@ -38,6 +38,7 @@
#include <arpa/inet.h>
#include <sys/poll.h>
#include <errno.h>
//socket blocking/options.
#include <fcntl.h>
@ -48,9 +49,6 @@
#include "util/rsnet.h" /* more generic networking header */
// Some Network functions that are missing from windows.
in_addr_t inet_netof(struct in_addr addr);
in_addr_t inet_network(const char *inet_name);
int inet_aton(const char *name, struct in_addr *addr);
extern int errno; /* Define extern errno, to duplicate unix behaviour */
@ -93,24 +91,11 @@ extern int errno; /* Define extern errno, to duplicate unix behaviour */
#include <list>
// Same def - different functions...
void showSocketError(std::string &out);
std::string socket_errorType(int err);
int sockaddr_cmp(struct sockaddr_in &addr1, struct sockaddr_in &addr2 );
int inaddr_cmp(struct sockaddr_in addr1, struct sockaddr_in addr2 );
int inaddr_cmp(struct sockaddr_in addr1, unsigned long);
bool getPreferredInterface(struct sockaddr_storage &existAddr, struct sockaddr_storage &prefAddr); // returns best addr.
bool getLocalInterfaces(struct sockaddr_storage &existAddr, std::list<struct sockaddr_storage> &addrs); // returns all possible addrs.
// checks (addr1 & 255.255.255.0) == (addr2 & 255.255.255.0)
bool isSameSubnet(struct in_addr *addr1, struct in_addr *addr2);
bool sameNet(const struct in_addr *addr, const struct in_addr *addr2);
in_addr_t pqi_inet_netof(struct in_addr addr); // our implementation.
bool LookupDNSAddr(std::string name, struct sockaddr_in &addr);
bool getLocalAddresses(std::list<struct sockaddr_storage> & addrs);
/* universal socket interface */

Some files were not shown because too many files have changed in this diff Show more