diff --git a/.travis.yml b/.travis.yml index d2d2c2781..5be37e084 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/README.md b/README.md index 4072f6a3f..5738b6cb9 100644 --- a/README.md +++ b/README.md @@ -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 ``` diff --git a/RetroShare.pro b/RetroShare.pro index 4a1be6b49..c4c937448 100644 --- a/RetroShare.pro +++ b/RetroShare.pro @@ -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 +} diff --git a/Start_RetroShare-Gui_Debug.bat b/Start_RetroShare-Gui_Debug.bat new file mode 100755 index 000000000..3ba38c3f8 --- /dev/null +++ b/Start_RetroShare-Gui_Debug.bat @@ -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 diff --git a/TODO.txt b/TODO.txt index ef4d189fb..653c4cb8e 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,345 +1,126 @@ +Legend: + 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. + + [ ] pending + [/] half-done, someone's on it + [-] cancelled + [X] done + +PS: no tabs in this file,thx ;-) + +----------------------------------------- TODO list ---------------------------------------------- + +GUI + E [ ] 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. + +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) + +DHT + H [ ] improve DHT lookups to find masquerading peers using fake peers. First experiments (by cyril) do not prove very efficient. + +GXS + M [X] create a tunnel service from distant chat code to make it (1) more generic (2) resistant to packet loss. + M [ ] 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 + +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 + + +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 [ ] add flags to allow distant messaging from contact list only / everyone / noone / only signed ids. + +Chat + E [ ] add flags to allow distant chat from contact list only / everyone / noone / only signed ids. + +Libretroshare + 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 + #3 0x0000000000fc1643 in RsServiceSerialiser::deserialise(void*, unsigned int*) () + #4 0x0000000000da4451 in RsSerialiser::deserialise(void*, unsigned int*) () + #5 0x0000000000fb5b4b in pqistreamer::handleincoming_locked() () + #6 0x0000000000fb4b3e in pqistreamer::tick_recv(unsigned int) () + #7 0x0000000000fb744a in pqithreadstreamer::data_tick() () + #8 0x0000000000e19b27 in RsTickingThread::runloop (this=0x7fffb004e7e8) at util/rsthreads.cc:196 + #9 0x0000000000e19748 in RsThread::rsthread_init (p=0x7fffb004e7e8) at util/rsthreads.cc:63 + #10 0x00007ffff4006f6b in start_thread () from /lib64/libpthread.so.0 + #11 0x00007ffff351c7ed in clone () from /lib64/libc.so.6 + +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 + +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,... + +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 + +Bugs + E [ ] find the bug that shows some peers online in Network although they are not. + M [ ] Selecting different options in messages composer -> contact list then come back, + shows disappearing / re-appearing people. What causes this??? + +Settings + 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. + +Packaging + E [ ] Sound files should be part of the install package at least on ubuntu (put them in /usr/share) + 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. - ----------------------------------------- GUI TWEAKS FOR 0.6 RELEASE ------------------------------------------------- - -To be done - -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 - explain what the service does and the dependencies - - 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. - - 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 - - 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. - - 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? - - 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 - - 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 @ - - 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 - - #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 - #3 0x0000000000fc1643 in RsServiceSerialiser::deserialise(void*, unsigned int*) () - #4 0x0000000000da4451 in RsSerialiser::deserialise(void*, unsigned int*) () - #5 0x0000000000fb5b4b in pqistreamer::handleincoming_locked() () - #6 0x0000000000fb4b3e in pqistreamer::tick_recv(unsigned int) () - #7 0x0000000000fb744a in pqithreadstreamer::data_tick() () - #8 0x0000000000e19b27 in RsTickingThread::runloop (this=0x7fffb004e7e8) at util/rsthreads.cc:196 - #9 0x0000000000e19748 in RsThread::rsthread_init (p=0x7fffb004e7e8) at util/rsthreads.cc:63 - #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) - - Post v0.6 release changes - ========================= - - 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) - - 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 - - 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 - - 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 - - Chat -H [ ] add "chat with this peer" from lobbies to start a private distant conversation with the GXS id of the peer - - 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. diff --git a/WindowsMSys2_InstallGuide.txt b/WindowsMSys2_InstallGuide.txt new file mode 100644 index 000000000..ded6a1420 --- /dev/null +++ b/WindowsMSys2_InstallGuide.txt @@ -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 + diff --git a/build-all-mingw32make.bat b/build-all-mingw32make.bat old mode 100644 new mode 100755 index 819642b46..49eebe687 --- a/build-all-mingw32make.bat +++ b/build-all-mingw32make.bat @@ -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 @@ -19,12 +19,12 @@ if %1x == x ( ) if /i %1==clean ( set clean=clean - shift + shift goto :loop1 ) if /i %1==pack ( set pack=pack - shift + shift goto :loop1 ) echo.%1>>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 -qmake retroshare-gui.pro "CONFIG+=version_detail_bash_script" +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 \ No newline at end of file diff --git a/build_scripts/Debian+Ubuntu/changelog b/build_scripts/Debian+Ubuntu/changelog index ff2101d8a..70bbeb0e0 100644 --- a/build_scripts/Debian+Ubuntu/changelog +++ b/build_scripts/Debian+Ubuntu/changelog @@ -1,5 +1,325 @@ retroshare06 (0.6.0-1.XXXXXX~YYYYYY) YYYYYY; 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 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 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 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 +418,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 Sun, 16 Aug 2015 20:00:00 +0100 + -- Cyril Soler 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 @@ -1232,7 +1552,7 @@ retroshare06 (0.6.0-0.7555~precise) precise; urgency=low - this version is the first unstable release of 0.6. It is incompatible with v0.5.5, but can be used simultaneously on the same computer. Please see release notes for v0.6 on https://retroshareteam.wordpress.com/ - + -- Cyril Soler Sun, 21 Sep 2014 20:00:00 +0100 retroshare (0.5.5-0.XXXXXX~YYYYYY) YYYYYY; urgency=low @@ -1487,9 +1807,9 @@ retroshare (0.5.5-0.6804~precise) precise; urgency=low retroshare (0.5.5-0.6732~precise) precise; urgency=low * Notes - This is the final release of the 0.5 brand. + This is the final release of the 0.5 brand. - - distant chat (encrypted with AES-PSK using tunnels, autenticated with PGP) + - distant chat (encrypted with AES-PSK using tunnels, autenticated with PGP) - distant messages (encrypted, through tunnels) => See http://retroshareteam.wordpress.com/2013/08/08/distant-chat-and-messaging-using-generic-tunnels/ - connection progress/status dialog @@ -1504,9 +1824,9 @@ retroshare (0.5.4-0.6685~precise) precise; urgency=low * Improvements - Added connection progress dialog, to show connection state, and give some feedback/advice to the user - added storage for denied connections in linkMgr - - new splash screen / about image - - improved GUI layout. Many patches, mainly from Phenom, electron - - GUI improvement for distant messages, showing correct names, handling links, correct toasters, etc + - new splash screen / about image + - improved GUI layout. Many patches, mainly from Phenom, electron + - GUI improvement for distant messages, showing correct names, handling links, correct toasters, etc - improved security feed so that one can send distant messages to peers that attempt to connect - improved command line parameter handling (used argstream class) - Disabled setting "Start RetroShare when my system starts" on Windows when running the debug version. @@ -1531,7 +1851,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 addign 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 @@ -1561,10 +1881,10 @@ retroshare (0.5.4-0.6546~precise) precise; urgency=low - added DynDNS to RS certificate link if available - removed MT19937 random generator which is not used anymore. Changed N from 624 to 1024 to reduce cost - improved completion for chat (Patch from Phenom) - - added help panels in MainWindow, to help beginners startup with the basic concepts. + - added help panels in MainWindow, to help beginners startup with the basic concepts. - changed welcome message in broadcast chat - improved GUI layouts in FriendList, NewsFeed, Forums, Channels, removed doubling unused buttons - - added last time of transfer (Patch from Phenom) + - added last time of transfer (Patch from Phenom) - added column with IP for connected peers (modified patch from Phenom) - Removed some more hardcoded colors - added completer to MimeTextEdit and ChatWidget (Patch from Phenom) @@ -2272,8 +2592,8 @@ retroshare (0.5.3-0.5327~natty) natty; urgency=low window by clicking on "manage keys/locations". This allows to easily create a new location with the same pgp key on another computer. To obtain a suitable keypair using gnupg, you need to concatenate the encrypted private key and the public key into an ascii file. This can be done using: - gpg -a --export-secret-keys [your ID] > mykey.asc - gpg -a --export [your ID] >> mykey.asc + gpg -a --export-secret-keys [your ID] > mykey.asc + gpg -a --export [your ID] >> mykey.asc * importing a key with subkeys in not yet possible. Please remove subkeys before importing. @@ -2303,10 +2623,10 @@ retroshare (0.5.3-0.5327~natty) natty; urgency=low * key removal from keyring. This is a challenge to keep locations synchronised. - Rework of tcponudp/tcpstream should make UDP connections much more stable. - * Fixed retransmit algorithm. Much more closely matched to TCP standard: http://tools.ietf.org/html/rfc2988 - * This increases retransmit timeouts, and reduces the number of packets resent. - * Added better debugging for retrans/close as separate #defines. - * Further testing is required ;) + * Fixed retransmit algorithm. Much more closely matched to TCP standard: http://tools.ietf.org/html/rfc2988 + * This increases retransmit timeouts, and reduces the number of packets resent. + * Added better debugging for retrans/close as separate #defines. + * Further testing is required ;) - Added dynamic choose of sources for chunk crc requests. Fixes the bug that would let a transfer not finish if the original surce for a crc is not here anymore. @@ -2508,7 +2828,7 @@ retroshare (0.5.3-0.5067~natty) natty; urgency=low - update new Spanish translation from Aitor - Added two new functions to libretroshare for writing formatted data to std::string - Added two new images from defnax to SecurityItem for SEC_TYPE_CONNECT_ATTEMPT and SEC_TYPE_UNKNOWN_IN.kkkkk - - added new toasters for private/group/lobby chat. + - added new toasters for private/group/lobby chat. - added copy certificate button to profile widget - added topics to chat lobbies. Improved CL gui - added deferred checking of chunks in FT. Not fully functional yet, for backward compatibility reasons. @@ -2582,8 +2902,8 @@ retroshare (0.5.3-0.4953~natty) natty; urgency=low * The forum/channel news feed is removed when the user reads the message in forums/channels * The standard font is now used for new chat lobbies. * Added a new menu item to set the font of a private chat and chat lobby to the default font. - * Changed the color of the time of the compact chat style from red to gray. - * disabled autodownload when subscribing to a channel. + * Changed the color of the time of the compact chat style from red to gray. + * disabled autodownload when subscribing to a channel. * set a icon for Friend Recommendation menu action * Sort nick names by name in the chat lobby. @@ -2641,7 +2961,7 @@ retroshare (0.5.3-0.4885~natty) natty; urgency=low * Unified Text Source. * Added "Cut Below Here" line - Switched BanList sharing to only your own list. (was OWN + FRIENDS lists) - This data is not used at the moment, so just reducing data before release. + This data is not used at the moment, so just reducing data before release. - Updated English Email Invite (sorry guys, you'll have to redo translations). - Set OSX default style to "Cleanlooks" - as AQUA style hides some windows. - Updated Version strings to V0.5.3a. / 4874 diff --git a/build_scripts/Debian+Ubuntu/makeSourcePackage.sh b/build_scripts/Debian+Ubuntu/makeSourcePackage.sh index 78efdf17e..40f0999dc 100755 --- a/build_scripts/Debian+Ubuntu/makeSourcePackage.sh +++ b/build_scripts/Debian+Ubuntu/makeSourcePackage.sh @@ -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... diff --git a/libbitdht/src/bitdht/Makefile b/libbitdht/src/bitdht/Makefile deleted file mode 100644 index 60e7b510b..000000000 --- a/libbitdht/src/bitdht/Makefile +++ /dev/null @@ -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 diff --git a/libbitdht/src/example/Makefile b/libbitdht/src/example/Makefile deleted file mode 100644 index 447407bb9..000000000 --- a/libbitdht/src/example/Makefile +++ /dev/null @@ -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) - - diff --git a/libbitdht/src/libbitdht.pro b/libbitdht/src/libbitdht.pro index 7d6dca1d6..a5251590f 100644 --- a/libbitdht/src/libbitdht.pro +++ b/libbitdht/src/libbitdht.pro @@ -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 \ - - diff --git a/libbitdht/src/tests/Makefile b/libbitdht/src/tests/Makefile deleted file mode 100644 index 5d6cc7f5c..000000000 --- a/libbitdht/src/tests/Makefile +++ /dev/null @@ -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 -############################################################### - diff --git a/libbitdht/src/udp/udplayer.cc b/libbitdht/src/udp/udplayer.cc index ddf0258de..4a37abf16 100644 --- a/libbitdht/src/udp/udplayer.cc +++ b/libbitdht/src/udp/udplayer.cc @@ -32,6 +32,7 @@ #include #include #include +#include /*** * #define UDP_ENABLE_BROADCAST 1 diff --git a/libbitdht/src/util/bdrandom.cc b/libbitdht/src/util/bdrandom.cc index 3d2bc6a66..6288f86b8 100644 --- a/libbitdht/src/util/bdrandom.cc +++ b/libbitdht/src/util/bdrandom.cc @@ -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__) diff --git a/libresapi/src/api/ApiServerMHD.cpp b/libresapi/src/api/ApiServerMHD.cpp index 898105b60..2feed2d42 100644 --- a/libresapi/src/api/ApiServerMHD.cpp +++ b/libresapi/src/api/ApiServerMHD.cpp @@ -7,6 +7,7 @@ #include #include +#include "util/ContentTypes.h" // for filestreamer #include @@ -274,12 +275,21 @@ 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()) - { - sendMessage(connection, MHD_HTTP_NOT_FOUND, "Error: URL is not a valid file hash"); - return MHD_YES; - } + } + 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 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; diff --git a/libresapi/src/api/ChatHandler.cpp b/libresapi/src/api/ChatHandler.cpp index 49470d816..a99759990 100644 --- a/libresapi/src/api/ChatHandler.cpp +++ b/libresapi/src/api/ChatHandler.cpp @@ -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,14 +71,18 @@ StreamBase& operator <<(StreamBase& left, KeyValueReference 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("distant_chat_id", l.distant_chat_id); + << makeKeyValueReference("distant_chat_id", l.distant_chat_id) + << makeKeyValueReference("is_broadcast", l.is_broadcast); return left; } @@ -158,10 +168,24 @@ void ChatHandler::tick() l.auto_subscribe = info.lobby_flags & RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE; l.is_private = !(info.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC); l.distant_chat_id.clear() ; + l.is_broadcast = false; lobbies.push_back(l); } } + ChatId id = ChatId::makeBroadcastId(); + { + Lobby l; + l.id = id.toLobbyId(); + 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 unsubscribed_lobbies; mRsMsgs->getListOfNearbyChatLobbies(unsubscribed_lobbies); for(std::vector::iterator vit = unsubscribed_lobbies.begin(); vit != unsubscribed_lobbies.end(); ++vit) @@ -177,6 +201,7 @@ void ChatHandler::tick() l.auto_subscribe = info.lobby_flags & RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE; l.is_private = !(info.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC); l.distant_chat_id.clear(); + l.is_broadcast = false; lobbies.push_back(l); } } @@ -305,62 +330,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 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 = ""; - 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; @@ -401,7 +371,77 @@ void ChatHandler::tick() } } -void ChatHandler::handleWildcard(Request &req, Response &resp) +void ChatHandler::getPlainText(const std::string& in, std::string &out, std::vector &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) != " 6) + last_six_chars = last_six_chars.substr(1); + std::string 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(); @@ -458,7 +498,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); @@ -637,17 +677,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 **********/ diff --git a/libresapi/src/api/ChatHandler.h b/libresapi/src/api/ChatHandler.h index 59c5a4d77..1d4ed221f 100644 --- a/libresapi/src/api/ChatHandler.h +++ b/libresapi/src/api/ChatHandler.h @@ -57,15 +57,16 @@ 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; - DistantChatPeerId distant_chat_id;// for subscribed lobbies: the id we use to write messages + RsGxsId distant_chat_id;// for subscribed lobbies: the id we use to write messages bool operator==(const Lobby& l) const { @@ -75,7 +76,8 @@ public: && subscribed == l.subscribed && auto_subscribe == l.auto_subscribe && is_private == l.is_private - && distant_chat_id == l.distant_chat_id; + && id == l.id + && is_broadcast == l.is_broadcast; } }; @@ -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 &links); + StateTokenServer* mStateTokenServer; RsNotify* mNotify; RsMsgs* mRsMsgs; diff --git a/libresapi/src/api/Operators.cpp b/libresapi/src/api/Operators.cpp index 223aa1a9e..97dff652d 100644 --- a/libresapi/src/api/Operators.cpp +++ b/libresapi/src/api/Operators.cpp @@ -14,9 +14,9 @@ StreamBase& operator <<(StreamBase& left, KeyValueReference 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 diff --git a/libresapi/src/api/RsControlModule.cpp b/libresapi/src/api/RsControlModule.cpp index 112994891..43a5c2241 100644 --- a/libresapi/src/api/RsControlModule.cpp +++ b/libresapi/src/api/RsControlModule.cpp @@ -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; } } diff --git a/libresapi/src/libresapi.pro b/libresapi/src/libresapi.pro index a45255e45..80e4650ae 100644 --- a/libresapi/src/libresapi.pro +++ b/libresapi/src/libresapi.pro @@ -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 += /usr/local/include + LIBS *= /usr/local/lib/libmicrohttpd.a + } else { + LIBS *= -lmicrohttpd + } + } SOURCES += \ api/ApiServerMHD.cpp @@ -51,7 +64,8 @@ SOURCES += \ api/GetPluginInterfaces.cpp \ api/ChatHandler.cpp \ api/LivereloadHandler.cpp \ - api/TmpBlobStore.cpp + api/TmpBlobStore.cpp \ + util/ContentTypes.cpp HEADERS += \ api/ApiServer.h \ @@ -74,4 +88,5 @@ HEADERS += \ api/GetPluginInterfaces.h \ api/ChatHandler.h \ api/LivereloadHandler.h \ - api/TmpBlobStore.h + api/TmpBlobStore.h \ + util/ContentTypes.h diff --git a/libresapi/src/util/ContentTypes.cpp b/libresapi/src/util/ContentTypes.cpp new file mode 100644 index 000000000..30434e093 --- /dev/null +++ b/libresapi/src/util/ContentTypes.cpp @@ -0,0 +1,88 @@ +#include "ContentTypes.h" +#include +#include +#include + +RsMutex ContentTypes::ctmtx = RsMutex("CTMTX"); +std::map 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::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"; +} + diff --git a/libresapi/src/util/ContentTypes.h b/libresapi/src/util/ContentTypes.h new file mode 100644 index 000000000..0e6b71e73 --- /dev/null +++ b/libresapi/src/util/ContentTypes.h @@ -0,0 +1,23 @@ +#ifndef CONTENTTYPES_H +#define CONTENTTYPES_H + +#include +#include +#include + +#define DEFAULTCT "application/octet-stream" + +class ContentTypes +{ +public: + static std::string cTypeFromExt(const std::string& extension); + +private: + static std::map cache; + static RsMutex ctmtx; + static const char* filename; + static bool inited; + static void addBasic(); +}; + +#endif // CONTENTTYPES_H diff --git a/libresapi/src/webfiles/green-black.css b/libresapi/src/webfiles/green-black.css index 1d4e8da41..31778e201 100644 --- a/libresapi/src/webfiles/green-black.css +++ b/libresapi/src/webfiles/green-black.css @@ -66,6 +66,10 @@ td{ background-color: midnightblue; } +.filelink{ + color: inherit; +} + input, textarea{ color: lime; font-family: monospace; diff --git a/libresapi/src/webfiles/gui.jsx b/libresapi/src/webfiles/gui.jsx index 76cd80a60..9df49c877 100644 --- a/libresapi/src/webfiles/gui.jsx +++ b/libresapi/src/webfiles/gui.jsx @@ -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 =
; - if(file.name.slice(-3) === "mp3") + var splits = file.name.split("."); + if(splits[splits.length-1].toLowerCase() in extensions) playBtn =
play
; var ctrlBtn =
; @@ -571,7 +580,7 @@ var DownloadsWidget = React.createClass({ ctrlBtn =
pause
; } return( - {this.props.data.name} + {this.props.data.name} {makeFriendlyUnit(this.props.data.size)} {makeFriendlyUnit(this.props.data.transfer_rate*1e3)}/s @@ -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( -
-

{this.state.file.name}

- -
- ); + var splits = this.state.file.name.split("."); + var mediatype = extensions[splits[splits.length - 1].toLowerCase()]; + if (mediatype == "audio") { + return ( +
+

{this.state.file.name}

+ +
+ ); + } else if (mediatype == "video") { + return( +
+

{this.state.file.name}

+ +
+ ); + } else { + return(
); + } } }, }); @@ -1467,7 +1491,7 @@ var ChatWidget = React.createClass({ { this.state.data.map(function(msg){ - return
{msg.send_time} {msg.author_name}: {markup(msg.msg, msg.links)}
; + return
{new Date(msg.send_time*1000).toLocaleTimeString()} {msg.author_name}: {markup(msg.msg, msg.links)}
; }) } - + {mainpage} ; diff --git a/libresapi/src/webui/green-black.css b/libresapi/src/webui/green-black.css index 1d4e8da41..31778e201 100644 --- a/libresapi/src/webui/green-black.css +++ b/libresapi/src/webui/green-black.css @@ -66,6 +66,10 @@ td{ background-color: midnightblue; } +.filelink{ + color: inherit; +} + input, textarea{ color: lime; font-family: monospace; diff --git a/libresapi/src/webui/gui.jsx b/libresapi/src/webui/gui.jsx index 76cd80a60..9df49c877 100644 --- a/libresapi/src/webui/gui.jsx +++ b/libresapi/src/webui/gui.jsx @@ -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 =
; - if(file.name.slice(-3) === "mp3") + var splits = file.name.split("."); + if(splits[splits.length-1].toLowerCase() in extensions) playBtn =
play
; var ctrlBtn =
; @@ -571,7 +580,7 @@ var DownloadsWidget = React.createClass({ ctrlBtn =
pause
; } return( - {this.props.data.name} + {this.props.data.name} {makeFriendlyUnit(this.props.data.size)} {makeFriendlyUnit(this.props.data.transfer_rate*1e3)}/s @@ -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( -
-

{this.state.file.name}

- -
- ); + var splits = this.state.file.name.split("."); + var mediatype = extensions[splits[splits.length - 1].toLowerCase()]; + if (mediatype == "audio") { + return ( +
+

{this.state.file.name}

+ +
+ ); + } else if (mediatype == "video") { + return( +
+

{this.state.file.name}

+ +
+ ); + } else { + return(
); + } } }, }); @@ -1467,7 +1491,7 @@ var ChatWidget = React.createClass({ { this.state.data.map(function(msg){ - return
{msg.send_time} {msg.author_name}: {markup(msg.msg, msg.links)}
; + return
{new Date(msg.send_time*1000).toLocaleTimeString()} {msg.author_name}: {markup(msg.msg, msg.links)}
; }) } - + {mainpage} ; diff --git a/libretroshare/src/chat/distributedchat.cc b/libretroshare/src/chat/distributedchat.cc index 7a683c2eb..72a3f2a93 100644 --- a/libretroshare/src/chat/distributedchat.cc +++ b/libretroshare/src/chat/distributedchat.cc @@ -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.mPgpLinked) { 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.mPgpLinked) { 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! diff --git a/libretroshare/src/dbase/fimonitor.cc b/libretroshare/src/dbase/fimonitor.cc index 400853beb..91a8ffb9b 100644 --- a/libretroshare/src/dbase/fimonitor.cc +++ b/libretroshare/src/dbase/fimonitor.cc @@ -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 ; } diff --git a/libretroshare/src/dbase/findex.cc b/libretroshare/src/dbase/findex.cc index 582785f21..1eeea8c9d 100644 --- a/libretroshare/src/dbase/findex.cc +++ b/libretroshare/src/dbase/findex.cc @@ -780,7 +780,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 +1089,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 +1370,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; diff --git a/libretroshare/src/ft/ftchunkmap.cc b/libretroshare/src/ft/ftchunkmap.cc index 49550077b..39d04efe6 100644 --- a/libretroshare/src/ft/ftchunkmap.cc +++ b/libretroshare/src/ft/ftchunkmap.cc @@ -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 ; diff --git a/libretroshare/src/grouter/grouteritems.cc b/libretroshare/src/grouter/grouteritems.cc index 14c3164c5..b67ed71e6 100644 --- a/libretroshare/src/grouter/grouteritems.cc +++ b/libretroshare/src/grouter/grouteritems.cc @@ -45,17 +45,18 @@ RsItem *RsGRouterSerialiser::deserialise(void *data, uint32_t *pktsize) switch(getRsItemSubType(rstype)) { - case RS_PKT_SUBTYPE_GROUTER_DATA: return deserialise_RsGRouterGenericDataItem (data, *pktsize); - case RS_PKT_SUBTYPE_GROUTER_TRANSACTION_CHUNK: return deserialise_RsGRouterTransactionChunkItem(data, *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_FRIENDS_LIST: return deserialise_RsGRouterMatrixFriendListItem(data, *pktsize); - case RS_PKT_SUBTYPE_GROUTER_ROUTING_INFO: return deserialise_RsGRouterRoutingInfoItem (data, *pktsize); + case RS_PKT_SUBTYPE_GROUTER_DATA: return deserialise_RsGRouterGenericDataItem (data, *pktsize); + case RS_PKT_SUBTYPE_GROUTER_TRANSACTION_CHUNK: return deserialise_RsGRouterTransactionChunkItem(data, *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); - default: - std::cerr << "RsGRouterSerialiser::deserialise(): Could not de-serialise item. SubPacket id = " << std::hex << getRsItemSubType(rstype) << " id = " << rstype << std::dec << std::endl; - return NULL; + default: + std::cerr << "RsGRouterSerialiser::deserialise(): Could not de-serialise item. SubPacket id = " << std::hex << getRsItemSubType(rstype) << " id = " << rstype << std::dec << std::endl; + return NULL; } return NULL; } @@ -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 ; diff --git a/libretroshare/src/grouter/grouteritems.h b/libretroshare/src/grouter/grouteritems.h index ea42eea61..574c7b3c4 100644 --- a/libretroshare/src/grouter/grouteritems.h +++ b/libretroshare/src/grouter/grouteritems.h @@ -33,20 +33,19 @@ #include "retroshare/rsgrouter.h" #include "groutermatrix.h" -const uint8_t RS_PKT_SUBTYPE_GROUTER_PUBLISH_KEY = 0x01 ; // used to publish a key -const uint8_t RS_PKT_SUBTYPE_GROUTER_ACK_deprecated = 0x03 ; // don't use! -const uint8_t RS_PKT_SUBTYPE_GROUTER_SIGNED_RECEIPT_deprecated = 0x04 ; // don't use! -const uint8_t RS_PKT_SUBTYPE_GROUTER_DATA_deprecated = 0x05 ; // don't use! -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_PUBLISH_KEY = 0x01 ; // used to publish a key +const uint8_t RS_PKT_SUBTYPE_GROUTER_ACK_deprecated = 0x03 ; // don't use! +const uint8_t RS_PKT_SUBTYPE_GROUTER_SIGNED_RECEIPT_deprecated = 0x04 ; // don't use! +const uint8_t RS_PKT_SUBTYPE_GROUTER_DATA_deprecated = 0x05 ; // don't use! +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 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 ; }; diff --git a/libretroshare/src/grouter/groutermatrix.cc b/libretroshare/src/grouter/groutermatrix.cc index 1401f6a6c..a6bb063cf 100644 --- a/libretroshare/src/grouter/groutermatrix.cc +++ b/libretroshare/src/grouter/groutermatrix.cc @@ -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::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::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. @@ -115,7 +157,19 @@ void GRouterMatrix::getListOfKnownKeys(std::vector& key_ids) const key_ids.clear() ; for(std::map >::const_iterator it(_time_combined_hits.begin());it!=_time_combined_hits.end();++it) - key_ids.push_back(it->first) ; + key_ids.push_back(it->first) ; +} + +bool GRouterMatrix::getTrackingInfo(const RsGxsMessageId& mid, RsPeerId &source_friend) +{ + std::map::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 @@ -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::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& friends, std::vector& probas) const @@ -241,55 +299,78 @@ bool GRouterMatrix::saveList(std::list& items) std::cerr << " GRoutingMatrix::saveList()" << std::endl; #endif - RsGRouterMatrixFriendListItem *item = new RsGRouterMatrixFriendListItem ; + RsGRouterMatrixFriendListItem *item = new RsGRouterMatrixFriendListItem ; - item->reverse_friend_indices = _reverse_friend_indices ; - items.push_back(item) ; + item->reverse_friend_indices = _reverse_friend_indices ; + items.push_back(item) ; - for(std::map >::const_iterator it(_routing_clues.begin());it!=_routing_clues.end();++it) - { - RsGRouterMatrixCluesItem *item = new RsGRouterMatrixCluesItem ; + for(std::map >::const_iterator it(_routing_clues.begin());it!=_routing_clues.end();++it) + { + RsGRouterMatrixCluesItem *item = new RsGRouterMatrixCluesItem ; - item->destination_key = it->first ; - item->clues = it->second ; + item->destination_key = it->first ; + item->clues = it->second ; - items.push_back(item) ; - } + items.push_back(item) ; + } - return true ; + for(std::map::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& items) { - RsGRouterMatrixFriendListItem *itm1 = NULL ; - RsGRouterMatrixCluesItem *itm2 = NULL ; + RsGRouterMatrixFriendListItem *itm1 = NULL ; + RsGRouterMatrixCluesItem *itm2 = NULL ; + RsGRouterMatrixTrackItem *itm3 = NULL ; #ifdef ROUTING_MATRIX_DEBUG std::cerr << " GRoutingMatrix::loadList()" << std::endl; #endif - for(std::list::const_iterator it(items.begin());it!=items.end();++it) - { - if(NULL != (itm2 = dynamic_cast(*it))) - { + for(std::list::const_iterator it(items.begin());it!=items.end();++it) + { + if(NULL != (itm3 = dynamic_cast(*it))) + { #ifdef ROUTING_MATRIX_DEBUG - std::cerr << " initing routing clues." << std::endl; + 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(*it))) + { +#ifdef ROUTING_MATRIX_DEBUG + std::cerr << " initing routing clues." << std::endl; #endif - _routing_clues[itm2->destination_key] = itm2->clues ; - _proba_need_updating = true ; // notifies to re-compute all the info. - } - if(NULL != (itm1 = dynamic_cast(*it))) - { - _reverse_friend_indices = itm1->reverse_friend_indices ; - _friend_indices.clear() ; + _routing_clues[itm2->destination_key] = itm2->clues ; + _proba_need_updating = true ; // notifies to re-compute all the info. + } + if(NULL != (itm1 = dynamic_cast(*it))) + { + _reverse_friend_indices = itm1->reverse_friend_indices ; + _friend_indices.clear() ; - for(uint32_t i=0;i<_reverse_friend_indices.size();++i) - _friend_indices[_reverse_friend_indices[i]] = i ; + for(uint32_t i=0;i<_reverse_friend_indices.size();++i) + _friend_indices[_reverse_friend_indices[i]] = i ; - _proba_need_updating = true ; // notifies to re-compute all the info. - } - } + _proba_need_updating = true ; // notifies to re-compute all the info. + } + } - return true ; + return true ; } diff --git a/libretroshare/src/grouter/groutermatrix.h b/libretroshare/src/grouter/groutermatrix.h index 4c9ddee95..18c0cb189 100644 --- a/libretroshare/src/grouter/groutermatrix.h +++ b/libretroshare/src/grouter/groutermatrix.h @@ -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& items) ; bool loadList(std::list& items) ; + bool cleanUp() ; + // Dump info in terminal. // void debugDump() const ; void getListOfKnownKeys(std::vector& key_ids) const ; + bool getTrackingInfo(const RsGxsMessageId& id,RsPeerId& source_friend); private: // returns the friend id, possibly creating a new id. // @@ -81,8 +91,9 @@ class GRouterMatrix // List of events received and computed routing probabilities // - std::map > _routing_clues ; // received routing clues. Should be saved. - std::map > _time_combined_hits ; // hit matrix after time-convolution filter + std::map > _routing_clues ; // received routing clues. Should be saved. + std::map > _time_combined_hits ; // hit matrix after time-convolution filter + std::map _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 _friend_indices ; // index for each friend to lookup in the routing matrix Not saved. std::vector _reverse_friend_indices ;// SSLid corresponding to each friend index. Saved. - }; diff --git a/libretroshare/src/grouter/groutertypes.h b/libretroshare/src/grouter/groutertypes.h index 0a3900421..3c4897b0a 100644 --- a/libretroshare/src/grouter/groutertypes.h +++ b/libretroshare/src/grouter/groutertypes.h @@ -37,9 +37,10 @@ class RsGRouterSignedReceiptItem ; 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_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 = 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. diff --git a/libretroshare/src/grouter/p3grouter.cc b/libretroshare/src/grouter/p3grouter.cc index 421d2c97c..8ed41178c 100644 --- a/libretroshare/src/grouter/p3grouter.cc +++ b/libretroshare/src/grouter/p3grouter.cc @@ -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 @@ -1698,6 +1699,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 +1715,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) @@ -2154,6 +2165,13 @@ bool p3GRouter::getRoutingCacheInfo(std::vector& 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 +2232,8 @@ void p3GRouter::debugDump() grouter_debug() << " Routing matrix: " << std::endl; -// if(_debug_enabled) - // _routing_matrix.debugDump() ; + if(_debug_enabled) + _routing_matrix.debugDump() ; } diff --git a/libretroshare/src/grouter/p3grouter.h b/libretroshare/src/grouter/p3grouter.h index 2d8f744cd..98beac792 100644 --- a/libretroshare/src/grouter/p3grouter.h +++ b/libretroshare/src/grouter/p3grouter.h @@ -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& 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() ; @@ -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 diff --git a/libretroshare/src/gxs/gxssecurity.cc b/libretroshare/src/gxs/gxssecurity.cc index edd005fd9..1895993ee 100644 --- a/libretroshare/src/gxs/gxssecurity.cc +++ b/libretroshare/src/gxs/gxssecurity.cc @@ -551,7 +551,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); @@ -681,12 +681,25 @@ bool GxsSecurity::validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& s EVP_VerifyInit(mdctx, EVP_sha1()); EVP_VerifyUpdate(mdctx, allGrpData, allGrpDataLen); int signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey); + EVP_MD_CTX_destroy(mdctx); - delete[] allGrpData ; + if(signOk != 1) // try previous API. This is a hack to accept groups previously signed with old APIs. + { + EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); + + EVP_VerifyInit(mdctx, EVP_sha1()); + EVP_VerifyUpdate(mdctx, allGrpData, allGrpDataLen-4); // that means ommit the last + signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey); + EVP_MD_CTX_destroy(mdctx); + + if(signOk) + std::cerr << "(WW) GXS group with old API found. Signature still checks!" << std::endl; + } + + delete[] allGrpData ; /* clean up */ EVP_PKEY_free(signKey); - EVP_MD_CTX_destroy(mdctx); grpMeta.signSet = signSet; diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index 01af6efd3..fe53c03e4 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -49,19 +49,19 @@ #define MSG_INDEX_GRPID std::string("INDEX_MESSAGES_GRPID") // generic -#define KEY_NXS_DATA std::string("nxsData") -#define KEY_NXS_DATA_LEN std::string("nxsDataLen") -#define KEY_NXS_IDENTITY std::string("identity") -#define KEY_GRP_ID std::string("grpId") -#define KEY_ORIG_GRP_ID std::string("origGrpId") -#define KEY_PARENT_GRP_ID std::string("parentGrpId") -#define KEY_SIGN_SET std::string("signSet") -#define KEY_TIME_STAMP std::string("timeStamp") -#define KEY_NXS_FLAGS std::string("flags") -#define KEY_NXS_META std::string("meta") +#define KEY_NXS_DATA std::string("nxsData") +#define KEY_NXS_DATA_LEN std::string("nxsDataLen") +#define KEY_NXS_IDENTITY std::string("identity") +#define KEY_GRP_ID std::string("grpId") +#define KEY_ORIG_GRP_ID std::string("origGrpId") +#define KEY_PARENT_GRP_ID std::string("parentGrpId") +#define KEY_SIGN_SET std::string("signSet") +#define KEY_TIME_STAMP std::string("timeStamp") +#define KEY_NXS_FLAGS std::string("flags") +#define KEY_NXS_META std::string("meta") #define KEY_NXS_SERV_STRING std::string("serv_str") -#define KEY_NXS_HASH std::string("hash") -#define KEY_RECV_TS std::string("recv_time_stamp") +#define KEY_NXS_HASH std::string("hash") +#define KEY_RECV_TS std::string("recv_time_stamp") // remove later #define KEY_NXS_FILE_OLD std::string("nxsFile") @@ -94,8 +94,8 @@ #define KEY_MSG_NAME std::string("msgName") // msg local -#define KEY_MSG_STATUS std::string("msgStatus") -#define KEY_CHILD_TS std::string("childTs") +#define KEY_MSG_STATUS std::string("msgStatus") +#define KEY_CHILD_TS std::string("childTs") // database release columns #define KEY_DATABASE_RELEASE_ID std::string("id") @@ -129,22 +129,22 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d initialise(isNewDatabase); // for retrieving msg meta - mColMsgMeta_GrpId = addColumn(mMsgMetaColumns, KEY_GRP_ID); - mColMsgMeta_TimeStamp = addColumn(mMsgMetaColumns, KEY_TIME_STAMP); - mColMsgMeta_NxsFlags = addColumn(mMsgMetaColumns, KEY_NXS_FLAGS); - mColMsgMeta_SignSet = addColumn(mMsgMetaColumns, KEY_SIGN_SET); - mColMsgMeta_NxsIdentity = addColumn(mMsgMetaColumns, KEY_NXS_IDENTITY); - mColMsgMeta_NxsHash = addColumn(mMsgMetaColumns, KEY_NXS_HASH); - mColMsgMeta_MsgId = addColumn(mMsgMetaColumns, KEY_MSG_ID); - mColMsgMeta_OrigMsgId = addColumn(mMsgMetaColumns, KEY_ORIG_MSG_ID); - mColMsgMeta_MsgStatus = addColumn(mMsgMetaColumns, KEY_MSG_STATUS); - mColMsgMeta_ChildTs = addColumn(mMsgMetaColumns, KEY_CHILD_TS); - mColMsgMeta_MsgParentId = addColumn(mMsgMetaColumns, KEY_MSG_PARENT_ID); - mColMsgMeta_MsgThreadId = addColumn(mMsgMetaColumns, KEY_MSG_THREAD_ID); - mColMsgMeta_Name = addColumn(mMsgMetaColumns, KEY_MSG_NAME); + mColMsgMeta_GrpId = addColumn(mMsgMetaColumns, KEY_GRP_ID); + mColMsgMeta_TimeStamp = addColumn(mMsgMetaColumns, KEY_TIME_STAMP); + mColMsgMeta_NxsFlags = addColumn(mMsgMetaColumns, KEY_NXS_FLAGS); + mColMsgMeta_SignSet = addColumn(mMsgMetaColumns, KEY_SIGN_SET); + mColMsgMeta_NxsIdentity = addColumn(mMsgMetaColumns, KEY_NXS_IDENTITY); + mColMsgMeta_NxsHash = addColumn(mMsgMetaColumns, KEY_NXS_HASH); + mColMsgMeta_MsgId = addColumn(mMsgMetaColumns, KEY_MSG_ID); + mColMsgMeta_OrigMsgId = addColumn(mMsgMetaColumns, KEY_ORIG_MSG_ID); + mColMsgMeta_MsgStatus = addColumn(mMsgMetaColumns, KEY_MSG_STATUS); + mColMsgMeta_ChildTs = addColumn(mMsgMetaColumns, KEY_CHILD_TS); + mColMsgMeta_MsgParentId = addColumn(mMsgMetaColumns, KEY_MSG_PARENT_ID); + mColMsgMeta_MsgThreadId = addColumn(mMsgMetaColumns, KEY_MSG_THREAD_ID); + mColMsgMeta_Name = addColumn(mMsgMetaColumns, KEY_MSG_NAME); mColMsgMeta_NxsServString = addColumn(mMsgMetaColumns, KEY_NXS_SERV_STRING); - mColMsgMeta_RecvTs = addColumn(mMsgMetaColumns, KEY_RECV_TS); - mColMsgMeta_NxsDataLen = addColumn(mMsgMetaColumns, KEY_NXS_DATA_LEN); + mColMsgMeta_RecvTs = addColumn(mMsgMetaColumns, KEY_RECV_TS); + mColMsgMeta_NxsDataLen = addColumn(mMsgMetaColumns, KEY_NXS_DATA_LEN); // for retrieving actual data mColMsg_GrpId = addColumn(mMsgColumns, KEY_GRP_ID); @@ -152,38 +152,48 @@ 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); - mColGrpMeta_NxsFlags = addColumn(mGrpMetaColumns, KEY_NXS_FLAGS); + mColGrpMeta_GrpId = addColumn(mGrpMetaColumns, KEY_GRP_ID); + mColGrpMeta_TimeStamp = addColumn(mGrpMetaColumns, KEY_TIME_STAMP); + mColGrpMeta_NxsFlags = addColumn(mGrpMetaColumns, KEY_NXS_FLAGS); // mColGrpMeta_SignSet = addColumn(mGrpMetaColumns, KEY_SIGN_SET); mColGrpMeta_NxsIdentity = addColumn(mGrpMetaColumns, KEY_NXS_IDENTITY); - mColGrpMeta_NxsHash = addColumn(mGrpMetaColumns, KEY_NXS_HASH); - mColGrpMeta_KeySet = addColumn(mGrpMetaColumns, KEY_KEY_SET); - mColGrpMeta_SubscrFlag = addColumn(mGrpMetaColumns, KEY_GRP_SUBCR_FLAG); - mColGrpMeta_Pop = addColumn(mGrpMetaColumns, KEY_GRP_POP); - mColGrpMeta_MsgCount = addColumn(mGrpMetaColumns, KEY_MSG_COUNT); - mColGrpMeta_Status = addColumn(mGrpMetaColumns, KEY_GRP_STATUS); - mColGrpMeta_Name = addColumn(mGrpMetaColumns, KEY_GRP_NAME); - mColGrpMeta_LastPost = addColumn(mGrpMetaColumns, KEY_GRP_LAST_POST); - mColGrpMeta_OrigGrpId = addColumn(mGrpMetaColumns, KEY_ORIG_GRP_ID); - mColGrpMeta_ServString = addColumn(mGrpMetaColumns, KEY_NXS_SERV_STRING); - mColGrpMeta_SignFlags = addColumn(mGrpMetaColumns, KEY_GRP_SIGN_FLAGS); - mColGrpMeta_CircleId = addColumn(mGrpMetaColumns, KEY_GRP_CIRCLE_ID); - mColGrpMeta_CircleType = addColumn(mGrpMetaColumns, KEY_GRP_CIRCLE_TYPE); + mColGrpMeta_NxsHash = addColumn(mGrpMetaColumns, KEY_NXS_HASH); + mColGrpMeta_KeySet = addColumn(mGrpMetaColumns, KEY_KEY_SET); + mColGrpMeta_SubscrFlag = addColumn(mGrpMetaColumns, KEY_GRP_SUBCR_FLAG); + mColGrpMeta_Pop = addColumn(mGrpMetaColumns, KEY_GRP_POP); + mColGrpMeta_MsgCount = addColumn(mGrpMetaColumns, KEY_MSG_COUNT); + mColGrpMeta_Status = addColumn(mGrpMetaColumns, KEY_GRP_STATUS); + mColGrpMeta_Name = addColumn(mGrpMetaColumns, KEY_GRP_NAME); + mColGrpMeta_LastPost = addColumn(mGrpMetaColumns, KEY_GRP_LAST_POST); + mColGrpMeta_OrigGrpId = addColumn(mGrpMetaColumns, KEY_ORIG_GRP_ID); + mColGrpMeta_ServString = addColumn(mGrpMetaColumns, KEY_NXS_SERV_STRING); + mColGrpMeta_SignFlags = addColumn(mGrpMetaColumns, KEY_GRP_SIGN_FLAGS); + mColGrpMeta_CircleId = addColumn(mGrpMetaColumns, KEY_GRP_CIRCLE_ID); + mColGrpMeta_CircleType = addColumn(mGrpMetaColumns, KEY_GRP_CIRCLE_TYPE); mColGrpMeta_InternCircle = addColumn(mGrpMetaColumns, KEY_GRP_INTERNAL_CIRCLE); - mColGrpMeta_Originator = addColumn(mGrpMetaColumns, KEY_GRP_ORIGINATOR); + mColGrpMeta_Originator = addColumn(mGrpMetaColumns, KEY_GRP_ORIGINATOR); mColGrpMeta_AuthenFlags = addColumn(mGrpMetaColumns, KEY_GRP_AUTHEN_FLAGS); mColGrpMeta_ParentGrpId = addColumn(mGrpMetaColumns, KEY_PARENT_GRP_ID); - mColGrpMeta_RecvTs = addColumn(mGrpMetaColumns, KEY_RECV_TS); - mColGrpMeta_RepCutoff = addColumn(mGrpMetaColumns, KEY_GRP_REP_CUTOFF); - mColGrpMeta_NxsDataLen = addColumn(mGrpMetaColumns, KEY_NXS_DATA_LEN); + mColGrpMeta_RecvTs = addColumn(mGrpMetaColumns, KEY_RECV_TS); + mColGrpMeta_RepCutoff = addColumn(mGrpMetaColumns, KEY_GRP_REP_CUTOFF); + mColGrpMeta_NxsDataLen = addColumn(mGrpMetaColumns, KEY_NXS_DATA_LEN); // for retrieving actual grp data mColGrp_GrpId = addColumn(mGrpColumns, KEY_GRP_ID); 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 &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 grps; - locked_retrieveGroups(c, grps); + locked_retrieveGroups(c, grps, withMeta ? mColGrp_WithMetaOffset : 0); std::vector::iterator vit = grps.begin(); #ifdef RS_DATA_SERVICE_DEBUG_TIME @@ -1051,12 +1060,12 @@ int RsDataService::retrieveNxsGrps(std::map &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 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 &grp, bool std::cerr << "RsDataService::retrieveNxsGrps() " << mDbName << ", Requests: " << requestedGroups << ", Results: " << resultCount << ", Time: " << timer.duration() << std::endl; #endif - if(withMeta && !grp.empty()) - { - std::map metaMap; - std::map::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& grps){ +void RsDataService::locked_retrieveGroups(RetroCursor* c, std::vector& grps, int metaOffset){ if(c){ bool valid = c->moveToFirst(); @@ -1127,6 +1108,9 @@ void RsDataService::locked_retrieveGroups(RetroCursor* c, std::vector // 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 msgIds; - - std::vector::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& msgV = msg[grpId]; - std::vector::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& msgMetaV = metaResult[grpId]; - std::vector::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& msgMetaV = metaResult[grpId]; - std::vector::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 &msgs) +void RsDataService::locked_retrieveMessages(RetroCursor *c, std::vector &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,14 +1244,14 @@ int RsDataService::retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaRes if (c) { locked_retrieveMsgMeta(c, metaSet); - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - resultCount += c->getResultCount(); -#endif } } } +#ifdef RS_DATA_SERVICE_DEBUG_TIME + resultCount += metaSet.size(); +#endif + msgMeta[grpId] = metaSet; } @@ -1361,7 +1269,7 @@ void RsDataService::locked_retrieveMsgMeta(RetroCursor *c, std::vectormoveToFirst(); 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::mapmGroupId] = g; @@ -1431,7 +1339,7 @@ int RsDataService::retrieveGxsGrpMetaData(std::map& msgs); + void locked_retrieveMessages(RetroCursor* c, std::vector& 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& grps); + void locked_retrieveGroups(RetroCursor* c, std::vector& 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 mMsgColumns; std::list mMsgMetaColumns; + std::list mMsgColumnsWithMeta; std::list mMsgIdColumn; std::list mGrpColumns; std::list mGrpMetaColumns; + std::list mGrpColumnsWithMeta; std::list 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; diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index e7ae496f9..f803ae589 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -33,6 +33,7 @@ #include "retroshare/rsgxsflags.h" #include "retroshare/rsgxscircles.h" #include "retroshare/rsgrouter.h" +#include "retroshare/rspeers.h" #include "rsgixs.h" #include "rsgxsutil.h" #include "rsserver/p3face.h" @@ -49,6 +50,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 @@ -416,7 +425,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 +471,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) @@ -494,25 +505,29 @@ int RsGenExchange::createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBin id_ret = SIGN_FAIL; } - signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY] = sign; + signSet.keySignSet[INDEX_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 +547,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 +585,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 +632,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()"; @@ -653,25 +676,29 @@ int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinar id_ret = SIGN_FAIL; } - signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY] = sign; + signSet.keySignSet[INDEX_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 +790,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 +823,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& keys = grpKeySet.keys; std::map::iterator mit = keys.begin(); @@ -849,31 +880,67 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecu bool haveKey = mGixs->haveKey(metaData.mAuthorId); if(haveKey) - { + { - RsTlvSecurityKey authorKey; - bool auth_key_fetched = mGixs->getKey(metaData.mAuthorId, authorKey) ; + RsTlvSecurityKey authorKey; + bool auth_key_fetched = mGixs->getKey(metaData.mAuthorId, authorKey) ; - if (auth_key_fetched) + if (auth_key_fetched) + { + RsTlvKeySignature sign = metaData.signSet.keySignSet[INDEX_AUTHEN_IDENTITY]; + idValidate &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey); + mGixs->timeStampKey(metaData.mAuthorId) ; + } + else + { + std::cerr << "RsGenExchange::validateMsg()"; + std::cerr << " ERROR Cannot Retrieve AUTHOR KEY for Message Validation"; + std::cerr << std::endl; + idValidate = false; + } + + 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.mPgpLinked) ? (RsReputations::REPUTATION_THRESHOLD_ANTI_SPAM): (RsReputations::REPUTATION_THRESHOLD_DEFAULT) ; + + if(details.mReputation.mOverallReputationScore < reputation_threshold) { - - RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY]; - idValidate &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey); - mGixs->timeStampKey(metaData.mAuthorId) ; +#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()"; - std::cerr << " ERROR Cannot Retrieve AUTHOR KEY for Message Validation"; - std::cerr << std::endl; - idValidate = false; - } + std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", accepted. Reputation score (" << details.mReputation.mOverallReputationScore <<") is above accepted threshold (" << reputation_threshold << ")" << std::endl; +#endif + } - }else + } + } + else { std::list 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 +957,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 @@ -911,8 +982,10 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp) if ((!metaData.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) @@ -930,7 +1003,7 @@ 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); mGixs->timeStampKey(metaData.mAuthorId) ; @@ -1135,7 +1208,6 @@ bool RsGenExchange::getGroupMeta(const uint32_t &token, std::list& metaV = mit->second; - msgInfo[mit->first] = std::vector(); std::vector& msgInfoV = msgInfo[mit->first]; std::vector::iterator vit = metaV.begin(); @@ -1181,7 +1252,6 @@ bool RsGenExchange::getMsgRelatedMeta(const uint32_t &token, GxsMsgRelatedMetaMa { std::vector& metaV = mit->second; - msgMeta[mit->first] = std::vector(); std::vector& msgInfoV = msgMeta[mit->first]; std::vector::iterator vit = metaV.begin(); @@ -1265,14 +1335,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 gxsMsgItems; const RsGxsGroupId& grpId = mit->first; + std::vector& gxsMsgItems = msgItems[grpId]; std::vector& nxsMsgsV = mit->second; std::vector::iterator vit = nxsMsgsV.begin(); for(; vit != nxsMsgsV.end(); ++vit) @@ -1305,7 +1375,6 @@ bool RsGenExchange::getMsgData(const uint32_t &token, GxsMsgDataMap &msgItems) } delete msg; } - msgItems[grpId] = gxsMsgItems; } } return ok; @@ -1317,17 +1386,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 gxsMsgItems; const RsGxsGrpMsgIdPair& msgId = mit->first; + std::vector &gxsMsgItems = msgItems[msgId]; std::vector& nxsMsgsV = mit->second; - std::vector::iterator vit - = nxsMsgsV.begin(); + std::vector::iterator vit = nxsMsgsV.begin(); for(; vit != nxsMsgsV.end(); ++vit) { RsNxsMsg*& msg = *vit; @@ -1360,15 +1427,11 @@ bool RsGenExchange::getMsgRelatedData(const uint32_t &token, GxsMsgRelatedDataMa delete msg; } - msgItems[msgId] = gxsMsgItems; } } return ok; } - - - RsTokenService* RsGenExchange::getTokenService() { return mDataAccess; @@ -1763,8 +1826,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 +2002,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); @@ -2070,13 +2139,18 @@ void RsGenExchange::processGroupUpdatePublish() void RsGenExchange::processRoutingClues() { - RS_STACK_MUTEX(mGenMtx) ; + RS_STACK_MUTEX(mGenMtx) ; for(std::map >::const_iterator it = mRoutingClues.begin();it!=mRoutingClues.end();++it) for(std::set::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 >::const_iterator it = mTrackingClues.begin();it!=mTrackingClues.end();++it) + rsGRouter->addTrackingInfo((*it).first,(*it).second) ; + + mTrackingClues.clear() ; } void RsGenExchange::processGroupDelete() { @@ -2291,6 +2365,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) @@ -2443,201 +2523,208 @@ void RsGenExchange::computeHash(const RsTlvBinaryData& data, RsFileHash& hash) void RsGenExchange::processRecvdMessages() { - RS_STACK_MUTEX(mGenMtx) ; + RS_STACK_MUTEX(mGenMtx) ; #ifdef GEN_EXCH_DEBUG - if(!mMsgPendingValidate.empty()) - std::cerr << "processing received messages" << std::endl; + if(!mMsgPendingValidate.empty()) + std::cerr << "processing received messages" << std::endl; #endif - NxsMsgPendingVect::iterator pend_it = mMsgPendingValidate.begin(); + NxsMsgPendingVect::iterator pend_it = mMsgPendingValidate.begin(); #ifdef GEN_EXCH_DEBUG - if(!mMsgPendingValidate.empty()) - std::cerr << " pending validation" << std::endl; + if(!mMsgPendingValidate.empty()) + std::cerr << " pending validation" << std::endl; #endif - for(; pend_it != mMsgPendingValidate.end();) - { - GxsPendingItem& gpsi = *pend_it; + for(; pend_it != mMsgPendingValidate.end();) + { + GxsPendingItem& gpsi = *pend_it; #ifdef GEN_EXCH_DEBUG - std::cerr << " grp=" << gpsi.mId.first << ", msg=" << gpsi.mId.second << ", attempts=" << gpsi.mAttempts ; + std::cerr << " grp=" << gpsi.mId.first << ", msg=" << gpsi.mId.second << ", attempts=" << gpsi.mAttempts ; #endif - if(gpsi.mAttempts == VALIDATE_MAX_ATTEMPTS) - { + if(gpsi.mAttempts == VALIDATE_MAX_ATTEMPTS) + { #ifdef GEN_EXCH_DEBUG std::cerr << " = max! deleting." << std::endl; #endif - delete gpsi.mItem; - pend_it = mMsgPendingValidate.erase(pend_it); - } - else - { + delete gpsi.mItem; + pend_it = mMsgPendingValidate.erase(pend_it); + } + else + { #ifdef GEN_EXCH_DEBUG std::cerr << " movign to recvd." << std::endl; #endif - mReceivedMsgs.push_back(gpsi.mItem); - ++pend_it; - } - } + mReceivedMsgs.push_back(gpsi.mItem); + ++pend_it; + } + } - if(mReceivedMsgs.empty()) - return; + if(mReceivedMsgs.empty()) + return; - std::vector::iterator vit = mReceivedMsgs.begin(); - GxsMsgReq msgIds; - std::map msgs; + std::vector::iterator vit = mReceivedMsgs.begin(); + GxsMsgReq msgIds; + std::map msgs; - std::map grpMetas; + std::map grpMetas; - // coalesce group meta retrieval for performance - for(; vit != mReceivedMsgs.end(); ++vit) - { - RsNxsMsg* msg = *vit; - grpMetas.insert(std::make_pair(msg->grpId, (RsGxsGrpMetaData*)NULL)); - } + // coalesce group meta retrieval for performance + for(; vit != mReceivedMsgs.end(); ++vit) + { + RsNxsMsg* msg = *vit; + grpMetas.insert(std::make_pair(msg->grpId, (RsGxsGrpMetaData*)NULL)); + } - mDataStore->retrieveGxsGrpMetaData(grpMetas); + mDataStore->retrieveGxsGrpMetaData(grpMetas); #ifdef GEN_EXCH_DEBUG - std::cerr << " updating received messages:" << std::endl; + std::cerr << " updating received messages:" << std::endl; #endif - for(vit = mReceivedMsgs.begin(); vit != mReceivedMsgs.end(); ++vit) - { - RsNxsMsg* msg = *vit; - RsGxsMsgMetaData* meta = new RsGxsMsgMetaData(); + for(vit = mReceivedMsgs.begin(); vit != mReceivedMsgs.end(); ++vit) + { + RsNxsMsg* msg = *vit; + RsGxsMsgMetaData* meta = new RsGxsMsgMetaData(); - bool ok = false; + bool ok = false; - if(msg->meta.bin_len != 0) - ok = meta->deserialise(msg->meta.bin_data, &(msg->meta.bin_len)); + if(msg->meta.bin_len != 0) + ok = meta->deserialise(msg->meta.bin_data, &(msg->meta.bin_len)); - msg->metaData = meta; + msg->metaData = meta; #ifdef GEN_EXCH_DEBUG - std::cerr << " deserialised info: grp id=" << meta->mGroupId << ", msg id=" << meta->mMsgId ; + std::cerr << " deserialised info: grp id=" << meta->mGroupId << ", msg id=" << meta->mMsgId ; #endif - uint8_t validateReturn = VALIDATE_FAIL; + uint8_t validateReturn = VALIDATE_FAIL; - if(ok) - { - std::map::iterator mit = grpMetas.find(msg->grpId); + if(ok) + { + std::map::iterator mit = grpMetas.find(msg->grpId); #ifdef GEN_EXCH_DEBUG - std::cerr << " msg info : grp id=" << msg->grpId << ", msg id=" << msg->msgId << std::endl; + 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); -#ifdef GEN_EXCH_DEBUG - std::cerr << " message validation result: " << validateReturn << std::endl; -#endif - } - - if(validateReturn == VALIDATE_SUCCESS) - { - meta->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; - msgs.insert(std::make_pair(msg, meta)); - - std::vector &msgv = msgIds[msg->grpId]; - if (std::find(msgv.begin(), msgv.end(), msg->msgId) == msgv.end()) - { - msgv.push_back(msg->msgId); - } - - NxsMsgPendingVect::iterator validated_entry = std::find(mMsgPendingValidate.begin(), mMsgPendingValidate.end(), - getMsgIdPair(*msg)); - - if(validated_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(validated_entry); - - computeHash(msg->msg, meta->mHash); - meta->recvTS = time(NULL); -#ifdef GEN_EXCH_DEBUG - std::cerr << " new status flags: " << meta->mMsgStatus << std::endl; - std::cerr << " computed hash: " << meta->mHash << std::endl; - std::cerr << "Message received. Identity=" << msg->metaData->mAuthorId << ", from peer " << msg->PeerId() << std::endl; -#endif - - if(!msg->metaData->mAuthorId.isNull()) - mRoutingClues[msg->metaData->mAuthorId].insert(msg->PeerId()) ; - } - } - else - { -#ifdef GEN_EXCH_DEBUG - std::cerr << " deserialisation failed!" <second; + validateReturn = validateMsg(msg, grpMeta->mGroupFlags, grpMeta->mSignFlags, grpMeta->keys); #ifdef GEN_EXCH_DEBUG - std::cerr << "failed to deserialise incoming meta, msgId: " - << "msg->grpId: " << msg->grpId << ", msgId: " << msg->msgId << 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 + } + + if(validateReturn == VALIDATE_SUCCESS) + { + meta->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; + msgs.insert(std::make_pair(msg, meta)); + + std::vector &msgv = msgIds[msg->grpId]; + if (std::find(msgv.begin(), msgv.end(), msg->msgId) == msgv.end()) + { + msgv.push_back(msg->msgId); + } + + NxsMsgPendingVect::iterator validated_entry = std::find(mMsgPendingValidate.begin(), mMsgPendingValidate.end(), + getMsgIdPair(*msg)); + + if(validated_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(validated_entry); + + computeHash(msg->msg, meta->mHash); + meta->recvTS = time(NULL); +#ifdef GEN_EXCH_DEBUG + std::cerr << " new status flags: " << meta->mMsgStatus << std::endl; + std::cerr << " computed hash: " << meta->mHash << std::endl; + std::cerr << "Message received. Identity=" << msg->metaData->mAuthorId << ", from peer " << msg->PeerId() << std::endl; #endif - NxsMsgPendingVect::iterator failed_entry = std::find(mMsgPendingValidate.begin(), mMsgPendingValidate.end(), - getMsgIdPair(*msg)); + if(!msg->metaData->mAuthorId.isNull()) + mRoutingClues[msg->metaData->mAuthorId].insert(msg->PeerId()) ; - if(failed_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(failed_entry); + if(grpMeta->mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) + mTrackingClues.push_back(std::make_pair(msg->msgId,msg->PeerId())) ; + } + } + else + { +#ifdef GEN_EXCH_DEBUG + std::cerr << " deserialisation failed!" <grpId: " << msg->grpId << ", msgId: " << msg->msgId << std::endl; +#endif + + NxsMsgPendingVect::iterator failed_entry = std::find(mMsgPendingValidate.begin(), mMsgPendingValidate.end(), + getMsgIdPair(*msg)); + + if(failed_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(failed_entry); delete msg; - } - else if(validateReturn == VALIDATE_FAIL_TRY_LATER) - { + } + else if(validateReturn == VALIDATE_FAIL_TRY_LATER) + { #ifdef GEN_EXCH_DEBUG - std::cerr << "failed to validate msg, trying again: " - << "msg->grpId: " << msg->grpId << ", msgId: " << msg->msgId << std::endl; + std::cerr << "failed to validate msg, trying again: " + << "msg->grpId: " << msg->grpId << ", msgId: " << msg->msgId << std::endl; #endif - RsGxsGrpMsgIdPair id; - id.first = msg->grpId; - id.second = msg->msgId; + RsGxsGrpMsgIdPair id; + id.first = msg->grpId; + id.second = msg->msgId; - // first check you haven't made too many attempts + // first check you haven't made too many attempts - NxsMsgPendingVect::iterator vit = std::find( - mMsgPendingValidate.begin(), mMsgPendingValidate.end(), id); + NxsMsgPendingVect::iterator vit = std::find( + mMsgPendingValidate.begin(), mMsgPendingValidate.end(), id); - if(vit == mMsgPendingValidate.end()) - { - GxsPendingItem item(msg, id); - mMsgPendingValidate.push_back(item); - }else - { + if(vit == mMsgPendingValidate.end()) + { + GxsPendingItem item(msg, id); + mMsgPendingValidate.push_back(item); + }else + { vit->mAttempts++; - } - } - } + } + } + } - // clean up resources from group meta retrieval - freeAndClearContainerResource, - RsGxsGrpMetaData*>(grpMetas); + // clean up resources from group meta retrieval + freeAndClearContainerResource, + RsGxsGrpMetaData*>(grpMetas); - if(!msgIds.empty()) - { + if(!msgIds.empty()) + { #ifdef GEN_EXCH_DEBUG - std::cerr << " removing existing and old messages from incoming list." << std::endl; + std::cerr << " removing existing and old messages from incoming list." << std::endl; #endif - removeDeleteExistingMessages(msgs, msgIds); + removeDeleteExistingMessages(msgs, msgIds); #ifdef GEN_EXCH_DEBUG - std::cerr << " storing remaining messages" << std::endl; + std::cerr << " storing remaining messages" << std::endl; #endif - mDataStore->storeMessage(msgs); + mDataStore->storeMessage(msgs); - RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_RECEIVE, false); - c->msgChangeMap = msgIds; - mNotifications.push_back(c); - } + RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_RECEIVE, false); + c->msgChangeMap = msgIds; + mNotifications.push_back(c); + } - mReceivedMsgs.clear(); + mReceivedMsgs.clear(); } void RsGenExchange::processRecvdGroups() @@ -2710,8 +2797,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,8 +2806,7 @@ 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) @@ -2737,6 +2822,7 @@ void RsGenExchange::processRecvdGroups() } else { + std::cerr << "(EE) deserialise error in group meta data" << std::endl; delete grp; delete meta; erase = true; @@ -2821,7 +2907,7 @@ void RsGenExchange::performUpdateValidation() bool RsGenExchange::updateValid(RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp) const { std::map& signSet = newGrp.metaData->signSet.keySignSet; - std::map::iterator mit = signSet.find(GXS_SERV::FLAG_AUTHEN_ADMIN); + std::map::iterator mit = signSet.find(INDEX_AUTHEN_ADMIN); if(mit == signSet.end()) { @@ -2900,7 +2986,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) // diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index ba59dcaac..1462b0285 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -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 mGroupDeletePublish; std::map > mRoutingClues ; - + std::list > mTrackingClues ; }; #endif // RSGENEXCHANGE_H diff --git a/libretroshare/src/gxs/rsgixs.h b/libretroshare/src/gxs/rsgixs.h index 19590baa9..cf13a77d3 100644 --- a/libretroshare/src/gxs/rsgixs.h +++ b/libretroshare/src/gxs/rsgixs.h @@ -166,6 +166,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 #ifdef SUSPENDED #endif diff --git a/libretroshare/src/gxs/rsgxsdata.cc b/libretroshare/src/gxs/rsgxsdata.cc index 36ae1f155..927c73dda 100644 --- a/libretroshare/src/gxs/rsgxsdata.cc +++ b/libretroshare/src/gxs/rsgxsdata.cc @@ -28,6 +28,11 @@ #include "serialiser/rsbaseserial.h" #include "serialiser/rstlvbase.h" +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_0001 = 0x0000 ; // current API + RsGxsGrpMetaData::RsGxsGrpMetaData() { clear(); @@ -46,10 +51,11 @@ uint32_t RsGxsGrpMetaData::serial_size() s += GetTlvStringSize(mServiceString); s += signSet.TlvSize(); s += keys.TlvSize(); - s += 4; // for mCircleType + s += 4; // for mCircleType s += mCircleId.serial_size(); - s += 4; // mAuthenFlag - s += mParentGrpId.serial_size(); + s += 4; // mAuthenFlag + s += mParentGrpId.serial_size(); // mParentGroupId + s += 4; // mSignFlag return s; } @@ -104,7 +110,7 @@ bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize) bool ok = true; - ok &= setRsItemHeader(data, tlvsize, 0, tlvsize); + ok &= setRsItemHeader(data, tlvsize, RS_GXS_GRP_META_DATA_VERSION_ID_0002, tlvsize); #ifdef GXS_DEBUG std::cerr << "RsGxsGrpMetaData serialise()" << std::endl; @@ -130,6 +136,7 @@ bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize) ok &= signSet.SetTlv(data, tlvsize, &offset); ok &= keys.SetTlv(data, tlvsize, &offset); + ok &= setRawUInt32(data, tlvsize, &offset, mSignFlags); // new in API v2. Was previously missing. Kept in the end for backward compatibility return ok; } @@ -154,12 +161,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 +228,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 +265,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_0001, tlvsize); #ifdef GXS_DEBUG std::cerr << "RsGxsGrpMetaData serialise()" << std::endl; diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h index 9829b8bd6..f80dbb862 100644 --- a/libretroshare/src/gxs/rsgxsdata.h +++ b/libretroshare/src/gxs/rsgxsdata.h @@ -52,7 +52,7 @@ public: 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 +123,6 @@ public: uint32_t recvTS; RsFileHash mHash; bool validated; - }; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index e1c922d61..c9033c9c0 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -448,7 +448,7 @@ bool RsGxsDataAccess::getGroupData(const uint32_t& token, std::list& 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::listmGroupIdResult; + 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& 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; } diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 8806b4e1c..63224a206 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -30,6 +30,7 @@ #include "rsgxsnetservice.h" #include "retroshare/rsconfig.h" +#include "retroshare/rsreputations.h" #include "retroshare/rsgxsflags.h" #include "retroshare/rsgxscircles.h" #include "pgp/pgpauxutils.h" @@ -1996,7 +1997,15 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr) std::cerr << ", no group meta found. Givign up." << std::endl; continue; } - + + if(rsReputations->isIdentityBanned(syncItem->authorId)) + { +#ifdef NXS_NET_DEBUG + std::cerr << ", Identity " << syncItem->authorId << " is banned. Not requesting message!" << std::endl; +#endif + continue ; + } + if(mReputations->haveReputation(syncItem->authorId) || noAuthor) { GixsReputation rep; @@ -2009,7 +2018,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr) // if author is required for this message, it will simply get dropped // at genexchange side of things - if(rep.score > (int)grpMeta->mReputationCutOff || noAuthor) + if(rep.score >= (int)grpMeta->mReputationCutOff || noAuthor) { #ifdef NXS_NET_DEBUG std::cerr << ", passed! Adding message to req list." << std::endl; @@ -2210,7 +2219,15 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr) haveItem = true; latestVersion = grpSyncItem->publishTs > metaIter->second->mPublishTs; } - + + if(!grpSyncItem->authorId.isNull() && rsReputations->isIdentityBanned(grpSyncItem->authorId)) + { +#ifdef NXS_NET_DEBUG + std::cerr << " Identity " << grpSyncItem->authorId << " is banned. Not syncing group." << std::endl; +#endif + continue ; + } + if( (mGrpAutoSync && !haveItem) || latestVersion) { // determine if you need to check reputation @@ -2228,10 +2245,14 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr) if(rep.score >= GIXS_CUT_OFF) { addGroupItemToList(tr, grpId, transN, reqList); +#ifdef NXS_NET_DEBUG std::cerr << " reputation cut off: limit=" << GIXS_CUT_OFF << " value=" << rep.score << ": allowed." << std::endl; +#endif } +#ifdef NXS_NET_DEBUG else std::cerr << " reputation cut off: limit=" << GIXS_CUT_OFF << " value=" << rep.score << ": you shall not pass." << std::endl; +#endif } else { diff --git a/libretroshare/src/gxs/rsgxsnetutils.cc b/libretroshare/src/gxs/rsgxsnetutils.cc index eb6dfb3d2..76dd8a68d 100644 --- a/libretroshare/src/gxs/rsgxsnetutils.cc +++ b/libretroshare/src/gxs/rsgxsnetutils.cc @@ -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++; diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 646c65778..e9ac68bf3 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -1,871 +1,861 @@ -!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri") - -TEMPLATE = lib -CONFIG += staticlib bitdht -CONFIG += create_prl -CONFIG -= qt -TARGET = retroshare -TARGET_PRL = libretroshare - - -#GXS Stuff. -# This should be disabled for releases until further notice. -CONFIG += gxs - -#CONFIG += dsdv - -profiling { - QMAKE_CXXFLAGS -= -fomit-frame-pointer - QMAKE_CXXFLAGS *= -pg -g -fno-omit-frame-pointer -} - -# treat warnings as error for better removing -#QMAKE_CFLAGS += -Werror -#QMAKE_CXXFLAGS += -Werror - -debug { -# DEFINES *= DEBUG -# DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG -# DEFINES *= CONTROL_DEBUG FT_DEBUG DEBUG_FTCHUNK P3TURTLE_DEBUG -# DEFINES *= P3TURTLE_DEBUG -# DEFINES *= NET_DEBUG -# DEFINES *= DISTRIB_DEBUG -# DEFINES *= P3TURTLE_DEBUG FT_DEBUG DEBUG_FTCHUNK MPLEX_DEBUG -# DEFINES *= STATUS_DEBUG SERV_DEBUG RSSERIAL_DEBUG #CONN_DEBUG - - QMAKE_CXXFLAGS -= -O2 -fomit-frame-pointer - QMAKE_CXXFLAGS *= -g -fno-omit-frame-pointer -} - -dsdv { -DEFINES *= SERVICES_DSDV -HEADERS += services/p3dsdv.h \ - serialiser/rstlvdsdv.h \ - serialiser/rsdsdvitems.h \ - retroshare/rsdsdv.h - -SOURCES *= serialiser/rstlvdsdv.cc \ - serialiser/rsdsdvitems.cc \ - services/p3dsdv.cc -} -bitdht { - -HEADERS += dht/p3bitdht.h \ - dht/connectstatebox.h \ - dht/stunaddrassist.h - -SOURCES += dht/p3bitdht.cc \ - dht/p3bitdht_interface.cc \ - dht/p3bitdht_peers.cc \ - dht/p3bitdht_peernet.cc \ - dht/p3bitdht_relay.cc \ - dht/connectstatebox.cc - -HEADERS += tcponudp/udppeer.h \ - tcponudp/bio_tou.h \ - tcponudp/tcppacket.h \ - tcponudp/tcpstream.h \ - tcponudp/tou.h \ - tcponudp/udpstunner.h \ - tcponudp/udprelay.h \ - -SOURCES += tcponudp/udppeer.cc \ - tcponudp/tcppacket.cc \ - tcponudp/tcpstream.cc \ - tcponudp/tou.cc \ - tcponudp/bss_tou.c \ - tcponudp/udpstunner.cc \ - tcponudp/udprelay.cc \ - - - 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 -} - - - - -PUBLIC_HEADERS = retroshare/rsdisc.h \ - retroshare/rsexpr.h \ - retroshare/rsfiles.h \ - retroshare/rshistory.h \ - retroshare/rsids.h \ - retroshare/rsiface.h \ - retroshare/rsinit.h \ - retroshare/rsplugin.h \ - retroshare/rsloginhandler.h \ - retroshare/rsmsgs.h \ - retroshare/rsnotify.h \ - retroshare/rspeers.h \ - retroshare/rsrank.h \ - retroshare/rsstatus.h \ - retroshare/rsturtle.h \ - retroshare/rsbanlist.h \ - retroshare/rstypes.h \ - retroshare/rsdht.h \ - retroshare/rsrtt.h \ - retroshare/rsconfig.h \ - retroshare/rsversion.h \ - retroshare/rsservicecontrol.h \ - - -HEADERS += plugins/pluginmanager.h \ - plugins/dlfcn_win32.h \ - serialiser/rspluginitems.h \ - util/rsinitedptr.h - -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") - - 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 - } else { - SQLCIPHER_OK = $$system(pkg-config --exists sqlcipher && echo yes) - isEmpty(SQLCIPHER_OK) { - # We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database. - exists(../../../lib/sqlcipher/.libs/libsqlcipher.a) { - LIBS += ../../../lib/sqlcipher/.libs/libsqlcipher.a - DEPENDPATH += ../../../lib/ - INCLUDEPATH += ../../../lib/ - } else { - 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 { - 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) { - # Normal libupnp - } else { - # Patched libupnp or new unreleased version - DEFINES *= PATCHED_LIBUPNP - } - - 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 -} - -unix { - DEFINES *= LIB_DIR=\"\\\"$${LIB_DIR}\\\"\" - DEFINES *= DATA_DIR=\"\\\"$${DATA_DIR}\\\"\" - - ## where to put the librarys interface - #include_rsiface.path = "$${INC_DIR}" - #include_rsiface.files = $$PUBLIC_HEADERS - #INSTALLS += include_rsiface - - ## where to put the shared library itself - #target.path = "$$LIB_DIR" - #INSTALLS *= target -} - -linux-g++ { - OBJECTS_DIR = temp/linux-g++/obj -} - -linux-g++-64 { - OBJECTS_DIR = temp/linux-g++-64/obj -} - -version_detail_bash_script { - linux-* { - QMAKE_EXTRA_TARGETS += write_version_detail - PRE_TARGETDEPS = write_version_detail - write_version_detail.commands = ./version_detail.sh - } - win32 { - QMAKE_EXTRA_TARGETS += write_version_detail - PRE_TARGETDEPS = write_version_detail - write_version_detail.commands = $$PWD/version_detail.bat - } -} - -#################### Cross compilation for windows under Linux #################### - -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++ - QMAKE_LIB = i586-mingw32msvc-ar - QMAKE_AR = i586-mingw32msvc-ar - DEFINES *= STATICLIB WIN32 - - CONFIG += upnp_miniupnpc - - SSL_DIR=../../../../openssl - UPNPC_DIR = ../../../../miniupnpc-1.3 - GPG_ERROR_DIR = ../../../../libgpg-error-1.7 - GPGME_DIR = ../../../../gpgme-1.1.8 - - INCLUDEPATH *= /usr/i586-mingw32msvc/include ${HOME}/.wine/drive_c/pthreads/include/ -} -################################# Windows ########################################## - -win32 { - QMAKE_CC = g++ - 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 - QMAKE_CXXFLAGS += -Wextra - - # Switch off optimization for release version - QMAKE_CXXFLAGS_RELEASE -= -O2 - QMAKE_CXXFLAGS_RELEASE += -O0 - QMAKE_CFLAGS_RELEASE -= -O2 - QMAKE_CFLAGS_RELEASE += -O0 - - # Switch on optimization for debug version - #QMAKE_CXXFLAGS_DEBUG += -O2 - #QMAKE_CFLAGS_DEBUG += -O2 - - DEFINES += USE_CMD_ARGS - - CONFIG += upnp_miniupnpc - - LIBS_DIR = $$PWD/../../../libs - OPENPGPSDK_DIR = $$PWD/../../openpgpsdk/src - - DEPENDPATH += . $$LIBS_DIR/include $$LIBS_DIR/include/miniupnpc $$OPENPGPSDK_DIR - INCLUDEPATH += . $$LIBS_DIR/include $$LIBS_DIR/include/miniupnpc $$OPENPGPSDK_DIR -} - -################################# MacOSX ########################################## - -mac { - QMAKE_CC = g++ - OBJECTS_DIR = temp/obj - MOC_DIR = temp/moc - #DEFINES = WINDOWS_SYS WIN32 STATICLIB MINGW - #DEFINES *= MINIUPNPC_VERSION=13 - DESTDIR = lib - - CONFIG += upnp_miniupnpc - - # zeroconf disabled at the end of libretroshare.pro (but need the code) - 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 - - INCLUDEPATH += . $${UPNPC_DIR} - INCLUDEPATH += $${OPENPGPSDK_DIR} - - #../openpgpsdk - #INCLUDEPATH += . $${UPNPC_DIR} $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src -} - -################################# FreeBSD ########################################## - -freebsd-* { - INCLUDEPATH *= /usr/local/include/gpgme - INCLUDEPATH *= /usr/local/include/glib-2.0 - - QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dstat64=stat -Dstatvfs64=statvfs -Dfopen64=fopen - - # linux/bsd can use either - libupnp is more complete and packaged. - #CONFIG += upnp_miniupnpc - CONFIG += upnp_libupnp - - DESTDIR = lib -} - -################################# OpenBSD ########################################## - -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 - - DESTDIR = lib -} - -################################### COMMON stuff ################################## - -# openpgpsdk -PRE_TARGETDEPS *= ../../openpgpsdk/src/lib/libops.a -LIBS *= ../../openpgpsdk/src/lib/libops.a -lbz2 - -HEADERS += dbase/cachestrapper.h \ - dbase/fimonitor.h \ - dbase/findex.h \ - dbase/fistore.h - -HEADERS += ft/ftchunkmap.h \ - ft/ftcontroller.h \ - ft/ftdata.h \ - ft/ftdatamultiplex.h \ - ft/ftdbase.h \ - ft/ftextralist.h \ - ft/ftfilecreator.h \ - ft/ftfileprovider.h \ - ft/ftfilesearch.h \ - ft/ftsearch.h \ - ft/ftserver.h \ - ft/fttransfermodule.h \ - ft/ftturtlefiletransferitem.h - -HEADERS += chat/distantchat.h \ - chat/p3chatservice.h \ - chat/distributedchat.h \ - chat/rschatitems.h - -HEADERS += pqi/authssl.h \ - pqi/authgpg.h \ - pqi/rsmemory.h \ - pgp/pgphandler.h \ - pgp/pgpkeyutil.h \ - pgp/rsaes.h \ - pgp/rscertificate.h \ - pgp/pgpauxutils.h \ - pqi/p3cfgmgr.h \ - pqi/p3peermgr.h \ - pqi/p3linkmgr.h \ - pqi/p3netmgr.h \ - pqi/p3notify.h \ - pqi/p3upnpmgr.h \ - pqi/pqiqos.h \ - pqi/pqi.h \ - pqi/pqi_base.h \ - pqi/pqiarchive.h \ - pqi/pqiassist.h \ - pqi/pqibin.h \ - pqi/pqihandler.h \ - pqi/pqihash.h \ - pqi/p3historymgr.h \ - pqi/pqiindic.h \ - pqi/pqiipset.h \ - pqi/pqilistener.h \ - pqi/pqiloopback.h \ - pqi/pqimonitor.h \ - pqi/pqinetwork.h \ - pqi/pqiperson.h \ - pqi/pqipersongrp.h \ - pqi/pqiservice.h \ - pqi/pqissl.h \ - pqi/pqissllistener.h \ - pqi/pqisslpersongrp.h \ - pqi/pqissludp.h \ - pqi/pqisslproxy.h \ - pqi/pqistore.h \ - pqi/pqistreamer.h \ - pqi/pqithreadstreamer.h \ - pqi/pqiqosstreamer.h \ - pqi/sslfns.h \ - pqi/pqinetstatebox.h \ - pqi/p3servicecontrol.h \ - -# pqi/p3dhtmgr.h \ - -HEADERS += rsserver/p3face.h \ - rsserver/p3history.h \ - rsserver/p3msgs.h \ - rsserver/p3peers.h \ - rsserver/p3status.h \ - rsserver/rsaccounts.h \ - rsserver/p3serverconfig.h - -HEADERS += grouter/groutercache.h \ - grouter/rsgrouter.h \ - grouter/grouteritems.h \ - grouter/p3grouter.h \ - grouter/rsgroutermatrix.h \ - grouter/groutertypes.h \ - grouter/rsgrouterclient.h - -HEADERS += serialiser/itempriorities.h \ - serialiser/rsbaseserial.h \ - serialiser/rsfiletransferitems.h \ - serialiser/rsserviceserialiser.h \ - serialiser/rsconfigitems.h \ - serialiser/rshistoryitems.h \ - serialiser/rsmsgitems.h \ - serialiser/rsserial.h \ - serialiser/rsserviceids.h \ - serialiser/rsserviceitems.h \ - serialiser/rsstatusitems.h \ - serialiser/rstlvaddrs.h \ - serialiser/rstlvbase.h \ - serialiser/rstlvitem.h \ - serialiser/rstlvidset.h \ - serialiser/rstlvfileitem.h \ - serialiser/rstlvimage.h \ - serialiser/rstlvstring.h \ - serialiser/rstlvbinary.h \ - serialiser/rstlvkeys.h \ - serialiser/rstlvkeyvalue.h \ - serialiser/rstlvgenericparam.h \ - serialiser/rstlvgenericmap.h \ - serialiser/rstlvgenericmap.inl \ - serialiser/rstlvlist.h \ - serialiser/rstlvmaps.h \ - serialiser/rstlvbanlist.h \ - serialiser/rsbanlistitems.h \ - serialiser/rsbwctrlitems.h \ - serialiser/rsdiscovery2items.h \ - serialiser/rsheartbeatitems.h \ - serialiser/rsrttitems.h \ - serialiser/rsgxsrecognitems.h \ - serialiser/rsgxsupdateitems.h \ - serialiser/rsserviceinfoitems.h \ - -HEADERS += services/p3msgservice.h \ - services/p3service.h \ - services/p3statusservice.h \ - services/p3banlist.h \ - services/p3bwctrl.h \ - services/p3discovery2.h \ - services/p3heartbeat.h \ - services/p3rtt.h \ - services/p3serviceinfo.cc \ - -HEADERS += turtle/p3turtle.h \ - turtle/rsturtleitem.h \ - turtle/turtletypes.h \ - turtle/turtleclientservice.h - -HEADERS += util/folderiterator.h \ - util/rsdebug.h \ - util/rscompress.h \ - util/smallobject.h \ - util/rsdir.h \ - util/rsdiscspace.h \ - util/rsnet.h \ - util/extaddrfinder.h \ - util/dnsresolver.h \ - util/rsprint.h \ - util/rsstring.h \ - util/rsstd.h \ - util/rsthreads.h \ - util/rsversioninfo.h \ - util/rswin.h \ - util/rsrandom.h \ - util/radix64.h \ - util/pugiconfig.h \ - util/rsmemcache.h \ - util/rstickevent.h \ - util/rsrecogn.h \ - util/rsscopetimer.h - -SOURCES += dbase/cachestrapper.cc \ - dbase/fimonitor.cc \ - dbase/findex.cc \ - dbase/fistore.cc \ - dbase/rsexpr.cc - - -SOURCES += ft/ftchunkmap.cc \ - ft/ftcontroller.cc \ - ft/ftdatamultiplex.cc \ - ft/ftdbase.cc \ - ft/ftextralist.cc \ - ft/ftfilecreator.cc \ - ft/ftfileprovider.cc \ - ft/ftfilesearch.cc \ - ft/ftserver.cc \ - ft/fttransfermodule.cc \ - ft/ftturtlefiletransferitem.cc - -SOURCES += chat/distantchat.cc \ - chat/p3chatservice.cc \ - chat/distributedchat.cc \ - chat/rschatitems.cc - -SOURCES += pqi/authgpg.cc \ - pqi/authssl.cc \ - pgp/pgphandler.cc \ - pgp/pgpkeyutil.cc \ - pgp/rscertificate.cc \ - pgp/pgpauxutils.cc \ - pqi/p3cfgmgr.cc \ - pqi/p3peermgr.cc \ - pqi/p3linkmgr.cc \ - pqi/p3netmgr.cc \ - pqi/p3notify.cc \ - pqi/pqiqos.cc \ - pqi/pqiarchive.cc \ - pqi/pqibin.cc \ - pqi/pqihandler.cc \ - pqi/p3historymgr.cc \ - pqi/pqiipset.cc \ - pqi/pqiloopback.cc \ - pqi/pqimonitor.cc \ - pqi/pqinetwork.cc \ - pqi/pqiperson.cc \ - pqi/pqipersongrp.cc \ - pqi/pqiservice.cc \ - pqi/pqissl.cc \ - pqi/pqissllistener.cc \ - pqi/pqisslpersongrp.cc \ - pqi/pqissludp.cc \ - pqi/pqisslproxy.cc \ - pqi/pqistore.cc \ - pqi/pqistreamer.cc \ - pqi/pqithreadstreamer.cc \ - pqi/pqiqosstreamer.cc \ - pqi/sslfns.cc \ - pqi/pqinetstatebox.cc \ - pqi/p3servicecontrol.cc \ - -# pqi/p3dhtmgr.cc \ - -SOURCES += rsserver/p3face-config.cc \ - rsserver/p3face-server.cc \ - rsserver/p3face-info.cc \ - rsserver/p3history.cc \ - rsserver/p3msgs.cc \ - rsserver/p3peers.cc \ - rsserver/p3status.cc \ - rsserver/rsinit.cc \ - rsserver/rsaccounts.cc \ - rsserver/rsloginhandler.cc \ - rsserver/rstypes.cc \ - rsserver/p3serverconfig.cc - -SOURCES += grouter/p3grouter.cc \ - grouter/grouteritems.cc \ - grouter/groutermatrix.cc - -SOURCES += plugins/pluginmanager.cc \ - plugins/dlfcn_win32.cc \ - serialiser/rspluginitems.cc - -SOURCES += serialiser/rsbaseserial.cc \ - serialiser/rsfiletransferitems.cc \ - serialiser/rsserviceserialiser.cc \ - serialiser/rsconfigitems.cc \ - serialiser/rshistoryitems.cc \ - serialiser/rsmsgitems.cc \ - serialiser/rsserial.cc \ - serialiser/rsstatusitems.cc \ - serialiser/rstlvaddrs.cc \ - serialiser/rstlvbase.cc \ - serialiser/rstlvitem.cc \ - serialiser/rstlvidset.cc \ - serialiser/rstlvfileitem.cc \ - serialiser/rstlvimage.cc \ - serialiser/rstlvstring.cc \ - serialiser/rstlvbinary.cc \ - serialiser/rstlvkeys.cc \ - serialiser/rstlvkeyvalue.cc \ - serialiser/rstlvgenericparam.cc \ - serialiser/rstlvbanlist.cc \ - serialiser/rsbanlistitems.cc \ - serialiser/rsbwctrlitems.cc \ - serialiser/rsdiscovery2items.cc \ - serialiser/rsheartbeatitems.cc \ - serialiser/rsrttitems.cc \ - serialiser/rsgxsrecognitems.cc \ - serialiser/rsgxsupdateitems.cc \ - serialiser/rsserviceinfoitems.cc \ - -SOURCES += services/p3msgservice.cc \ - services/p3service.cc \ - services/p3statusservice.cc \ - services/p3banlist.cc \ - services/p3bwctrl.cc \ - services/p3discovery2.cc \ - services/p3heartbeat.cc \ - services/p3rtt.cc \ - services/p3serviceinfo.cc \ - -SOURCES += turtle/p3turtle.cc \ - turtle/rsturtleitem.cc -# turtle/turtlerouting.cc \ -# turtle/turtlesearch.cc \ -# turtle/turtletunnels.cc - - -SOURCES += util/folderiterator.cc \ - util/rsdebug.cc \ - util/rscompress.cc \ - util/smallobject.cc \ - util/rsdir.cc \ - util/rsdiscspace.cc \ - util/rsnet.cc \ - util/rsnet_ss.cc \ - util/extaddrfinder.cc \ - util/dnsresolver.cc \ - util/rsprint.cc \ - util/rsstring.cc \ - util/rsthreads.cc \ - util/rsversioninfo.cc \ - util/rswin.cc \ - util/rsaes.cc \ - util/rsrandom.cc \ - util/rstickevent.cc \ - util/rsrecogn.cc \ - util/rsscopetimer.cc - - -upnp_miniupnpc { - HEADERS += upnp/upnputil.h upnp/upnphandler_miniupnp.h - SOURCES += upnp/upnputil.c upnp/upnphandler_miniupnp.cc -} - -upnp_libupnp { - HEADERS += upnp/UPnPBase.h upnp/upnphandler_linux.h - SOURCES += upnp/UPnPBase.cpp upnp/upnphandler_linux.cc - DEFINES *= RS_USE_LIBUPNP -} - - - -zeroconf { - -HEADERS += zeroconf/p3zeroconf.h \ - -SOURCES += zeroconf/p3zeroconf.cc \ - -# Disable Zeroconf (we still need the code for zcnatassist -# DEFINES *= RS_ENABLE_ZEROCONF - -} - -# This is seperated from the above for windows/linux platforms. -# It is acceptable to build in zeroconf and have it not work, -# but unacceptable to rely on Apple's libraries for Upnp when we have alternatives. ' - -zcnatassist { - -HEADERS += zeroconf/p3zcnatassist.h \ - -SOURCES += zeroconf/p3zcnatassist.cc \ - - DEFINES *= RS_ENABLE_ZCNATASSIST - -} - -# 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 \ - gxs/rsgds.h \ - gxs/rsgxs.h \ - gxs/rsdataservice.h \ - gxs/rsgxsnetservice.h \ - retroshare/rsgxsflags.h \ - retroshare/rsgxsifacetypes.h \ - gxs/rsgenexchange.h \ - gxs/rsnxsobserver.h \ - gxs/rsgxsdata.h \ - retroshare/rstokenservice.h \ - gxs/rsgxsdataaccess.h \ - retroshare/rsgxsservice.h \ - serialiser/rsgxsitems.h \ - util/retrodb.h \ - util/rsdbbind.h \ - gxs/rsgxsutil.h \ - util/contentvalue.h \ - gxs/gxssecurity.h \ - gxs/rsgxsifacehelper.h \ - gxs/gxstokenqueue.h \ - gxs/rsgxsnetutils.h \ - gxs/rsgxsiface.h \ - gxs/rsgxsrequesttypes.h - - - SOURCES += serialiser/rsnxsitems.cc \ - gxs/rsdataservice.cc \ - gxs/rsgenexchange.cc \ - gxs/rsgxsnetservice.cc \ - gxs/rsgxsdata.cc \ - serialiser/rsgxsitems.cc \ - gxs/rsgxsdataaccess.cc \ - util/retrodb.cc \ - util/contentvalue.cc \ - util/rsdbbind.cc \ - gxs/gxssecurity.cc \ - gxs/gxstokenqueue.cc \ - gxs/rsgxsnetutils.cc \ - gxs/rsgxsutil.cc \ - gxs/rsgxsrequesttypes.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 \ - serialiser/rsgxsiditems.cc \ - services/p3gxsreputation.cc \ - serialiser/rsgxsreputationitems.cc \ - - # GxsTunnel service - HEADERS += gxstunnel/p3gxstunnel.h \ - gxstunnel/rsgxstunnelitems.h \ - retroshare/rsgxstunnel.h - - SOURCES += gxstunnel/p3gxstunnel.cc \ - gxstunnel/rsgxstunnelitems.cc - - # GxsCircles Service - HEADERS += services/p3gxscircles.h \ - serialiser/rsgxscircleitems.h \ - retroshare/rsgxscircles.h \ - - SOURCES += services/p3gxscircles.cc \ - serialiser/rsgxscircleitems.cc \ - - # GxsForums Service - HEADERS += retroshare/rsgxsforums.h \ - services/p3gxsforums.h \ - serialiser/rsgxsforumitems.h - - SOURCES += services/p3gxsforums.cc \ - serialiser/rsgxsforumitems.cc \ - - # GxsChannels Service - HEADERS += retroshare/rsgxschannels.h \ - services/p3gxschannels.h \ - services/p3gxscommon.h \ - serialiser/rsgxscommentitems.h \ - serialiser/rsgxschannelitems.h \ - - SOURCES += services/p3gxschannels.cc \ - services/p3gxscommon.cc \ - serialiser/rsgxscommentitems.cc \ - serialiser/rsgxschannelitems.cc \ - - # Wiki Service - HEADERS += retroshare/rswiki.h \ - services/p3wiki.h \ - serialiser/rswikiitems.h - - SOURCES += services/p3wiki.cc \ - serialiser/rswikiitems.cc \ - - # Wire Service - HEADERS += retroshare/rswire.h \ - services/p3wire.h \ - serialiser/rswireitems.h - - SOURCES += services/p3wire.cc \ - serialiser/rswireitems.cc \ - - # Posted Service - HEADERS += services/p3postbase.h \ - services/p3posted.h \ - retroshare/rsposted.h \ - serialiser/rsposteditems.h - - SOURCES += services/p3postbase.cc \ - services/p3posted.cc \ - serialiser/rsposteditems.cc - - #Photo Service - HEADERS += services/p3photoservice.h \ - retroshare/rsphoto.h \ - serialiser/rsphotoitems.h \ - - SOURCES += services/p3photoservice.cc \ - serialiser/rsphotoitems.cc \ -} - - - - - - -########################################################################################################### -# OLD CONFIG OPTIONS. -# Not used much - but might be useful one day. -# - -testnetwork { - # used in rsserver/rsinit.cc Enabled Port Restrictions, and makes Proxy Port next to Dht Port. - DEFINES *= LOCALNET_TESTING - - # used in tcponudp/udprelay.cc Debugging Info for Relays. - DEFINES *= DEBUG_UDP_RELAY - - # used in tcponudp/udpstunner.[h | cc] enables local stun (careful - modifies class variables). - DEFINES *= UDPSTUN_ALLOW_LOCALNET - - # used in pqi/p3linkmgr.cc prints out extra debug. - DEFINES *= LINKMGR_DEBUG_LINKTYPE - - # used in dht/connectstatebox to reduce connection times and display debug. - # DEFINES *= TESTING_PERIODS - # DEFINES *= DEBUG_CONNECTBOX -} - - -test_bitdht { - # DISABLE TCP CONNECTIONS... - DEFINES *= P3CONNMGR_NO_TCP_CONNECTIONS - - # NO AUTO CONNECTIONS??? FOR TESTING DHT STATUS. - DEFINES *= P3CONNMGR_NO_AUTO_CONNECTION - - # ENABLED UDP NOW. -} - - - +!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri") + +TEMPLATE = lib +CONFIG += staticlib bitdht +CONFIG += create_prl +CONFIG -= qt +TARGET = retroshare +TARGET_PRL = libretroshare +DESTDIR = lib + +#CONFIG += dsdv + +profiling { + QMAKE_CXXFLAGS -= -fomit-frame-pointer + QMAKE_CXXFLAGS *= -pg -g -fno-omit-frame-pointer +} + +# treat warnings as error for better removing +#QMAKE_CFLAGS += -Werror +#QMAKE_CXXFLAGS += -Werror + +debug { +# DEFINES *= DEBUG +# DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG +# DEFINES *= CONTROL_DEBUG FT_DEBUG DEBUG_FTCHUNK P3TURTLE_DEBUG +# DEFINES *= P3TURTLE_DEBUG +# DEFINES *= NET_DEBUG +# DEFINES *= DISTRIB_DEBUG +# DEFINES *= P3TURTLE_DEBUG FT_DEBUG DEBUG_FTCHUNK MPLEX_DEBUG +# DEFINES *= STATUS_DEBUG SERV_DEBUG RSSERIAL_DEBUG #CONN_DEBUG + + QMAKE_CXXFLAGS -= -O2 -fomit-frame-pointer + QMAKE_CXXFLAGS *= -g -fno-omit-frame-pointer +} + +dsdv { +DEFINES *= SERVICES_DSDV +HEADERS += services/p3dsdv.h \ + serialiser/rstlvdsdv.h \ + serialiser/rsdsdvitems.h \ + retroshare/rsdsdv.h + +SOURCES *= serialiser/rstlvdsdv.cc \ + serialiser/rsdsdvitems.cc \ + services/p3dsdv.cc +} +bitdht { + +HEADERS += dht/p3bitdht.h \ + dht/connectstatebox.h \ + dht/stunaddrassist.h + +SOURCES += dht/p3bitdht.cc \ + dht/p3bitdht_interface.cc \ + dht/p3bitdht_peers.cc \ + dht/p3bitdht_peernet.cc \ + dht/p3bitdht_relay.cc \ + dht/connectstatebox.cc + +HEADERS += tcponudp/udppeer.h \ + tcponudp/bio_tou.h \ + tcponudp/tcppacket.h \ + tcponudp/tcpstream.h \ + tcponudp/tou.h \ + tcponudp/udpstunner.h \ + tcponudp/udprelay.h \ + +SOURCES += tcponudp/udppeer.cc \ + tcponudp/tcppacket.cc \ + tcponudp/tcpstream.cc \ + tcponudp/tou.cc \ + tcponudp/bss_tou.c \ + tcponudp/udpstunner.cc \ + tcponudp/udprelay.cc \ + + DEFINES *= RS_USE_BITDHT + + BITDHT_DIR = ../../libbitdht/src + DEPENDPATH += . $${BITDHT_DIR} + INCLUDEPATH += . $${BITDHT_DIR} + PRE_TARGETDEPS *= $${BITDHT_DIR}/lib/libbitdht.a + LIBS *= $${BITDHT_DIR}/lib/libbitdht.a +} + + + + +PUBLIC_HEADERS = retroshare/rsdisc.h \ + retroshare/rsexpr.h \ + retroshare/rsfiles.h \ + retroshare/rshistory.h \ + retroshare/rsids.h \ + retroshare/rsiface.h \ + retroshare/rsinit.h \ + retroshare/rsplugin.h \ + retroshare/rsloginhandler.h \ + retroshare/rsmsgs.h \ + retroshare/rsnotify.h \ + retroshare/rspeers.h \ + retroshare/rsrank.h \ + retroshare/rsstatus.h \ + retroshare/rsturtle.h \ + retroshare/rsbanlist.h \ + retroshare/rstypes.h \ + retroshare/rsdht.h \ + retroshare/rsrtt.h \ + retroshare/rsconfig.h \ + retroshare/rsversion.h \ + retroshare/rsservicecontrol.h \ + + +HEADERS += plugins/pluginmanager.h \ + plugins/dlfcn_win32.h \ + serialiser/rspluginitems.h \ + util/rsinitedptr.h + +HEADERS += $$PUBLIC_HEADERS + + +################################# Linux ########################################## +linux-* { + CONFIG += link_pkgconfig + + QMAKE_CXXFLAGS *= -Wall -D_FILE_OFFSET_BITS=64 + QMAKE_CC = g++ + + contains(CONFIG, NO_SQLCIPHER) { + DEFINES *= NO_SQLCIPHER + PKGCONFIG *= sqlite3 + } else { + SQLCIPHER_OK = $$system(pkg-config --exists sqlcipher && echo yes) + isEmpty(SQLCIPHER_OK) { + # We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database. + exists(../../../lib/sqlcipher/.libs/libsqlcipher.a) { + LIBS += ../../../lib/sqlcipher/.libs/libsqlcipher.a + DEPENDPATH += ../../../lib/ + INCLUDEPATH += ../../../lib/ + } else { + 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' /usr/include/upnp/upnp.h >/dev/null 2>&1) { + # Normal libupnp + } else { + # Patched libupnp or new unreleased version + DEFINES *= PATCHED_LIBUPNP + } + + DEFINES *= UBUNTU + PKGCONFIG *= gnome-keyring-1 + PKGCONFIG *= libssl libupnp + PKGCONFIG *= libcrypto zlib + LIBS *= -lpthread -ldl +} + +unix { + DEFINES *= PLUGIN_DIR=\"\\\"$${PLUGIN_DIR}\\\"\" + DEFINES *= DATA_DIR=\"\\\"$${DATA_DIR}\\\"\" + + ## where to put the librarys interface + #include_rsiface.path = "$${INC_DIR}" + #include_rsiface.files = $$PUBLIC_HEADERS + #INSTALLS += include_rsiface + + ## where to put the shared library itself + #target.path = "$$LIB_DIR" + #INSTALLS *= target +} + +linux-g++ { + OBJECTS_DIR = temp/linux-g++/obj +} + +linux-g++-64 { + OBJECTS_DIR = temp/linux-g++-64/obj +} + +version_detail_bash_script { + linux-* { + QMAKE_EXTRA_TARGETS += write_version_detail + PRE_TARGETDEPS = write_version_detail + write_version_detail.commands = ./version_detail.sh + } + win32 { + QMAKE_EXTRA_TARGETS += write_version_detail + PRE_TARGETDEPS = write_version_detail + write_version_detail.commands = $$PWD/version_detail.bat + } +} + +#################### Cross compilation for windows under Linux #################### + +win32-x-g++ { + OBJECTS_DIR = temp/win32xgcc/obj + DEFINES *= WINDOWS_SYS WIN32 WIN_CROSS_UBUNTU + QMAKE_CXXFLAGS *= -Wmissing-include-dirs + QMAKE_CC = i586-mingw32msvc-g++ + QMAKE_LIB = i586-mingw32msvc-ar + QMAKE_AR = i586-mingw32msvc-ar + DEFINES *= STATICLIB WIN32 + + CONFIG += upnp_miniupnpc + + SSL_DIR=../../../../openssl + UPNPC_DIR = ../../../../miniupnpc-1.3 + GPG_ERROR_DIR = ../../../../libgpg-error-1.7 + GPGME_DIR = ../../../../gpgme-1.1.8 + + INCLUDEPATH *= /usr/i586-mingw32msvc/include ${HOME}/.wine/drive_c/pthreads/include/ +} +################################# Windows ########################################## + +win32 { + QMAKE_CC = g++ + OBJECTS_DIR = temp/obj + MOC_DIR = temp/moc + DEFINES *= WINDOWS_SYS WIN32 STATICLIB MINGW WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T + # This defines the platform to be WinXP or later and is needed for getaddrinfo (_WIN32_WINNT_WINXP) + DEFINES *= WINVER=0x0501 + + # Switch on extra warnings + QMAKE_CFLAGS += -Wextra + QMAKE_CXXFLAGS += -Wextra + + # Switch off optimization for release version + QMAKE_CXXFLAGS_RELEASE -= -O2 + QMAKE_CXXFLAGS_RELEASE += -O0 + QMAKE_CFLAGS_RELEASE -= -O2 + QMAKE_CFLAGS_RELEASE += -O0 + + # Switch on optimization for debug version + #QMAKE_CXXFLAGS_DEBUG += -O2 + #QMAKE_CFLAGS_DEBUG += -O2 + + DEFINES += USE_CMD_ARGS + + CONFIG += upnp_miniupnpc + + LIBS += -lsqlcipher + + DEPENDPATH += . $$INC_DIR + INCLUDEPATH += . $$INC_DIR +} + +################################# MacOSX ########################################## + +mac { + QMAKE_CC = g++ + OBJECTS_DIR = temp/obj + MOC_DIR = temp/moc + #DEFINES = WINDOWS_SYS WIN32 STATICLIB MINGW + DEFINES *= MINIUPNPC_VERSION=13 + + CONFIG += upnp_miniupnpc + + # zeroconf disabled at the end of libretroshare.pro (but need the code) + #CONFIG += zeroconf + #CONFIG += zcnatassist + + # Beautiful Hack to fix 64bit file access. + QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dfopen64=fopen -Dvstatfs64=vstatfs + + UPNPC_DIR = /usr/local/include + #GPG_ERROR_DIR = ../../../../libgpg-error-1.7 + #GPGME_DIR = ../../../../gpgme-1.1.8 + + INCLUDEPATH += . $${UPNPC_DIR} + + #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 ########################################## + +freebsd-* { + INCLUDEPATH *= /usr/local/include/gpgme + INCLUDEPATH *= /usr/local/include/glib-2.0 + + QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dstat64=stat -Dstatvfs64=statvfs -Dfopen64=fopen + + # linux/bsd can use either - libupnp is more complete and packaged. + #CONFIG += upnp_miniupnpc + CONFIG += upnp_libupnp +} + +################################# OpenBSD ########################################## + +openbsd-* { + INCLUDEPATH *= /usr/local/include + INCLUDEPATH += $$system(pkg-config --cflags glib-2.0 | sed -e "s/-I//g") + + 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 +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 \ + dbase/findex.h \ + dbase/fistore.h + +HEADERS += ft/ftchunkmap.h \ + ft/ftcontroller.h \ + ft/ftdata.h \ + ft/ftdatamultiplex.h \ + ft/ftdbase.h \ + ft/ftextralist.h \ + ft/ftfilecreator.h \ + ft/ftfileprovider.h \ + ft/ftfilesearch.h \ + ft/ftsearch.h \ + ft/ftserver.h \ + ft/fttransfermodule.h \ + ft/ftturtlefiletransferitem.h + +HEADERS += chat/distantchat.h \ + chat/p3chatservice.h \ + chat/distributedchat.h \ + chat/rschatitems.h + +HEADERS += pqi/authssl.h \ + pqi/authgpg.h \ + pqi/rsmemory.h \ + pgp/pgphandler.h \ + pgp/pgpkeyutil.h \ + pgp/rsaes.h \ + pgp/rscertificate.h \ + pgp/pgpauxutils.h \ + pqi/p3cfgmgr.h \ + pqi/p3peermgr.h \ + pqi/p3linkmgr.h \ + pqi/p3netmgr.h \ + pqi/p3notify.h \ + pqi/p3upnpmgr.h \ + pqi/pqiqos.h \ + pqi/pqi.h \ + pqi/pqi_base.h \ + pqi/pqiarchive.h \ + pqi/pqiassist.h \ + pqi/pqibin.h \ + pqi/pqihandler.h \ + pqi/pqihash.h \ + pqi/p3historymgr.h \ + pqi/pqiindic.h \ + pqi/pqiipset.h \ + pqi/pqilistener.h \ + pqi/pqiloopback.h \ + pqi/pqimonitor.h \ + pqi/pqinetwork.h \ + pqi/pqiperson.h \ + pqi/pqipersongrp.h \ + pqi/pqiservice.h \ + pqi/pqissl.h \ + pqi/pqissllistener.h \ + pqi/pqisslpersongrp.h \ + pqi/pqissludp.h \ + pqi/pqisslproxy.h \ + pqi/pqistore.h \ + pqi/pqistreamer.h \ + pqi/pqithreadstreamer.h \ + pqi/pqiqosstreamer.h \ + pqi/sslfns.h \ + pqi/pqinetstatebox.h \ + pqi/p3servicecontrol.h \ + +# pqi/p3dhtmgr.h \ + +HEADERS += rsserver/p3face.h \ + rsserver/p3history.h \ + rsserver/p3msgs.h \ + rsserver/p3peers.h \ + rsserver/p3status.h \ + rsserver/rsaccounts.h \ + rsserver/p3serverconfig.h + +HEADERS += grouter/groutercache.h \ + grouter/rsgrouter.h \ + grouter/grouteritems.h \ + grouter/p3grouter.h \ + grouter/rsgroutermatrix.h \ + grouter/groutertypes.h \ + grouter/rsgrouterclient.h + +HEADERS += serialiser/itempriorities.h \ + serialiser/rsbaseserial.h \ + serialiser/rsfiletransferitems.h \ + serialiser/rsserviceserialiser.h \ + serialiser/rsconfigitems.h \ + serialiser/rshistoryitems.h \ + serialiser/rsmsgitems.h \ + serialiser/rsserial.h \ + serialiser/rsserviceids.h \ + serialiser/rsserviceitems.h \ + serialiser/rsstatusitems.h \ + serialiser/rstlvaddrs.h \ + serialiser/rstlvbase.h \ + serialiser/rstlvitem.h \ + serialiser/rstlvidset.h \ + serialiser/rstlvfileitem.h \ + serialiser/rstlvimage.h \ + serialiser/rstlvstring.h \ + serialiser/rstlvbinary.h \ + serialiser/rstlvkeys.h \ + serialiser/rstlvkeyvalue.h \ + serialiser/rstlvgenericparam.h \ + serialiser/rstlvgenericmap.h \ + serialiser/rstlvgenericmap.inl \ + serialiser/rstlvlist.h \ + serialiser/rstlvmaps.h \ + serialiser/rstlvbanlist.h \ + serialiser/rsbanlistitems.h \ + serialiser/rsbwctrlitems.h \ + serialiser/rsdiscovery2items.h \ + serialiser/rsheartbeatitems.h \ + serialiser/rsrttitems.h \ + serialiser/rsgxsrecognitems.h \ + serialiser/rsgxsupdateitems.h \ + serialiser/rsserviceinfoitems.h \ + +HEADERS += services/p3msgservice.h \ + services/p3service.h \ + services/p3statusservice.h \ + services/p3banlist.h \ + services/p3bwctrl.h \ + services/p3discovery2.h \ + services/p3heartbeat.h \ + services/p3rtt.h \ + services/p3serviceinfo.cc \ + +HEADERS += turtle/p3turtle.h \ + turtle/rsturtleitem.h \ + turtle/turtletypes.h \ + turtle/turtleclientservice.h + +HEADERS += util/folderiterator.h \ + util/rsdebug.h \ + util/rscompress.h \ + util/smallobject.h \ + util/rsdir.h \ + util/rsdiscspace.h \ + util/rsnet.h \ + util/extaddrfinder.h \ + util/dnsresolver.h \ + util/rsprint.h \ + util/rsstring.h \ + util/rsstd.h \ + util/rsthreads.h \ + util/rsversioninfo.h \ + util/rswin.h \ + util/rsrandom.h \ + util/radix64.h \ + util/pugiconfig.h \ + util/rsmemcache.h \ + util/rstickevent.h \ + util/rsrecogn.h \ + util/rsscopetimer.h + +SOURCES += dbase/cachestrapper.cc \ + dbase/fimonitor.cc \ + dbase/findex.cc \ + dbase/fistore.cc \ + dbase/rsexpr.cc + + +SOURCES += ft/ftchunkmap.cc \ + ft/ftcontroller.cc \ + ft/ftdatamultiplex.cc \ + ft/ftdbase.cc \ + ft/ftextralist.cc \ + ft/ftfilecreator.cc \ + ft/ftfileprovider.cc \ + ft/ftfilesearch.cc \ + ft/ftserver.cc \ + ft/fttransfermodule.cc \ + ft/ftturtlefiletransferitem.cc + +SOURCES += chat/distantchat.cc \ + chat/p3chatservice.cc \ + chat/distributedchat.cc \ + chat/rschatitems.cc + +SOURCES += pqi/authgpg.cc \ + pqi/authssl.cc \ + pgp/pgphandler.cc \ + pgp/pgpkeyutil.cc \ + pgp/rscertificate.cc \ + pgp/pgpauxutils.cc \ + pqi/p3cfgmgr.cc \ + pqi/p3peermgr.cc \ + pqi/p3linkmgr.cc \ + pqi/p3netmgr.cc \ + pqi/p3notify.cc \ + pqi/pqiqos.cc \ + pqi/pqiarchive.cc \ + pqi/pqibin.cc \ + pqi/pqihandler.cc \ + pqi/p3historymgr.cc \ + pqi/pqiipset.cc \ + pqi/pqiloopback.cc \ + pqi/pqimonitor.cc \ + pqi/pqinetwork.cc \ + pqi/pqiperson.cc \ + pqi/pqipersongrp.cc \ + pqi/pqiservice.cc \ + pqi/pqissl.cc \ + pqi/pqissllistener.cc \ + pqi/pqisslpersongrp.cc \ + pqi/pqissludp.cc \ + pqi/pqisslproxy.cc \ + pqi/pqistore.cc \ + pqi/pqistreamer.cc \ + pqi/pqithreadstreamer.cc \ + pqi/pqiqosstreamer.cc \ + pqi/sslfns.cc \ + pqi/pqinetstatebox.cc \ + pqi/p3servicecontrol.cc \ + +# pqi/p3dhtmgr.cc \ + +SOURCES += rsserver/p3face-config.cc \ + rsserver/p3face-server.cc \ + rsserver/p3face-info.cc \ + rsserver/p3history.cc \ + rsserver/p3msgs.cc \ + rsserver/p3peers.cc \ + rsserver/p3status.cc \ + rsserver/rsinit.cc \ + rsserver/rsaccounts.cc \ + rsserver/rsloginhandler.cc \ + rsserver/rstypes.cc \ + rsserver/p3serverconfig.cc + +SOURCES += grouter/p3grouter.cc \ + grouter/grouteritems.cc \ + grouter/groutermatrix.cc + +SOURCES += plugins/pluginmanager.cc \ + plugins/dlfcn_win32.cc \ + serialiser/rspluginitems.cc + +SOURCES += serialiser/rsbaseserial.cc \ + serialiser/rsfiletransferitems.cc \ + serialiser/rsserviceserialiser.cc \ + serialiser/rsconfigitems.cc \ + serialiser/rshistoryitems.cc \ + serialiser/rsmsgitems.cc \ + serialiser/rsserial.cc \ + serialiser/rsstatusitems.cc \ + serialiser/rstlvaddrs.cc \ + serialiser/rstlvbase.cc \ + serialiser/rstlvitem.cc \ + serialiser/rstlvidset.cc \ + serialiser/rstlvfileitem.cc \ + serialiser/rstlvimage.cc \ + serialiser/rstlvstring.cc \ + serialiser/rstlvbinary.cc \ + serialiser/rstlvkeys.cc \ + serialiser/rstlvkeyvalue.cc \ + serialiser/rstlvgenericparam.cc \ + serialiser/rstlvbanlist.cc \ + serialiser/rsbanlistitems.cc \ + serialiser/rsbwctrlitems.cc \ + serialiser/rsdiscovery2items.cc \ + serialiser/rsheartbeatitems.cc \ + serialiser/rsrttitems.cc \ + serialiser/rsgxsrecognitems.cc \ + serialiser/rsgxsupdateitems.cc \ + serialiser/rsserviceinfoitems.cc \ + +SOURCES += services/p3msgservice.cc \ + services/p3service.cc \ + services/p3statusservice.cc \ + services/p3banlist.cc \ + services/p3bwctrl.cc \ + services/p3discovery2.cc \ + services/p3heartbeat.cc \ + services/p3rtt.cc \ + services/p3serviceinfo.cc \ + +SOURCES += turtle/p3turtle.cc \ + turtle/rsturtleitem.cc +# turtle/turtlerouting.cc \ +# turtle/turtlesearch.cc \ +# turtle/turtletunnels.cc + + +SOURCES += util/folderiterator.cc \ + util/rsdebug.cc \ + util/rscompress.cc \ + util/smallobject.cc \ + util/rsdir.cc \ + util/rsdiscspace.cc \ + util/rsnet.cc \ + util/rsnet_ss.cc \ + util/extaddrfinder.cc \ + util/dnsresolver.cc \ + util/rsprint.cc \ + util/rsstring.cc \ + util/rsthreads.cc \ + util/rsversioninfo.cc \ + util/rswin.cc \ + util/rsaes.cc \ + util/rsrandom.cc \ + util/rstickevent.cc \ + util/rsrecogn.cc \ + util/rsscopetimer.cc + + +upnp_miniupnpc { + HEADERS += upnp/upnputil.h upnp/upnphandler_miniupnp.h + SOURCES += upnp/upnputil.c upnp/upnphandler_miniupnp.cc +} + +upnp_libupnp { + HEADERS += upnp/UPnPBase.h upnp/upnphandler_linux.h + SOURCES += upnp/UPnPBase.cpp upnp/upnphandler_linux.cc + DEFINES *= RS_USE_LIBUPNP +} + + + +zeroconf { + +HEADERS += zeroconf/p3zeroconf.h \ + +SOURCES += zeroconf/p3zeroconf.cc \ + +# Disable Zeroconf (we still need the code for zcnatassist +# DEFINES *= RS_ENABLE_ZEROCONF + +} + +# This is seperated from the above for windows/linux platforms. +# It is acceptable to build in zeroconf and have it not work, +# but unacceptable to rely on Apple's libraries for Upnp when we have alternatives. ' + +zcnatassist { + +HEADERS += zeroconf/p3zcnatassist.h \ + +SOURCES += zeroconf/p3zcnatassist.cc \ + + DEFINES *= RS_ENABLE_ZCNATASSIST + +} + +# new gxs cache system +# this should be disabled for releases until further notice. + +DEFINES *= SQLITE_HAS_CODEC +DEFINES *= GXS_ENABLE_SYNC_MSGS + +HEADERS += serialiser/rsnxsitems.h \ + gxs/rsgds.h \ + gxs/rsgxs.h \ + gxs/rsdataservice.h \ + gxs/rsgxsnetservice.h \ + retroshare/rsgxsflags.h \ + retroshare/rsgxsifacetypes.h \ + gxs/rsgenexchange.h \ + gxs/rsnxsobserver.h \ + gxs/rsgxsdata.h \ + retroshare/rstokenservice.h \ + gxs/rsgxsdataaccess.h \ + retroshare/rsgxsservice.h \ + serialiser/rsgxsitems.h \ + util/retrodb.h \ + util/rsdbbind.h \ + gxs/rsgxsutil.h \ + util/contentvalue.h \ + gxs/gxssecurity.h \ + gxs/rsgxsifacehelper.h \ + gxs/gxstokenqueue.h \ + gxs/rsgxsnetutils.h \ + gxs/rsgxsiface.h \ + gxs/rsgxsrequesttypes.h + + +SOURCES += serialiser/rsnxsitems.cc \ + gxs/rsdataservice.cc \ + gxs/rsgenexchange.cc \ + gxs/rsgxsnetservice.cc \ + gxs/rsgxsdata.cc \ + serialiser/rsgxsitems.cc \ + gxs/rsgxsdataaccess.cc \ + util/retrodb.cc \ + util/contentvalue.cc \ + util/rsdbbind.cc \ + gxs/gxssecurity.cc \ + gxs/gxstokenqueue.cc \ + gxs/rsgxsnetutils.cc \ + gxs/rsgxsutil.cc \ + gxs/rsgxsrequesttypes.cc + +# gxs tunnels +HEADERS += gxstunnel/p3gxstunnel.h \ + gxstunnel/rsgxstunnelitems.h \ + retroshare/rsgxstunnel.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 \ + serialiser/rsgxsiditems.cc \ + services/p3gxsreputation.cc \ + serialiser/rsgxsreputationitems.cc \ + +# GxsCircles Service +HEADERS += services/p3gxscircles.h \ + serialiser/rsgxscircleitems.h \ + retroshare/rsgxscircles.h \ + +SOURCES += services/p3gxscircles.cc \ + serialiser/rsgxscircleitems.cc \ + +# GxsForums Service +HEADERS += retroshare/rsgxsforums.h \ + services/p3gxsforums.h \ + serialiser/rsgxsforumitems.h + +SOURCES += services/p3gxsforums.cc \ + serialiser/rsgxsforumitems.cc \ + +# GxsChannels Service +HEADERS += retroshare/rsgxschannels.h \ + services/p3gxschannels.h \ + services/p3gxscommon.h \ + serialiser/rsgxscommentitems.h \ + serialiser/rsgxschannelitems.h \ + +SOURCES += services/p3gxschannels.cc \ + services/p3gxscommon.cc \ + serialiser/rsgxscommentitems.cc \ + serialiser/rsgxschannelitems.cc \ + +wikipoos { + # Wiki Service + HEADERS += retroshare/rswiki.h \ + services/p3wiki.h \ + serialiser/rswikiitems.h + + SOURCES += services/p3wiki.cc \ + serialiser/rswikiitems.cc \ +} + +gxsthewire { + # Wire Service + HEADERS += retroshare/rswire.h \ + services/p3wire.h \ + serialiser/rswireitems.h + + SOURCES += services/p3wire.cc \ + serialiser/rswireitems.cc \ +} + +# Posted Service +HEADERS += services/p3postbase.h \ + services/p3posted.h \ + retroshare/rsposted.h \ + serialiser/rsposteditems.h + +SOURCES += services/p3postbase.cc \ + services/p3posted.cc \ + serialiser/rsposteditems.cc + +gxsphotoshare { + #Photo Service + HEADERS += services/p3photoservice.h \ + retroshare/rsphoto.h \ + serialiser/rsphotoitems.h \ + + SOURCES += services/p3photoservice.cc \ + serialiser/rsphotoitems.cc \ +} + + + + + + +########################################################################################################### +# OLD CONFIG OPTIONS. +# Not used much - but might be useful one day. +# + +testnetwork { + # used in rsserver/rsinit.cc Enabled Port Restrictions, and makes Proxy Port next to Dht Port. + DEFINES *= LOCALNET_TESTING + + # used in tcponudp/udprelay.cc Debugging Info for Relays. + DEFINES *= DEBUG_UDP_RELAY + + # used in tcponudp/udpstunner.[h | cc] enables local stun (careful - modifies class variables). + DEFINES *= UDPSTUN_ALLOW_LOCALNET + + # used in pqi/p3linkmgr.cc prints out extra debug. + DEFINES *= LINKMGR_DEBUG_LINKTYPE + + # used in dht/connectstatebox to reduce connection times and display debug. + # DEFINES *= TESTING_PERIODS + # DEFINES *= DEBUG_CONNECTBOX +} + + +test_bitdht { + # DISABLE TCP CONNECTIONS... + DEFINES *= P3CONNMGR_NO_TCP_CONNECTIONS + + # NO AUTO CONNECTIONS??? FOR TESTING DHT STATUS. + DEFINES *= P3CONNMGR_NO_AUTO_CONNECTION + + # ENABLED UDP NOW. +} + diff --git a/libretroshare/src/pgp/pgpkeyutil.cc b/libretroshare/src/pgp/pgpkeyutil.cc index f415f8db9..067496bf0 100644 --- a/libretroshare/src/pgp/pgpkeyutil.cc +++ b/libretroshare/src/pgp/pgpkeyutil.cc @@ -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) ; diff --git a/libretroshare/src/pqi/Makefile b/libretroshare/src/pqi/Makefile deleted file mode 100644 index dc41bfa16..000000000 --- a/libretroshare/src/pqi/Makefile +++ /dev/null @@ -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 -############################################################### - diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index 661894512..274187f5b 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -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]); } diff --git a/libretroshare/src/pqi/p3cfgmgr.cc b/libretroshare/src/pqi/p3cfgmgr.cc index 6f11af038..b920cffa8 100644 --- a/libretroshare/src/pqi/p3cfgmgr.cc +++ b/libretroshare/src/pqi/p3cfgmgr.cc @@ -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) diff --git a/libretroshare/src/pqi/p3historymgr.cc b/libretroshare/src/pqi/p3historymgr.cc index b4f5c3068..04e97f08a 100644 --- a/libretroshare/src/pqi/p3historymgr.cc +++ b/libretroshare/src/pqi/p3historymgr.cc @@ -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 @@ -168,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 ; @@ -182,7 +188,9 @@ void p3HistoryMgr::cleanOldMessages() std::map::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) ; @@ -198,7 +206,9 @@ void p3HistoryMgr::cleanOldMessages() { std::map >::iterator mit2 = mit ; ++mit2 ; - std::cerr << " removing peer id " << mit->first << ", since it has no messages" << std::endl; +#ifdef HISTMGR_DEBUG + std::cerr << " removing peer id " << mit->first << ", since it has no messages" << std::endl; +#endif mMessages.erase(mit) ; mit = mit2 ; @@ -303,7 +313,9 @@ bool p3HistoryMgr::loadList(std::list& load) std::map >::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)); @@ -341,7 +353,9 @@ bool p3HistoryMgr::loadList(std::list& 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; } @@ -443,7 +457,9 @@ bool p3HistoryMgr::getMessages(const ChatId &chatId, std::list &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; @@ -464,7 +480,9 @@ bool p3HistoryMgr::getMessages(const ChatId &chatId, std::list &msgs } } } +#ifdef HISTMGR_DEBUG std::cerr << msgs.size() << " messages added." << std::endl; +#endif return true; } @@ -494,7 +512,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 >::iterator mit = mMessages.find(chatPeerId); if (mit == mMessages.end()) { @@ -520,7 +540,9 @@ void p3HistoryMgr::removeMessages(const std::list &msgIds) std::list removedIds; std::list::iterator iit; +#ifdef HISTMGR_DEBUG std::cerr << "********** p3History::removeMessages called()" << std::endl; +#endif { RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/ @@ -533,7 +555,9 @@ void p3HistoryMgr::removeMessages(const std::list &msgIds) std::map::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); diff --git a/libretroshare/src/pqi/p3linkmgr.cc b/libretroshare/src/pqi/p3linkmgr.cc index 016e47d5c..d7262bd84 100644 --- a/libretroshare/src/pqi/p3linkmgr.cc +++ b/libretroshare/src/pqi/p3linkmgr.cc @@ -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); @@ -1624,6 +1625,17 @@ bool p3LinkMgrIMPL::retryConnectTCP(const RsPeerId &id) /* 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)) + { +#ifdef LINKMGR_DEBUG + std::cerr << "p3LinkMgrIMPL::retryConnectTCP() invalid hidden type (" << type << ") -> return false"; + std::cerr << std::endl; +#endif + return false; + } + struct sockaddr_storage proxy_addr; std::string domain_addr; uint16_t domain_port; @@ -1636,7 +1648,7 @@ bool p3LinkMgrIMPL::retryConnectTCP(const RsPeerId &id) std::map::iterator it; if (mFriendList.end() != (it = mFriendList.find(id))) { - 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)); } } @@ -1698,7 +1710,7 @@ bool p3LinkMgrIMPL::retryConnectTCP(const RsPeerId &id) #define MAX_TCP_ADDR_AGE (3600 * 24 * 14) // two weeks in seconds. -bool p3LinkMgrIMPL::locked_CheckPotentialAddr(const struct sockaddr_storage &addr, time_t age) +bool p3LinkMgrIMPL::locked_CheckPotentialAddr(const struct sockaddr_storage &addr, time_t age) { #ifdef LINKMGR_DEBUG std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr("; @@ -1719,13 +1731,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 +1767,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; - + return true; } @@ -2018,7 +1972,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 +1980,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; diff --git a/libretroshare/src/pqi/p3linkmgr.h b/libretroshare/src/pqi/p3linkmgr.h index a35bf508c..0565cd740 100644 --- a/libretroshare/src/pqi/p3linkmgr.h +++ b/libretroshare/src/pqi/p3linkmgr.h @@ -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); diff --git a/libretroshare/src/pqi/p3netmgr.cc b/libretroshare/src/pqi/p3netmgr.cc index ccca8eb37..8776ad182 100644 --- a/libretroshare/src/pqi/p3netmgr.cc +++ b/libretroshare/src/pqi/p3netmgr.cc @@ -696,9 +696,9 @@ void p3NetMgrIMPL::netExtCheck() bool isStable = false; struct sockaddr_storage tmpip ; - std::map address_votes ; + std::map address_votes ; - /* check for External Address */ + /* check for External Address */ /* in order of importance */ /* (1) UPnP -> which handles itself */ { @@ -708,35 +708,41 @@ void p3NetMgrIMPL::netExtCheck() /* net Assist */ if (netAssistExtAddress(tmpip)) - { + { #if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netExtCheck() Ext supplied from netAssistExternalAddress()" << std::endl; + std::cerr << "p3NetMgrIMPL::netExtCheck() Ext supplied from netAssistExternalAddress()" << std::endl; #endif - if(sockaddr_storage_isValidNet(tmpip)) - { - if(rsBanList->isAddressAccepted(tmpip,RSBANLIST_CHECKING_FLAGS_BLACKLIST)) - { - // must be stable??? - isStable = true; - mNetFlags.mExtAddr = tmpip; - mNetFlags.mExtAddrOk = true; - mNetFlags.mExtAddrStableOk = isStable; + if(sockaddr_storage_isValidNet(tmpip)) + { + if(rsBanList->isAddressAccepted(tmpip,RSBANLIST_CHECKING_FLAGS_BLACKLIST)) + { + // must be stable??? + isStable = true; + //mNetFlags.mExtAddr = tmpip; + mNetFlags.mExtAddrOk = true; + mNetFlags.mExtAddrStableOk = isStable; - address_votes[tmpip].n++ ; - } - else - std::cerr << "(SS) netAssisExternalAddress returned wrong own IP " << sockaddr_storage_iptostring(tmpip) << " (banned). Rejecting." << std::endl; - } + address_votes[tmpip].n++ ; + + std::cerr << "NetAssistAddress reported external address " << sockaddr_storage_iptostring(tmpip) << std::endl; + } + else + 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 - { - std::cerr << "p3NetMgrIMPL::netExtCheck() Bad Address supplied from netAssistExternalAddress()" << std::endl; - } + else + { + std::cerr << "p3NetMgrIMPL::netExtCheck() Bad Address supplied from netAssistExternalAddress()" << std::endl; + } #endif - } + } } +#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) @@ -748,30 +754,31 @@ void p3NetMgrIMPL::netExtCheck() if (mDhtStunner) { - /* input network bits */ - if (mDhtStunner->getExternalAddr(tmpaddr, isstable)) - { - if(rsBanList->isAddressAccepted(tmpaddr,RSBANLIST_CHECKING_FLAGS_BLACKLIST)) - { - // must be stable??? - isStable = (isstable == 1); - mNetFlags.mExtAddr = tmpaddr; - mNetFlags.mExtAddrOk = true; - mNetFlags.mExtAddrStableOk = isStable; + /* input network bits */ + if (mDhtStunner->getExternalAddr(tmpaddr, isstable)) + { + if(rsBanList->isAddressAccepted(tmpaddr,RSBANLIST_CHECKING_FLAGS_BLACKLIST)) + { + // must be stable??? + isStable = (isstable == 1); + //mNetFlags.mExtAddr = tmpaddr; + mNetFlags.mExtAddrOk = true; + mNetFlags.mExtAddrStableOk = isStable; - address_votes[tmpaddr].n++ ; + address_votes[tmpaddr].n++ ; #ifdef NETMGR_DEBUG_STATEBOX - std::cerr << "p3NetMgrIMPL::netExtCheck() From DhtStunner: "; - std::cerr << sockaddr_storage_tostring(tmpaddr); - std::cerr << " Stable: " << (uint32_t) isstable; - std::cerr << std::endl; + std::cerr << "p3NetMgrIMPL::netExtCheck() From DhtStunner: "; + std::cerr << sockaddr_storage_tostring(tmpaddr); + std::cerr << " Stable: " << (uint32_t) isstable; + std::cerr << std::endl; #endif - } - else - std::cerr << "(SS) DHTStunner returned wrong own IP " << sockaddr_storage_iptostring(tmpaddr) << " (banned). Rejecting." << std::endl; - } + } + else + std::cerr << "(SS) DHTStunner returned wrong own IP " << sockaddr_storage_iptostring(tmpaddr) << " (banned). Rejecting." << std::endl; + } } } +#endif /* otherwise ask ExtAddrFinder */ { @@ -782,119 +789,159 @@ void p3NetMgrIMPL::netExtCheck() std::cerr << "p3NetMgrIMPL::netExtCheck() checking ExtAddrFinder" << std::endl; #endif bool extFinderOk = mExtAddrFinder->hasValidIP(tmpip); - if (extFinderOk) + if (extFinderOk) { #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(tmpip, 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 = tmpip; + //mNetFlags.mExtAddr = tmpip; mNetFlags.mExtAddrOk = true; - address_votes[tmpip].n++ ; + address_votes[tmpip].n++ ; /* XXX HACK TO FIX */ #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; } } } - - /* any other sources ??? */ + + /* 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 */ if (mNetFlags.mExtAddrOk) - { - // look at votes. + { + // look at votes. - std::cerr << "Figuring out ext addr from voting:" << std::endl; - uint32_t admax = 0 ; + std::cerr << "Figuring out ext addr from voting:" << std::endl; + uint32_t admax = 0 ; - for(std::map::const_iterator it(address_votes.begin());it!=address_votes.end();++it) - { - std::cerr << " Vote: " << sockaddr_storage_iptostring(it->first) << " : " << it->second.n << " votes." ; + for(std::map::const_iterator it(address_votes.begin());it!=address_votes.end();++it) + { + std::cerr << " Vote: " << sockaddr_storage_iptostring(it->first) << " : " << it->second.n << " votes." ; - if(it->second.n > admax) - { - mNetFlags.mExtAddr = it->first ; - admax = it->second.n ; + if(it->second.n > admax) + { + mNetFlags.mExtAddr = it->first ; + admax = it->second.n ; - std::cerr << " Kept!" << std::endl; - } - else - std::cerr << " Discarded." << std::endl; - } + std::cerr << " Kept!" << std::endl; + } + else + std::cerr << " Discarded." << std::endl; + } #if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netExtCheck() "; - std::cerr << "ExtAddr: " << sockaddr_storage_tostring(mNetFlags.mExtAddr); - std::cerr << std::endl; + std::cerr << "p3NetMgrIMPL::netExtCheck() "; + std::cerr << "ExtAddr: " << sockaddr_storage_tostring(mNetFlags.mExtAddr); + std::cerr << std::endl; #endif - //update ip address list - mExtAddr = mNetFlags.mExtAddr; + //update ip address list + mExtAddr = mNetFlags.mExtAddr; - mNetStatus = RS_NET_DONE; - netSetupDone = true; + mNetStatus = RS_NET_DONE; + netSetupDone = true; #if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netExtCheck() Ext Ok: RS_NET_DONE" << std::endl; + std::cerr << "p3NetMgrIMPL::netExtCheck() Ext Ok: RS_NET_DONE" << std::endl; #endif - if (!mNetFlags.mExtAddrStableOk) - { + if (!mNetFlags.mExtAddrStableOk) + { #if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netUdpCheck() UDP Unstable :( "; - std::cerr << std::endl; - std::cerr << "p3NetMgrIMPL::netUdpCheck() We are unreachable"; - std::cerr << std::endl; - std::cerr << "netMode => RS_NET_MODE_UNREACHABLE"; - std::cerr << std::endl; + std::cerr << "p3NetMgrIMPL::netUdpCheck() UDP Unstable :( "; + std::cerr << std::endl; + std::cerr << "p3NetMgrIMPL::netUdpCheck() We are unreachable"; + std::cerr << std::endl; + std::cerr << "netMode => RS_NET_MODE_UNREACHABLE"; + std::cerr << std::endl; #endif - // Due to the new UDP connections - we can still connect some of the time! - // So limit warning! + // Due to the new UDP connections - we can still connect some of the time! + // So limit warning! - //mNetMode &= ~(RS_NET_MODE_ACTUAL); - //mNetMode |= RS_NET_MODE_UNREACHABLE; + //mNetMode &= ~(RS_NET_MODE_ACTUAL); + //mNetMode |= RS_NET_MODE_UNREACHABLE; - /* send a system warning message */ - //pqiNotify *notify = getPqiNotify(); - //if (notify) - { - std::string title = - "Warning: Bad Firewall Configuration"; + /* send a system warning message */ + //pqiNotify *notify = getPqiNotify(); + //if (notify) + { + std::string title = + "Warning: Bad Firewall Configuration"; - std::string msg; - msg += " **** WARNING **** \n"; - msg += "Retroshare has detected that you are behind"; - msg += " a restrictive Firewall\n"; - msg += "\n"; - msg += "You will have limited connectivity to other firewalled peers\n"; - msg += "\n"; - msg += "You can fix this by:\n"; - msg += " (1) opening an External Port\n"; - msg += " (2) enabling UPnP, or\n"; - msg += " (3) get a new (approved) Firewall/Router\n"; + std::string msg; + msg += " **** WARNING **** \n"; + msg += "Retroshare has detected that you are behind"; + msg += " a restrictive Firewall\n"; + msg += "\n"; + msg += "You will have limited connectivity to other firewalled peers\n"; + msg += "\n"; + msg += "You can fix this by:\n"; + msg += " (1) opening an External Port\n"; + msg += " (2) enabling UPnP, or\n"; + msg += " (3) get a new (approved) Firewall/Router\n"; - //notify->AddSysMessage(0, RS_SYS_WARNING, title, msg); + //notify->AddSysMessage(0, RS_SYS_WARNING, title, msg); - std::cerr << msg << std::endl; - } + std::cerr << msg << std::endl; + } - } + } - } + } if (mNetFlags.mExtAddrOk) { diff --git a/libretroshare/src/pqi/p3peermgr.cc b/libretroshare/src/pqi/p3peermgr.cc index dde9d3569..bcde912ef 100644 --- a/libretroshare/src/pqi/p3peermgr.cc +++ b/libretroshare/src/pqi/p3peermgr.cc @@ -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); @@ -372,8 +385,43 @@ bool p3PeerMgrIMPL::isHidden() 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 - return (it->second).hiddenNode; + 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::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)) - { - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - mProxyServerAddress = proxy_addr; + switch (type) { + case RS_HIDDEN_TYPE_I2P: + if (!sockaddr_storage_same(mProxyServerAddressI2P, proxy_addr)) + { + IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ + 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) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - proxy_status = mProxyServerStatus; - return true; -} -bool p3PeerMgrIMPL::getProxyServerAddress(struct sockaddr_storage &proxy_addr) +/** + * @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_addr = mProxyServerAddress; + 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; } - + +/** + * @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 *******/ + + 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::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::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; } } @@ -1246,20 +1467,51 @@ bool p3PeerMgrIMPL::addCandidateForOwnExternalAddress(const RsPeerId &from, cons // * emit a warnign when the address is unknown // * if multiple peers report the same address => notify the LinkMgr that the external address had changed. - sockaddr_storage addr_filtered ; - sockaddr_storage_copyip(addr_filtered,addr) ; + sockaddr_storage addr_filtered ; + sockaddr_storage_clear(addr_filtered) ; + sockaddr_storage_copyip(addr_filtered,addr) ; #ifdef PEER_DEBUG - std::cerr << "Own external address is " << sockaddr_storage_iptostring(addr_filtered) << ", as reported by friend " << from << std::endl; + std::cerr << "Own external address is " << sockaddr_storage_iptostring(addr_filtered) << ", as reported by friend " << from << std::endl; #endif - if(!sockaddr_storage_isExternalNet(addr_filtered)) + if(!sockaddr_storage_isExternalNet(addr_filtered)) + { +#ifdef PEER_DEBUG + std::cerr << " address is not an external address. Returning false" << std::endl ; +#endif + return false ; + } + + // Update a list of own IPs: + // - remove old values for that same peer + // - remove values for non connected peers + { -#ifdef PEER_DEBUG - std::cerr << " address is not an external address. Returning false" << std::endl ; -#endif - return false ; + RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ + + mReportedOwnAddresses[from] = addr_filtered ; + + for(std::map::iterator it(mReportedOwnAddresses.begin());it!=mReportedOwnAddresses.end();) + if(!mLinkMgr->isOnline(it->first)) + { + std::map::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 ; @@ -1282,10 +1534,56 @@ 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 addr_counts ; + + for(std::map::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::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& lst,const RsPeerId& pid,p3LinkMgr *link_mgr) { bool changed = false ; @@ -1620,9 +1918,10 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list& 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& 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& 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& 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,13 +2340,24 @@ bool p3PeerMgrIMPL::loadList(std::list& 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); } return true; diff --git a/libretroshare/src/pqi/p3peermgr.h b/libretroshare/src/pqi/p3peermgr.h index 2af81855a..78be4a6cb 100644 --- a/libretroshare/src/pqi/p3peermgr.h +++ b/libretroshare/src/pqi/p3peermgr.h @@ -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 ******************************/ @@ -349,7 +364,7 @@ void printPeerLists(std::ostream &out); p3LinkMgrIMPL *mLinkMgr; p3NetMgrIMPL *mNetMgr; - + private: RsMutex mPeerMtx; /* protects below */ @@ -362,6 +377,8 @@ private: std::map mFriendList; // std::map mOthersList; + std::map mReportedOwnAddresses ; + std::list groupList; uint32_t lastGroupId; @@ -369,8 +386,10 @@ private: std::map 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 ; }; diff --git a/libretroshare/src/pqi/p3servicecontrol.cc b/libretroshare/src/pqi/p3servicecontrol.cc index 4b3c48f65..820b29a4c 100644 --- a/libretroshare/src/pqi/p3servicecontrol.cc +++ b/libretroshare/src/pqi/p3servicecontrol.cc @@ -148,7 +148,7 @@ public: uint32_t tmp ; ok &= getRawUInt32(data, rssize, &offset, &tmp); - for(int i=0;inotifyEvent(this, CONNECT_FAILED, raddr); } } diff --git a/libretroshare/src/pqi/pqilistener.h b/libretroshare/src/pqi/pqilistener.h index 46e030206..6d02db294 100644 --- a/libretroshare/src/pqi/pqilistener.h +++ b/libretroshare/src/pqi/pqilistener.h @@ -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; } }; diff --git a/libretroshare/src/pqi/pqinetwork.cc b/libretroshare/src/pqi/pqinetwork.cc index 00e24c600..5d5c35e8d 100644 --- a/libretroshare/src/pqi/pqinetwork.cc +++ b/libretroshare/src/pqi/pqinetwork.cc @@ -55,6 +55,11 @@ int errno; #endif +#ifdef __HAIKU__ + #include + #define IFF_RUNNING 0x0001 +#endif + /********************************** WINDOWS/UNIX SPECIFIC PART ******************/ #ifndef WINDOWS_SYS @@ -758,52 +763,6 @@ bool getLocalInterfaces(struct sockaddr_storage &existAddr, std::lists_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. @@ -899,16 +858,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 +873,8 @@ int unix_socket(int /*domain*/, int /*type*/, int /*protocol*/) osock = -1; errno = WinToUnixError(WSAGetLastError()); } -#endif -/******************* WINDOWS SPECIFIC PART ******************/ +#endif // WINDOWS_SYS + return osock; } diff --git a/libretroshare/src/pqi/pqinetwork.h b/libretroshare/src/pqi/pqinetwork.h index f8118f7a0..32719f90f 100644 --- a/libretroshare/src/pqi/pqinetwork.h +++ b/libretroshare/src/pqi/pqinetwork.h @@ -38,6 +38,7 @@ #include #include +#include //socket blocking/options. #include @@ -104,10 +105,6 @@ 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 &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); diff --git a/libretroshare/src/pqi/pqiperson.h b/libretroshare/src/pqi/pqiperson.h index 07c345db3..d47fa420a 100644 --- a/libretroshare/src/pqi/pqiperson.h +++ b/libretroshare/src/pqi/pqiperson.h @@ -48,57 +48,36 @@ static const int HEARTBEAT_REPEAT_TIME = 5; #include "pqi/pqiqosstreamer.h" #include "pqi/pqithreadstreamer.h" -class pqiconnect: public pqiQoSstreamer, public NetInterface +class pqiconnect : public pqiQoSstreamer, public NetInterface { public: - pqiconnect(PQInterface *parent, RsSerialiser *rss, NetBinInterface *ni_in) - :pqiQoSstreamer(parent, rss, ni_in->PeerId(), ni_in, 0), // pqistreamer will cleanup NetInterface. - NetInterface(NULL, ni_in->PeerId()), // No need for callback - ni(ni_in) - { - if (!ni_in) - { - std::cerr << "pqiconnect::pqiconnect() NetInterface == NULL, FATAL!"; - std::cerr << std::endl; - exit(1); - } - return; - } + pqiconnect(PQInterface *parent, RsSerialiser *rss, NetBinInterface *ni_in) : + pqiQoSstreamer(parent, rss, ni_in->PeerId(), ni_in, 0), // pqistreamer will cleanup NetInterface. + NetInterface(NULL, ni_in->PeerId()), // No need for callback + ni(ni_in) {} -virtual ~pqiconnect() { return; } -virtual bool getCryptoParams(RsPeerCryptoParams& params) ; + virtual ~pqiconnect() {} + virtual bool getCryptoParams(RsPeerCryptoParams& params); // presents a virtual NetInterface -> passes to ni. -virtual int connect(const struct sockaddr_storage &raddr) { return ni->connect(raddr); } -virtual int listen() { return ni -> listen(); } -virtual int stoplistening() { return ni -> stoplistening(); } -virtual int reset() { return ni -> reset(); } -virtual int disconnect() { return ni -> reset(); } -virtual bool connect_parameter(uint32_t type, uint32_t value) { return ni -> connect_parameter(type, value);} -virtual bool connect_parameter(uint32_t type, std::string value) { return ni -> connect_parameter(type, value);} -virtual bool connect_additional_address(uint32_t type, const struct sockaddr_storage &addr) { return ni -> connect_additional_address(type, addr);} - - -virtual int getConnectAddress(struct sockaddr_storage &raddr){ return ni->getConnectAddress(raddr); } + virtual int connect(const struct sockaddr_storage &raddr) { return ni->connect(raddr); } + virtual int listen() { return ni->listen(); } + virtual int stoplistening() { return ni->stoplistening(); } + virtual int reset() { return ni->reset(); } + virtual int disconnect() { return ni->reset(); } + virtual bool connect_parameter(uint32_t type, uint32_t value) { return ni->connect_parameter(type, value);} + virtual bool connect_parameter(uint32_t type, std::string value) { return ni->connect_parameter(type, value);} + virtual bool connect_additional_address(uint32_t type, const struct sockaddr_storage &addr) { return ni->connect_additional_address(type, addr); } + virtual int getConnectAddress(struct sockaddr_storage &raddr){ return ni->getConnectAddress(raddr); } // get the contact from the net side! -virtual const RsPeerId& PeerId() -{ - if (ni) - { - return ni->PeerId(); - } - else - { - return PQInterface::PeerId(); - } -} + virtual const RsPeerId& PeerId() { return ni->PeerId(); } // to check if our interface. -virtual bool thisNetInterface(NetInterface *ni_in) { return (ni_in == ni); } + virtual bool thisNetInterface(NetInterface *ni_in) { return (ni_in == ni); } + protected: NetBinInterface *ni; -protected: }; diff --git a/libretroshare/src/pqi/pqipersongrp.cc b/libretroshare/src/pqi/pqipersongrp.cc index 9336736b4..e6a44d5cd 100644 --- a/libretroshare/src/pqi/pqipersongrp.cc +++ b/libretroshare/src/pqi/pqipersongrp.cc @@ -617,15 +617,19 @@ int pqipersongrp::connectPeer(const RsPeerId& id uint32_t ptype; if (type & RS_NET_CONN_TCP_ALL) { - if (type == RS_NET_CONN_TCP_HIDDEN) - { - ptype = PQI_CONNECT_HIDDEN_TCP; - timeout = RS_TCP_HIDDEN_TIMEOUT_PERIOD; - } - else - { + switch (type) { + case RS_NET_CONN_TCP_HIDDEN_TOR: + ptype = PQI_CONNECT_HIDDEN_TOR_TCP; + timeout = RS_TCP_HIDDEN_TIMEOUT_PERIOD; + break; + case RS_NET_CONN_TCP_HIDDEN_I2P: + ptype = PQI_CONNECT_HIDDEN_I2P_TCP; + timeout = RS_TCP_HIDDEN_TIMEOUT_PERIOD; + break; + default: ptype = PQI_CONNECT_TCP; - timeout = RS_TCP_STD_TIMEOUT_PERIOD; + timeout = RS_TCP_STD_TIMEOUT_PERIOD; + break; } #ifdef PGRP_DEBUG std::cerr << " pqipersongrp::connectPeer() connecting with TCP: Timeout :" << timeout; diff --git a/libretroshare/src/pqi/pqiqos.cc b/libretroshare/src/pqi/pqiqos.cc index 25db06432..b0d5ec5f5 100644 --- a/libretroshare/src/pqi/pqiqos.cc +++ b/libretroshare/src/pqi/pqiqos.cc @@ -27,7 +27,7 @@ void pqiQoS::clear() { void *item ; - for(int i=0;i<_item_queues.size();++i) + for(uint32_t i=0;i<_item_queues.size();++i) while( (item = _item_queues[i].pop()) != NULL) free(item) ; @@ -46,7 +46,7 @@ void pqiQoS::print() const void pqiQoS::in_rsItem(void *ptr,int priority) { - if(priority >= _item_queues.size()) + if(uint32_t(priority) >= _item_queues.size()) { std::cerr << "pqiQoS::in_rsRawItem() ****Warning****: priority " << priority << " out of scope [0," << _item_queues.size()-1 << "]. Priority will be clamped to maximum value." << std::endl; priority = _item_queues.size()-1 ; diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index 35007db99..1a04dcd73 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -103,7 +103,7 @@ pqissl::pqissl(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm) sslmode(PQISSL_ACTIVE), ssl_connection(NULL), sockfd(-1), readpkt(NULL), pktlen(0), total_len(0), attempt_ts(0), - sameLAN(false), n_read_zero(0), mReadZeroTS(0), ssl_connect_timeout(0), + n_read_zero(0), mReadZeroTS(0), ssl_connect_timeout(0), mConnectDelay(0), mConnectTS(0), mConnectTimeout(0), mTimeoutTS(0) { @@ -255,7 +255,6 @@ int pqissl::reset_locked() sockfd = -1; waiting = WAITING_NOT; ssl_connection = NULL; - sameLAN = false; n_read_zero = 0; mReadZeroTS = 0; total_len = 0 ; @@ -286,54 +285,40 @@ int pqissl::reset_locked() return 1; } -bool pqissl::connect_parameter(uint32_t type, const std::string &value) +bool pqissl::connect_parameter(uint32_t type, uint32_t value) { - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - - /* remove unused parameter warnings */ - (void) type; - (void) value; - return false; -} - - -bool pqissl::connect_parameter(uint32_t type, uint32_t value) -{ - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - -#ifdef PQISSL_LOG_DEBUG - { - std::string out = "pqissl::connect_parameter() Peer: " + PeerId(); - rs_sprintf_append(out, " type: %u value: %u", type, value); - rslog(RSL_DEBUG_ALL, pqisslzone, out); - } +#ifdef PQISSL_LOG_DEBUG + std::cerr << "pqissl::connect_parameter() Peer: " << PeerId(); #endif - if (type == NET_PARAM_CONNECT_DELAY) + switch(type) { -#ifdef PQISSL_LOG_DEBUG - std::string out = "pqissl::connect_parameter() Peer: " + PeerId(); - rs_sprintf_append(out, " DELAY: %u", value); - rslog(RSL_DEBUG_BASIC, pqisslzone, out); + case NET_PARAM_CONNECT_DELAY: + { +#ifdef PQISSL_LOG_DEBUG + std::cerr << " DELAY: " << value << std::endl; #endif - - + RS_STACK_MUTEX(mSslMtx); mConnectDelay = value; return true; } - else if (type == NET_PARAM_CONNECT_TIMEOUT) + case NET_PARAM_CONNECT_TIMEOUT: { -#ifdef PQISSL_LOG_DEBUG - std::string out = "pqissl::connect_parameter() Peer: " + PeerId(); - rs_sprintf_append(out, " TIMEOUT: %u", value); - rslog(RSL_DEBUG_BASIC, pqisslzone, out); +#ifdef PQISSL_LOG_DEBUG + std::cerr << " TIMEOUT: " << value << std::endl; #endif - + RS_STACK_MUTEX(mSslMtx); mConnectTimeout = value; return true; } - return false; - //return NetInterface::connect_parameter(type, value); + default: + { +#ifdef PQISSL_LOG_DEBUG + std::cerr << " type: " << type << " value: " << value << std::endl; +#endif + return false; + } + } } @@ -1472,22 +1457,12 @@ int pqissl::accept_locked(SSL *ssl, int fd, const struct sockaddr_storage &forei struct sockaddr_storage localaddr; mLinkMgr->getLocalAddress(localaddr); - sameLAN = sockaddr_storage_samesubnet(remote_addr, localaddr); { std::string out = "pqissl::accept() SUCCESSFUL connection to: " + PeerId().toStdString(); out += " localaddr: " + sockaddr_storage_iptostring(localaddr); out += " remoteaddr: " + sockaddr_storage_iptostring(remote_addr); - if (sameLAN) - { - out += " SAME LAN"; - } - else - { - out += " DIFF LANs"; - } - rslog(RSL_WARNING, pqisslzone, out); } @@ -1961,10 +1936,7 @@ bool pqissl::cansend(uint32_t usec) } -RsFileHash pqissl::gethash() -{ - return RsFileHash() ; -} +RsFileHash pqissl::gethash() { return RsFileHash(); } /********** End of Implementation of BinInterface ******************/ diff --git a/libretroshare/src/pqi/pqissl.h b/libretroshare/src/pqi/pqissl.h index 13033cce5..b4cd267d6 100644 --- a/libretroshare/src/pqi/pqissl.h +++ b/libretroshare/src/pqi/pqissl.h @@ -98,7 +98,7 @@ virtual int reset(); virtual int disconnect(); virtual int getConnectAddress(struct sockaddr_storage &raddr); -virtual bool connect_parameter(uint32_t type, const std::string &value); +virtual bool connect_parameter(uint32_t /*type*/, const std::string & /*value*/) { return false; } virtual bool connect_parameter(uint32_t type, uint32_t value); // BinInterface @@ -170,10 +170,13 @@ int Extract_Failed_SSL_Certificate(); // try to get cert anyway. bool CheckConnectionTimeout(); - //protected internal fns that are overloaded for udp case. -virtual int net_internal_close(int fd); -virtual int net_internal_SSL_set_fd(SSL *ssl, int fd); -virtual int net_internal_fcntl_nonblock(int fd); + /* Do we really need this ? + * It is very specific TCP+SSL stuff and unlikely to be reused. + * In fact we are overloading them in pqissludp case where they do different things or nothing. + */ + virtual int net_internal_close(int fd); + virtual int net_internal_SSL_set_fd(SSL *ssl, int fd); + virtual int net_internal_fcntl_nonblock(int fd); /* data */ @@ -196,8 +199,6 @@ virtual int net_internal_fcntl_nonblock(int fd); int attempt_ts; - bool sameLAN; /* flag use to allow high-speed transfers */ - int n_read_zero; /* a counter to determine if the connection is really dead */ time_t mReadZeroTS; /* timestamp of first READ_ZERO occurance */ @@ -208,11 +209,9 @@ virtual int net_internal_fcntl_nonblock(int fd); uint32_t mConnectTimeout; time_t mTimeoutTS; - private: // ssl only fns. -int connectInterface(const struct sockaddr_storage &addr); - + int connectInterface(const struct sockaddr_storage &addr); }; diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index b46b946ed..7426d9799 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -56,19 +56,17 @@ const int pqissllistenzone = 49787; */ -pqissllistenbase::pqissllistenbase(const struct sockaddr_storage &addr, p3PeerMgr *pm) - :laddr(addr), active(false), mPeerMgr(pm) - +pqissllistenbase::pqissllistenbase(const sockaddr_storage &addr, p3PeerMgr *pm) + : laddr(addr), active(false), mPeerMgr(pm) { - if (!(AuthSSL::getAuthSSL()-> active())) { - pqioutput(PQL_ALERT, pqissllistenzone, - "SSL-CTX-CERT-ROOT not initialised!"); - + if (!(AuthSSL::getAuthSSL()-> active())) + { + pqioutput(PQL_ALERT, pqissllistenzone, + "SSL-CTX-CERT-ROOT not initialised!"); exit(1); } setuplisten(); - return; } pqissllistenbase::~pqissllistenbase() @@ -123,6 +121,10 @@ int pqissllistenbase::setuplisten() err = fcntl(lsock, F_SETFL, O_NONBLOCK); if (err < 0) { + shutdown(lsock,SHUT_RDWR) ; + close(lsock) ; + lsock = -1 ; + std::string out; rs_sprintf(out, "Error: Cannot make socket NON-Blocking: %d", err); pqioutput(PQL_ERROR, pqissllistenzone, out); @@ -145,6 +147,9 @@ int pqissllistenbase::setuplisten() unsigned long int on = 1; if (0 != (err = ioctlsocket(lsock, FIONBIO, &on))) { + closesocket(lsock) ; + lsock = -1 ; + std::string out; rs_sprintf(out, "pqissllistenbase::setuplisten() Error: Cannot make socket NON-Blocking: %d\n", err); out += "Socket Error: " + socket_errorType(WSAGetLastError()); @@ -723,18 +728,7 @@ int pqissllistenbase::isSSLActive(int /*fd*/, SSL *ssl) * */ -pqissllistener::pqissllistener(const struct sockaddr_storage &addr, p3PeerMgr *lm) - :pqissllistenbase(addr, lm) -{ - return; -} - -pqissllistener::~pqissllistener() -{ - return; -} - -int pqissllistener::addlistenaddr(const RsPeerId& id, pqissl *acc) +int pqissllistener::addlistenaddr(const RsPeerId& id, pqissl *acc) { std::map::iterator it; @@ -748,7 +742,6 @@ int pqissllistener::addlistenaddr(const RsPeerId& id, pqissl *acc) pqioutput(PQL_DEBUG_ALERT, pqissllistenzone, out); return -1; - } } @@ -785,7 +778,7 @@ int pqissllistener::removeListenPort(const RsPeerId& id) } -int pqissllistener::status() +int pqissllistener::status() { pqissllistenbase::status(); // print certificates we are listening for. diff --git a/libretroshare/src/pqi/pqissllistener.h b/libretroshare/src/pqi/pqissllistener.h index 27ab26bab..b5de39069 100644 --- a/libretroshare/src/pqi/pqissllistener.h +++ b/libretroshare/src/pqi/pqissllistener.h @@ -49,13 +49,12 @@ class p3PeerMgr; class AcceptedSSL { - public: - +public: int mFd; SSL *mSSL; RsPeerId mPeerId; - - struct sockaddr_storage mAddr; + + sockaddr_storage mAddr; time_t mAcceptTS; }; @@ -64,26 +63,22 @@ class AcceptedSSL class pqissllistenbase: public pqilistener { - public: +public: + pqissllistenbase(const struct sockaddr_storage &addr, p3PeerMgr *pm); + virtual ~pqissllistenbase(); + /*************************************/ + /* LISTENER INTERFACE */ + virtual int tick(); + virtual int status(); + virtual int setListenAddr(const struct sockaddr_storage &addr); + virtual int setuplisten(); + virtual int resetlisten(); + /*************************************/ - pqissllistenbase(const struct sockaddr_storage &addr, p3PeerMgr *pm); -virtual ~pqissllistenbase(); - -/*************************************/ -/* LISTENER INTERFACE **/ - -virtual int tick(); -virtual int status(); -virtual int setListenAddr(const struct sockaddr_storage &addr); -virtual int setuplisten(); -virtual int resetlisten(); - -/*************************************/ - -int acceptconnection(); -int continueaccepts(); -int finaliseAccepts(); + int acceptconnection(); + int continueaccepts(); + int finaliseAccepts(); struct IncomingSSLInfo { @@ -95,52 +90,44 @@ int finaliseAccepts(); }; // fn to get cert, anyway -int continueSSL(IncomingSSLInfo&, bool); -int closeConnection(int fd, SSL *ssl); -int isSSLActive(int fd, SSL *ssl); + int continueSSL(IncomingSSLInfo&, bool); + int closeConnection(int fd, SSL *ssl); + int isSSLActive(int fd, SSL *ssl); -virtual int completeConnection(int sockfd, IncomingSSLInfo&) = 0; -virtual int finaliseConnection(int fd, SSL *ssl, const RsPeerId& peerId, const struct sockaddr_storage &raddr) = 0; - protected: + virtual int completeConnection(int sockfd, IncomingSSLInfo&) = 0; + virtual int finaliseConnection(int fd, SSL *ssl, const RsPeerId& peerId, + const sockaddr_storage &raddr) = 0; +protected: struct sockaddr_storage laddr; std::list accepted_ssl; - - private: - - int Extract_Failed_SSL_Certificate(const IncomingSSLInfo&); - - bool active; - int lsock; - - std::list incoming_ssl ; - - protected: - p3PeerMgr *mPeerMgr; +private: + int Extract_Failed_SSL_Certificate(const IncomingSSLInfo&); + bool active; + int lsock; + std::list incoming_ssl ; }; class pqissllistener: public pqissllistenbase { - public: +public: + pqissllistener(const struct sockaddr_storage &addr, p3PeerMgr *pm) : + pqissllistenbase(addr, pm) {} + virtual ~pqissllistener() {} - pqissllistener(const struct sockaddr_storage &addr, p3PeerMgr *pm); -virtual ~pqissllistener(); + int addlistenaddr(const RsPeerId& id, pqissl *acc); + int removeListenPort(const RsPeerId& id); -int addlistenaddr(const RsPeerId& id, pqissl *acc); -int removeListenPort(const RsPeerId& id); + virtual int status(); + virtual int completeConnection(int sockfd, IncomingSSLInfo&); + virtual int finaliseConnection(int fd, SSL *ssl, const RsPeerId& peerId, + const sockaddr_storage &raddr); -//virtual int tick(); -virtual int status(); - -virtual int completeConnection(int sockfd, IncomingSSLInfo&); -virtual int finaliseConnection(int fd, SSL *ssl, const RsPeerId& peerId, const struct sockaddr_storage &raddr); - - private: - - std::map listenaddr; +private: + std::map listenaddr; }; diff --git a/libretroshare/src/pqi/pqisslpersongrp.cc b/libretroshare/src/pqi/pqisslpersongrp.cc index 8988d8872..898b28bb5 100644 --- a/libretroshare/src/pqi/pqisslpersongrp.cc +++ b/libretroshare/src/pqi/pqisslpersongrp.cc @@ -91,7 +91,36 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener pqiconnect *pqisc = new pqiconnect(pqip, rss, pqis); - pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TCP, pqisc); + /* first select type based on peer */ + uint32_t typePeer = mPeerMgr->getHiddenType(id); + switch (typePeer) { + case RS_HIDDEN_TYPE_TOR: + pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqisc); + break; + case RS_HIDDEN_TYPE_I2P: + pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqisc); + break; + default: + /* peer is not a hidden one but we are */ + /* select type based on ourselves */ + uint32_t typeOwn = mPeerMgr->getHiddenType(AuthSSL::getAuthSSL()->OwnId()); + switch (typeOwn) { + case RS_HIDDEN_TYPE_I2P: + pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqisc); + break; + default: + /* this case shouldn't happen! */ + std::cerr << "pqisslpersongrp::locked_createPerson WARNING INVALID HIDDEN TYPES - THIS SHOULD NOT HAPPEN!" << std::endl; + std::cerr << " - ID: " << id << std::endl; + std::cerr << " - mPeerMgr->isHidden(): " << mPeerMgr->isHidden() << std::endl; + std::cerr << " - mPeerMgr->isHiddenPeer(id): " << mPeerMgr->isHiddenPeer(id) << std::endl; + std::cerr << " - hidden types: peer=" << typePeer << " own=" << typeOwn << std::endl; + std::cerr << " --> falling back to Tor" << std::endl; + case RS_HIDDEN_TYPE_TOR: + pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqisc); + break; + } + } } else { diff --git a/libretroshare/src/pqi/pqissludp.cc b/libretroshare/src/pqi/pqissludp.cc index 5259fb38e..c9b7c7b4d 100644 --- a/libretroshare/src/pqi/pqissludp.cc +++ b/libretroshare/src/pqi/pqissludp.cc @@ -51,22 +51,22 @@ static const uint32_t PQI_SSLUDP_DEF_CONN_PERIOD = 300; /* 5 minutes? */ /********** PQI SSL UDP STUFF **************************************/ -pqissludp::pqissludp(PQInterface *parent, p3LinkMgr *lm) - :pqissl(NULL, parent, lm), tou_bio(NULL), - listen_checktime(0), mConnectPeriod(PQI_SSLUDP_DEF_CONN_PERIOD), mConnectFlags(0), mConnectBandwidth(0) +pqissludp::pqissludp(PQInterface *parent, p3LinkMgr *lm) : + pqissl(NULL, parent, lm), tou_bio(NULL), listen_checktime(0), + mConnectPeriod(PQI_SSLUDP_DEF_CONN_PERIOD), mConnectFlags(0), + mConnectBandwidth(0) { - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ + RS_STACK_MUTEX(mSslMtx); sockaddr_storage_clear(remote_addr); sockaddr_storage_clear(mConnectProxyAddr); sockaddr_storage_clear(mConnectSrcAddr); - return; } pqissludp::~pqissludp() { - rslog(RSL_ALERT, pqissludpzone, + rslog(RSL_ALERT, pqissludpzone, "pqissludp::~pqissludp -> destroying pqissludp"); /* must call reset from here, so that the @@ -76,16 +76,13 @@ pqissludp::~pqissludp() * This means that reset() will be called twice, but this should * be harmless. */ - stoplistening(); /* remove from p3proxy listenqueue */ - reset(); + stoplistening(); /* remove from p3proxy listenqueue */ + reset(); - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ + RS_STACK_MUTEX(mSslMtx); if (tou_bio) // this should be in the reset? - { BIO_free(tou_bio); - } - return; } int pqissludp::reset_locked() @@ -153,7 +150,7 @@ int pqissludp::attach() // The Address determination is done centrally -int pqissludp::Initiate_Connection() +int pqissludp::Initiate_Connection() { int err; @@ -349,7 +346,7 @@ int pqissludp::Initiate_Connection() } /********* VERY DIFFERENT **********/ -int pqissludp::Basic_Connection_Complete() +int pqissludp::Basic_Connection_Complete() { rslog(RSL_DEBUG_BASIC, pqissludpzone, "pqissludp::Basic_Connection_Complete()..."); @@ -449,15 +446,6 @@ int pqissludp::net_internal_fcntl_nonblock(int /*fd*/) } -/* These are identical to pqinetssl version */ -//int pqissludp::status() - -int pqissludp::tick() -{ - pqissl::tick(); - return 1; -} - // listen fns call the udpproxy. int pqissludp::listen() { diff --git a/libretroshare/src/pqi/pqissludp.h b/libretroshare/src/pqi/pqissludp.h index 86b2bc27a..848717bbd 100644 --- a/libretroshare/src/pqi/pqissludp.h +++ b/libretroshare/src/pqi/pqissludp.h @@ -45,7 +45,7 @@ class pqissludp; class cert; -/* This provides a NetBinInterface, which is +/* This provides a NetBinInterface, which is * primarily inherited from pqissl. * fns declared here are different -> all others are identical. */ @@ -53,49 +53,48 @@ class cert; class pqissludp: public pqissl { public: - pqissludp(PQInterface *parent, p3LinkMgr *lm); + pqissludp(PQInterface *parent, p3LinkMgr *lm); -virtual ~pqissludp(); + virtual ~pqissludp(); // NetInterface. // listen fns call the udpproxy. -virtual int listen(); -virtual int stoplistening(); -virtual int tick(); + virtual int listen(); + virtual int stoplistening(); -virtual bool connect_parameter(uint32_t type, uint32_t value); -virtual bool connect_additional_address(uint32_t type, const struct sockaddr_storage &addr); + virtual bool connect_parameter(uint32_t type, uint32_t value); + virtual bool connect_additional_address(uint32_t type, const struct sockaddr_storage &addr); // BinInterface. // These are reimplemented. -virtual bool moretoread(uint32_t usec); -virtual bool cansend(uint32_t usec); + virtual bool moretoread(uint32_t usec); + virtual bool cansend(uint32_t usec); /* UDP always through firewalls -> always bandwidth Limited */ -virtual bool bandwidthLimited() { return true; } + virtual bool bandwidthLimited() { return true; } protected: // pqissludp specific. // called to initiate a connection; -int attach(); + int attach(); -virtual int reset_locked(); + virtual int reset_locked(); -virtual int Initiate_Connection(); -virtual int Basic_Connection_Complete(); + virtual int Initiate_Connection(); + virtual int Basic_Connection_Complete(); -//protected internal fns that are overloaded for udp case. -virtual int net_internal_close(int fd); -virtual int net_internal_SSL_set_fd(SSL *ssl, int fd); -virtual int net_internal_fcntl_nonblock(int fd); + /* Do we really need this ? + * It is very specific UDP+ToU+SSL stuff and unlikely to be reused. + * In fact we are overloading them here becase they are very do different of pqissl. + */ + virtual int net_internal_close(int fd); + virtual int net_internal_SSL_set_fd(SSL *ssl, int fd); + virtual int net_internal_fcntl_nonblock(int fd); private: BIO *tou_bio; // specific to ssludp. - //int remote_timeout; - //int proxy_timeout; - long listen_checktime; uint32_t mConnectPeriod; diff --git a/libretroshare/src/pqi/sslfns.cc b/libretroshare/src/pqi/sslfns.cc index 2d31950aa..9e5813b75 100644 --- a/libretroshare/src/pqi/sslfns.cc +++ b/libretroshare/src/pqi/sslfns.cc @@ -72,102 +72,79 @@ X509_REQ *GenerateX509Req( std::string loc, std::string state, std::string country, int nbits_in, std::string &errString) { - /* generate request */ - X509_REQ *req=X509_REQ_new(); + /* generate request */ + X509_REQ *req=X509_REQ_new(); - // setup output. - BIO *bio_out = NULL; - bio_out = BIO_new(BIO_s_file()); - BIO_set_fp(bio_out,stdout,BIO_NOCLOSE); + // setup output. + BIO *bio_out = BIO_new(BIO_s_file()); + BIO_set_fp(bio_out,stdout,BIO_NOCLOSE); - EVP_PKEY *pkey = NULL; + EVP_PKEY *pkey = NULL; + X509_NAME *x509_name = NULL ; + RSA *rsa = NULL ; - // first generate a key.... - if ((pkey=EVP_PKEY_new()) == NULL) - { - fprintf(stderr,"GenerateX509Req: Couldn't Create Key\n"); - errString = "Couldn't Create Key"; - return 0; - } + try + { + // first generate a key.... + if ((pkey=EVP_PKEY_new()) == NULL) + { + fprintf(stderr,"GenerateX509Req: Couldn't Create Key\n"); + throw std::runtime_error("Couldn't Create Key") ; + } - int nbits = 2048; - unsigned long e = 0x10001; + int nbits = 2048; + unsigned long e = 0x10001; - if ((nbits_in >= 512) && (nbits_in <= 4096)) - { - nbits = nbits_in; - } - else - { - fprintf(stderr,"GenerateX509Req: strange num of nbits: %d\n", nbits_in); - fprintf(stderr,"GenerateX509Req: reverting to %d\n", nbits); - } + if ((nbits_in >= 512) && (nbits_in <= 4096)) + { + nbits = nbits_in; + } + else + { + fprintf(stderr,"GenerateX509Req: strange num of nbits: %d\n", nbits_in); + fprintf(stderr,"GenerateX509Req: reverting to %d\n", nbits); + } + rsa = RSA_generate_key(nbits, e, NULL, NULL); - RSA *rsa = RSA_generate_key(nbits, e, NULL, NULL); - if ((rsa == NULL) || !EVP_PKEY_assign_RSA(pkey, rsa)) - { - if(rsa) RSA_free(rsa); - fprintf(stderr,"GenerateX509Req: Couldn't Generate RSA Key!\n"); - errString = "Couldn't generate RSA Key"; - return 0; - } + if ((rsa == NULL) || !EVP_PKEY_assign_RSA(pkey, rsa)) + throw std::runtime_error("Couldn't generate RSA Key"); + // open the file. + FILE *out; + if (NULL == (out = RsDirUtil::rs_fopen(pkey_file.c_str(), "w"))) + throw std::runtime_error("Couldn't Create Key File \"" + pkey_file + "\""); - // open the file. - FILE *out; - if (NULL == (out = RsDirUtil::rs_fopen(pkey_file.c_str(), "w"))) - { - fprintf(stderr,"GenerateX509Req: Couldn't Create Key File!"); - fprintf(stderr," : %s\n", pkey_file.c_str()); + const EVP_CIPHER *cipher = EVP_des_ede3_cbc(); - errString = "Couldn't Create Key File"; - return 0; - } + if (!PEM_write_PrivateKey(out,pkey,cipher, NULL,0,NULL,(void *) passwd.c_str())) + { + fclose(out) ; + throw std::runtime_error("Couldn't Save Private Key to file \""+pkey_file+"\""); + } - const EVP_CIPHER *cipher = EVP_des_ede3_cbc(); + fclose(out); - if (!PEM_write_PrivateKey(out,pkey,cipher, - NULL,0,NULL,(void *) passwd.c_str())) - { - fprintf(stderr,"GenerateX509Req() Couldn't Save Private Key"); - fprintf(stderr," : %s\n", pkey_file.c_str()); + // We have now created a private key.... + std::cerr << "GenerateX509Req() Saved Private Key to file \"" << pkey_file << "\"" << std::endl; - errString = "Couldn't Save Private Key File"; - return 0; - } - fclose(out); + /********** Test Loading the private Key.... ************/ + FILE *tst_in = NULL; + EVP_PKEY *tst_pkey = NULL; - // We have now created a private key.... - fprintf(stderr,"GenerateX509Req() Saved Private Key"); - fprintf(stderr," : %s\n", pkey_file.c_str()); + if (NULL == (tst_in = RsDirUtil::rs_fopen(pkey_file.c_str(), "rb"))) + throw std::runtime_error("GenerateX509Req() Couldn't Open Private Key file \""+pkey_file+"\"") ; - /********** Test Loading the private Key.... ************/ - FILE *tst_in = NULL; - EVP_PKEY *tst_pkey = NULL; - if (NULL == (tst_in = RsDirUtil::rs_fopen(pkey_file.c_str(), "rb"))) - { - fprintf(stderr,"GenerateX509Req() Couldn't Open Private Key"); - fprintf(stderr," : %s\n", pkey_file.c_str()); + if (NULL == (tst_pkey = PEM_read_PrivateKey(tst_in,NULL,NULL,(void *) passwd.c_str()))) + { + fclose(tst_in); + throw std::runtime_error("GenerateX509Req() Couldn't read Private Key file \""+pkey_file+"\"") ; + } - errString = "Couldn't Open Private Key"; - return 0; - } + fclose(tst_in); + EVP_PKEY_free(tst_pkey); - if (NULL == (tst_pkey = - PEM_read_PrivateKey(tst_in,NULL,NULL,(void *) passwd.c_str()))) - { - fprintf(stderr,"GenerateX509Req() Couldn't Read Private Key"); - fprintf(stderr," : %s\n", pkey_file.c_str()); - - errString = "Couldn't Read Private Key"; - return 0; - } - fclose(tst_in); - EVP_PKEY_free(tst_pkey); - /********** Test Loading the private Key.... ************/ - - /* Fill in details: fields. + /* Fill in details: fields. req->req_info; req->req_info->enc; req->req_info->version; @@ -175,108 +152,88 @@ X509_REQ *GenerateX509Req( req->req_info->pubkey; ****************************/ - long version = 0x00; - unsigned long chtype = MBSTRING_UTF8; - X509_NAME *x509_name = X509_NAME_new(); + long version = 0x00; + unsigned long chtype = MBSTRING_UTF8; + x509_name = X509_NAME_new(); - // fill in the request. + // fill in the request. - /**** X509_REQ -> Version ********************************/ - if (!X509_REQ_set_version(req,version)) /* version 1 */ - { - fprintf(stderr,"GenerateX509Req(): Couldn't Set Version!\n"); + /**** X509_REQ -> Version ********************************/ + if(!X509_REQ_set_version(req,version)) /* version 1 */ + throw std::runtime_error("GenerateX509Req(): Couldn't Set SSL certificate Version!"); - errString = "Couldn't Set Version"; - return 0; - } - /**** X509_REQ -> Version ********************************/ - /**** X509_REQ -> Key ********************************/ + /**** X509_REQ -> Version ********************************/ + /**** X509_REQ -> Key ********************************/ - if (!X509_REQ_set_pubkey(req,pkey)) - { - fprintf(stderr,"GenerateX509Req() Couldn't Set PUBKEY !\n"); + if (!X509_REQ_set_pubkey(req,pkey)) + throw std::runtime_error("GenerateX509Req(): Couldn't Set SSL certificate PUBKEY!"); - errString = "Couldn't Set PubKey"; - return 0; - } + /**** SUBJECT ********************************/ + // create the name. - /**** SUBJECT ********************************/ - // create the name. + // fields to add. + // commonName CN + // emailAddress (none) + // organizationName O + // localityName L + // stateOrProvinceName ST + // countryName C - // fields to add. - // commonName CN - // emailAddress (none) - // organizationName O - // localityName L - // stateOrProvinceName ST - // countryName C + if (0 == strlen(name.c_str())) + throw std::runtime_error("No name! Aborting.") ; - if (0 < strlen(name.c_str())) - { - X509_NAME_add_entry_by_txt(x509_name, "CN", chtype, - (unsigned char *) name.c_str(), -1, -1, 0); - } - else - { - fprintf(stderr,"GenerateX509Req(): No Name -> Not creating X509 Cert Req\n"); - errString = "No Name, Aborting"; - return 0; - } + X509_NAME_add_entry_by_txt(x509_name, "CN", chtype, (unsigned char *) name.c_str(), -1, -1, 0); - if (0 < strlen(email.c_str())) - { - //X509_NAME_add_entry_by_txt(x509_name, "Email", 0, - // (unsigned char *) ui -> gen_email -> value(), -1, -1, 0); - X509_NAME_add_entry_by_NID(x509_name, 48, 0, - (unsigned char *) email.c_str(), -1, -1, 0); - } + if (0 < strlen(email.c_str())) + X509_NAME_add_entry_by_NID(x509_name, 48, 0, (unsigned char *) email.c_str(), -1, -1, 0); - if (0 < strlen(org.c_str())) - { - X509_NAME_add_entry_by_txt(x509_name, "O", chtype, - (unsigned char *) org.c_str(), -1, -1, 0); - } + if (0 < strlen(org.c_str())) + X509_NAME_add_entry_by_txt(x509_name, "O", chtype, (unsigned char *) org.c_str(), -1, -1, 0); - if (0 < strlen(loc.c_str())) - { - X509_NAME_add_entry_by_txt(x509_name, "L", chtype, - (unsigned char *) loc.c_str(), -1, -1, 0); - } + if (0 < strlen(loc.c_str())) + X509_NAME_add_entry_by_txt(x509_name, "L", chtype, (unsigned char *) loc.c_str(), -1, -1, 0); - if (0 < strlen(state.c_str())) - { - X509_NAME_add_entry_by_txt(x509_name, "ST", chtype, - (unsigned char *) state.c_str(), -1, -1, 0); - } + if (0 < strlen(state.c_str())) + X509_NAME_add_entry_by_txt(x509_name, "ST", chtype, (unsigned char *) state.c_str(), -1, -1, 0); - if (0 < strlen(country.c_str())) - { - X509_NAME_add_entry_by_txt(x509_name, "C", chtype, - (unsigned char *) country.c_str(), -1, -1, 0); - } + if (0 < strlen(country.c_str())) + X509_NAME_add_entry_by_txt(x509_name, "C", chtype, (unsigned char *) country.c_str(), -1, -1, 0); - if (!X509_REQ_set_subject_name(req,x509_name)) - { - fprintf(stderr,"GenerateX509Req() Couldn't Set Name to Request!\n"); - X509_NAME_free(x509_name); + if (!X509_REQ_set_subject_name(req,x509_name)) + throw std::runtime_error("GenerateX509Req() Couldn't Set Name to Request!"); - errString = "Couldn't Set Name"; - return 0; - } + X509_NAME_free(x509_name); - X509_NAME_free(x509_name); - /**** SUBJECT ********************************/ + /**** SUBJECT ********************************/ - if (!X509_REQ_sign(req,pkey,EVP_sha1())) - { - fprintf(stderr,"GenerateX509Req() Failed to Sign REQ\n"); + if (!X509_REQ_sign(req,pkey,EVP_sha1())) + throw std::runtime_error("GenerateX509Req() Failed to sign REQ"); - errString = "Couldn't Sign Req"; - return 0; - } + errString = "No Error"; - errString = "No Error"; - return req; + return req; + } + catch(std::exception& e) + { + std::cerr << "(EE) Key creation failed: " << e.what() << std::endl; + errString = e.what() ; + req = NULL ; + } + + + if(rsa) + RSA_free(rsa); + + if(x509_name) + X509_NAME_free(x509_name); + + if(bio_out) + BIO_free_all(bio_out) ; + + if(pkey) + EVP_PKEY_free(pkey); + + return req ; } #define SERIAL_RAND_BITS 64 diff --git a/libretroshare/src/retroshare/Makefile b/libretroshare/src/retroshare/Makefile deleted file mode 100644 index 0b4646b09..000000000 --- a/libretroshare/src/retroshare/Makefile +++ /dev/null @@ -1,25 +0,0 @@ - -RS_TOP_DIR = .. -##### Define any flags that are needed for this section ####### -############################################################### - -############################################################### -include $(RS_TOP_DIR)/scripts/config.mk -############################################################### - -OBJ = notifytxt.o retroshare.o - -#TESTOBJ = - -TESTS = retroshare-nogui - -all: tests - -retroshare-nogui: $(OBJ) - $(CC) $(CFLAGS) -o retroshare-nogui $(OBJ) $(LIBS) - - -############################################################### -include $(RS_TOP_DIR)/scripts/rules.mk -############################################################### - diff --git a/libretroshare/src/retroshare/rsgrouter.h b/libretroshare/src/retroshare/rsgrouter.h index 8db40b194..acd3aee10 100644 --- a/libretroshare/src/retroshare/rsgrouter.h +++ b/libretroshare/src/retroshare/rsgrouter.h @@ -102,6 +102,9 @@ public: //===================================================// virtual void addRoutingClue(const GRouterKeyId& destination, const RsPeerId& source) =0; + virtual void addTrackingInfo(const RsGxsMessageId& mid,const RsPeerId& peer_id) =0; + + virtual bool getTrackingInfo(const RsGxsMessageId& mid, RsPeerId& provider_id) =0; }; // To access the GRouter from anywhere diff --git a/libretroshare/src/retroshare/rsgxsflags.h b/libretroshare/src/retroshare/rsgxsflags.h index a7cc27ee4..0b2d78a08 100644 --- a/libretroshare/src/retroshare/rsgxsflags.h +++ b/libretroshare/src/retroshare/rsgxsflags.h @@ -18,48 +18,36 @@ namespace GXS_SERV { /** START privacy **/ - static const uint32_t FLAG_PRIVACY_MASK = 0x0000000f; - - // pub key encrypted - static const uint32_t FLAG_PRIVACY_PRIVATE = 0x00000001; - - // publish private key needed to publish - static const uint32_t FLAG_PRIVACY_RESTRICTED = 0x00000002; - - // anyone can publish, publish key pair not needed - static const uint32_t FLAG_PRIVACY_PUBLIC = 0x00000004; + static const uint32_t FLAG_PRIVACY_MASK = 0x0000000f; + static const uint32_t FLAG_PRIVACY_PRIVATE = 0x00000001; // pub key encrypted + static const uint32_t FLAG_PRIVACY_RESTRICTED = 0x00000002; // publish private key needed to publish + static const uint32_t FLAG_PRIVACY_PUBLIC = 0x00000004; // anyone can publish, publish key pair not needed /** END privacy **/ - /** START authentication **/ - - static const uint32_t FLAG_AUTHEN_MASK = 0x000000f0; - - // identity - static const uint32_t FLAG_AUTHEN_IDENTITY = 0x000000010; - - // publish key - static const uint32_t FLAG_AUTHEN_PUBLISH = 0x000000020; - - // admin key - static const uint32_t FLAG_AUTHEN_ADMIN = 0x00000040; - - // pgp sign identity - static const uint32_t FLAG_AUTHEN_PGP_IDENTITY = 0x00000080; - /** END authentication **/ + + /** START author authentication flags **/ + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_MASK = 0x0000ff00; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_NONE = 0x00000000; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_GPG = 0x00000100; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_REQUIRED = 0x00000200; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN = 0x00000400; + static const uint32_t FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES = 0x00000800; + static const uint32_t FLAG_GROUP_SIGN_PUBLISH_MASK = 0x000000ff; + static const uint32_t FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED = 0x00000001; + static const uint32_t FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED = 0x00000002; + static const uint32_t FLAG_GROUP_SIGN_PUBLISH_THREADHEAD = 0x00000004; + static const uint32_t FLAG_GROUP_SIGN_PUBLISH_NONEREQ = 0x00000008; + /** START msg authentication flags **/ - static const uint8_t MSG_AUTHEN_MASK = 0x0f; - - static const uint8_t MSG_AUTHEN_ROOT_PUBLISH_SIGN = 0x01; - + static const uint8_t MSG_AUTHEN_MASK = 0x0f; + static const uint8_t MSG_AUTHEN_ROOT_PUBLISH_SIGN = 0x01; static const uint8_t MSG_AUTHEN_CHILD_PUBLISH_SIGN = 0x02; - - static const uint8_t MSG_AUTHEN_ROOT_AUTHOR_SIGN = 0x04; - - static const uint8_t MSG_AUTHEN_CHILD_AUTHOR_SIGN = 0x08; + static const uint8_t MSG_AUTHEN_ROOT_AUTHOR_SIGN = 0x04; + static const uint8_t MSG_AUTHEN_CHILD_AUTHOR_SIGN = 0x08; /** END msg authentication flags **/ @@ -71,12 +59,9 @@ namespace GXS_SERV { /** START Subscription Flags. (LOCAL) **/ - static const uint32_t GROUP_SUBSCRIBE_ADMIN = 0x01; - - static const uint32_t GROUP_SUBSCRIBE_PUBLISH = 0x02; - - static const uint32_t GROUP_SUBSCRIBE_SUBSCRIBED = 0x04; - + static const uint32_t GROUP_SUBSCRIBE_ADMIN = 0x01; + static const uint32_t GROUP_SUBSCRIBE_PUBLISH = 0x02; + static const uint32_t GROUP_SUBSCRIBE_SUBSCRIBED = 0x04; static const uint32_t GROUP_SUBSCRIBE_NOT_SUBSCRIBED = 0x08; /*! @@ -95,17 +80,12 @@ namespace GXS_SERV { * * NOTE: RsGxsCommentService uses 0x000f0000. */ - static const uint32_t GXS_MSG_STATUS_GEN_MASK = 0x0000ffff; - + static const uint32_t GXS_MSG_STATUS_GEN_MASK = 0x0000ffff; static const uint32_t GXS_MSG_STATUS_UNPROCESSED = 0x00000001; - - static const uint32_t GXS_MSG_STATUS_GUI_UNREAD = 0x00000002; - - static const uint32_t GXS_MSG_STATUS_GUI_NEW = 0x00000004; - - static const uint32_t GXS_MSG_STATUS_KEEP = 0x00000008; - - static const uint32_t GXS_MSG_STATUS_DELETE = 0x000000020; + static const uint32_t GXS_MSG_STATUS_GUI_UNREAD = 0x00000002; + static const uint32_t GXS_MSG_STATUS_GUI_NEW = 0x00000004; + static const uint32_t GXS_MSG_STATUS_KEEP = 0x00000008; + static const uint32_t GXS_MSG_STATUS_DELETE = 0x00000020; /** END GXS Msg status flags **/ @@ -123,10 +103,13 @@ namespace GXS_SERV { #define IS_MSG_NEW(status) (status & GXS_SERV::GXS_MSG_STATUS_GUI_NEW) #define IS_MSG_UNREAD(status) (status & GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD) +#define IS_GROUP_PGP_AUTHED(signFlags) (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) +#define IS_GROUP_MESSAGE_TRACKING(signFlags) (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) + #define IS_GROUP_ADMIN(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) -#define IS_GROUP_PUBLISHER(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH) +#define IS_GROUP_PUBLISHER(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH) #define IS_GROUP_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) -#define IS_GROUP_NOT_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED) +#define IS_GROUP_NOT_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED) #define IS_MSG_UNPROCESSED(status) (status & GXS_SERV::GXS_MSG_STATUS_UNPROCESSED) diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index fec4d0944..d3ee14041 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -32,6 +32,7 @@ #include "retroshare/rstokenservice.h" #include "retroshare/rsgxsifacehelper.h" +#include "retroshare/rsreputations.h" #include "retroshare/rsids.h" #include "serialiser/rstlvimage.h" #include "retroshare/rsgxscommon.h" @@ -158,8 +159,7 @@ class RsIdentityDetails { public: RsIdentityDetails() - :mIsOwnId(false), mPgpLinked(false), mPgpKnown(false), - mReputation(), mLastUsageTS(0) { return; } + :mIsOwnId(false), mPgpLinked(false), mPgpKnown(false), mLastUsageTS(0) { return; } RsGxsId mId; @@ -175,8 +175,12 @@ public: // Recogn details. std::list mRecognTags; - // reputation details. - GxsReputation mReputation; + // Cyril: Reputation details. At some point we might want to merge information + // between the two into a single global score. Since the old reputation system + // is not finished yet, I leave this in place. We should decide what to do with it. + + GxsReputation mReputation_oldSystem; // this is the old "mReputation" field, which apparently is not used. + RsReputations::ReputationInfo mReputation; // avatar RsGxsImage mAvatar ; @@ -214,7 +218,7 @@ public: /********************************************************************************************/ /********************************************************************************************/ - + // For Other Services.... // It should be impossible for them to get a message which we don't have the identity. // Its a major error if we don't have the identity. diff --git a/libretroshare/src/retroshare/rspeers.h b/libretroshare/src/retroshare/rspeers.h index afb3f1a81..b10c85983 100644 --- a/libretroshare/src/retroshare/rspeers.h +++ b/libretroshare/src/retroshare/rspeers.h @@ -63,6 +63,14 @@ const uint32_t RS_NETMODE_EXT = 0x0003; const uint32_t RS_NETMODE_HIDDEN = 0x0004; const uint32_t RS_NETMODE_UNREACHABLE = 0x0005; +/* Hidden Type */ +const uint32_t RS_HIDDEN_TYPE_NONE = 0x0000; +const uint32_t RS_HIDDEN_TYPE_UNKNOWN = 0x0001; +const uint32_t RS_HIDDEN_TYPE_TOR = 0x0002; +const uint32_t RS_HIDDEN_TYPE_I2P = 0x0004; +/* mask to match all valid hidden types */ +const uint32_t RS_HIDDEN_TYPE_MASK = RS_HIDDEN_TYPE_I2P | RS_HIDDEN_TYPE_TOR; + /* Visibility */ const uint32_t RS_VS_DISC_OFF = 0x0000; const uint32_t RS_VS_DISC_MINIMAL = 0x0001; @@ -96,7 +104,8 @@ const uint32_t RS_PEER_CONNECTSTATE_TRYING_UDP = 3; const uint32_t RS_PEER_CONNECTSTATE_CONNECTED_TCP = 4; const uint32_t RS_PEER_CONNECTSTATE_CONNECTED_UDP = 5; const uint32_t RS_PEER_CONNECTSTATE_CONNECTED_TOR = 6; -const uint32_t RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN = 7; +const uint32_t RS_PEER_CONNECTSTATE_CONNECTED_I2P = 7; +const uint32_t RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN = 8; /* Error codes for certificate cleaning and cert parsing. Numbers should not overlap. */ @@ -232,6 +241,7 @@ class RsPeerDetails bool isHiddenNode; std::string hiddenNodeAddress; uint16_t hiddenNodePort; + uint32_t hiddenType; // Filled in for Standard Node. std::string localAddr; @@ -350,8 +360,8 @@ class RsPeers virtual bool setNetworkMode(const RsPeerId &ssl_id, uint32_t netMode) = 0; virtual bool setVisState(const RsPeerId &ssl_id, uint16_t vs_disc, uint16_t vs_dht) = 0; - virtual bool getProxyServer(std::string &addr, uint16_t &port,uint32_t& status_flags) = 0; - virtual bool setProxyServer(const std::string &addr, const uint16_t port) = 0; + virtual bool getProxyServer(const uint32_t type, std::string &addr, uint16_t &port,uint32_t& status_flags) = 0; + virtual bool setProxyServer(const uint32_t type, const std::string &addr, const uint16_t port) = 0; virtual void getIPServersList(std::list& ip_servers) = 0; virtual void allowServerIPDetermination(bool) = 0; diff --git a/libretroshare/src/retroshare/rsplugin.h b/libretroshare/src/retroshare/rsplugin.h index bb882c8dd..83936fe8e 100644 --- a/libretroshare/src/retroshare/rsplugin.h +++ b/libretroshare/src/retroshare/rsplugin.h @@ -40,6 +40,7 @@ extern RsPluginHandler *rsPlugins ; class p3Service ; class RsServiceControl ; +class RsReputations ; class RsTurtle ; class RsGxsTunnelService ; class RsDht ; @@ -118,6 +119,7 @@ public: RsUtil::inited_ptr mGxsForums; RsUtil::inited_ptr mGxsChannels; RsUtil::inited_ptr mGxsTunnels; + RsUtil::inited_ptr mReputations; }; class RsPlugin diff --git a/libretroshare/src/retroshare/rsreputations.h b/libretroshare/src/retroshare/rsreputations.h new file mode 100644 index 000000000..807f45f40 --- /dev/null +++ b/libretroshare/src/retroshare/rsreputations.h @@ -0,0 +1,61 @@ +/* + * libretroshare/src/services: rsreputation.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 + +#include "retroshare/rsids.h" +#include "retroshare/rsgxsifacetypes.h" + +class RsReputations +{ +public: + static const float REPUTATION_THRESHOLD_ANTI_SPAM = 1.4f ; + static const float REPUTATION_THRESHOLD_DEFAULT = 1.0f ; + + // This is the interface file for the reputation system + // + enum Opinion { OPINION_NEGATIVE = 0, OPINION_NEUTRAL = 1, OPINION_POSITIVE = 2 } ; + enum Assessment { ASSESSMENT_BAD = 0, ASSESSMENT_OK = 1 } ; + + struct ReputationInfo + { + RsReputations::Opinion mOwnOpinion ; + float mOverallReputationScore ; + float mFriendAverage ; + RsReputations::Assessment mAssessment; // this should help clients in taking decisions + }; + + virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) =0; + virtual bool getReputationInfo(const RsGxsId& id,ReputationInfo& info) =0 ; + + // This one is a proxy designed to allow fast checking of a GXS id. + // it basically returns true if assessment is not ASSESSMENT_OK + + virtual bool isIdentityBanned(const RsGxsId& id) =0; +}; + +// To access reputations from anywhere +// +extern RsReputations *rsReputations ; diff --git a/libretroshare/src/rsserver/Makefile b/libretroshare/src/rsserver/Makefile deleted file mode 100644 index fae412965..000000000 --- a/libretroshare/src/rsserver/Makefile +++ /dev/null @@ -1,35 +0,0 @@ - -RS_TOP_DIR = .. -##### Define any flags that are needed for this section ####### -############################################################### - -############################################################### -include $(RS_TOP_DIR)/scripts/config.mk -############################################################### - -RSOBJ = rsinit.o \ - p3peers.o \ - p3rank.o \ - p3photo.o \ - p3msgs.o \ - p3blog.o \ - p3discovery.o \ - p3face-server.o \ - p3face-config.o \ - p3face-msgs.o \ - rsiface.o \ - rstypes.o - -#TESTOBJ = - -#TESTS = - -all: librs tests - -#tlvbase_test : tlvbase_test.o -# $(CC) $(CFLAGS) -o tlvbase_test tlvbase_test.o $(OBJ) $(LIBS) - -############################################################### -include $(RS_TOP_DIR)/scripts/rules.mk -############################################################### - diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 54819d40a..e980fb258 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -313,6 +313,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d) d.isHiddenNode = true; d.hiddenNodeAddress = ps.hiddenDomain; d.hiddenNodePort = ps.hiddenPort; + d.hiddenType = ps.hiddenType; d.localAddr = sockaddr_storage_iptostring(ps.localaddr); d.localPort = sockaddr_storage_port(ps.localaddr); d.extAddr = "hidden"; @@ -324,6 +325,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d) d.isHiddenNode = false; d.hiddenNodeAddress = ""; d.hiddenNodePort = 0; + d.hiddenType = RS_HIDDEN_TYPE_NONE; d.localAddr = sockaddr_storage_iptostring(ps.localaddr); d.localPort = sockaddr_storage_port(ps.localaddr); @@ -435,20 +437,79 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d) } else if (pcs.state & RS_PEER_S_CONNECTED) { - if(isProxyAddress(pcs.connectaddr) || mPeerMgr->isHidden()) - d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_TOR; - else if (pcs.connecttype == RS_NET_CONN_TCP_ALL) - { - d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_TCP; - } - else if (pcs.connecttype == RS_NET_CONN_UDP_ALL) - { - d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_UDP; - } - else - { - d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN; - } + /* peer is connected - determine how and set proper connectState */ + if(mPeerMgr->isHidden()) + { + uint32_t type; + /* hidden location */ + /* use connection direction to determine connection type */ + if(pcs.actAsServer) + { + /* incoming connection */ + /* use own type to set connectState */ + type = mPeerMgr->getHiddenType(AuthSSL::getAuthSSL()->OwnId()); + switch (type) { + case RS_HIDDEN_TYPE_TOR: + d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_TOR; + break; + case RS_HIDDEN_TYPE_I2P: + d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_I2P; + break; + default: + d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN; + break; + } + } + else + { + /* outgoing connection */ + /* use peer hidden type to set connectState */ + switch (ps.hiddenType) { + case RS_HIDDEN_TYPE_TOR: + d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_TOR; + break; + case RS_HIDDEN_TYPE_I2P: + d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_I2P; + break; + default: + d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN; + break; + } + } + } + else if (ps.hiddenType & RS_HIDDEN_TYPE_MASK) + { + /* hidden peer */ + /* use hidden type to set connectState */ + switch (ps.hiddenType) { + case RS_HIDDEN_TYPE_TOR: + d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_TOR; + break; + case RS_HIDDEN_TYPE_I2P: + d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_I2P; + break; + default: + d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN; + break; + } + } + else + { + /* peer and we are normal nodes */ + /* use normal detection to set connectState */ + if (pcs.connecttype == RS_NET_CONN_TCP_ALL) + { + d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_TCP; + } + else if (pcs.connecttype == RS_NET_CONN_UDP_ALL) + { + d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_UDP; + } + else + { + d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN; + } + } } d.wasDeniedConnection = pcs.wasDeniedConnection; @@ -457,13 +518,13 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d) return true; } -bool p3Peers::isProxyAddress(const sockaddr_storage& addr) +bool p3Peers::isProxyAddress(const uint32_t type, const sockaddr_storage& addr) { uint16_t port ; std::string string_addr; - uint32_t status ; + uint32_t status ; - if(!getProxyServer(string_addr, port, status)) + if(!getProxyServer(type, string_addr, port, status)) return false ; return sockaddr_storage_iptostring(addr)==string_addr && sockaddr_storage_port(addr)==port ; @@ -923,21 +984,21 @@ bool p3Peers::setVisState(const RsPeerId &id, uint16_t vs_disc, uint16_t vs_dht) return mPeerMgr->setVisState(id, vs_disc, vs_dht); } -bool p3Peers::getProxyServer(std::string &addr, uint16_t &port, uint32_t &status) +bool p3Peers::getProxyServer(const uint32_t type, std::string &addr, uint16_t &port, uint32_t &status) { #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::getProxyServer()" << std::endl; #endif struct sockaddr_storage proxy_addr; - mPeerMgr->getProxyServerAddress(proxy_addr); + mPeerMgr->getProxyServerAddress(type, proxy_addr); addr = sockaddr_storage_iptostring(proxy_addr); port = sockaddr_storage_port(proxy_addr); - mPeerMgr->getProxyServerStatus(status); + mPeerMgr->getProxyServerStatus(type, status); return true; } -bool p3Peers::setProxyServer(const std::string &addr_str, const uint16_t port) +bool p3Peers::setProxyServer(const uint32_t type, const std::string &addr_str, const uint16_t port) { #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::setProxyServer() " << std::endl; @@ -958,7 +1019,7 @@ bool p3Peers::setProxyServer(const std::string &addr_str, const uint16_t port) #endif /********************************** WINDOWS/UNIX SPECIFIC PART *******************/ { - return mPeerMgr->setProxyServerAddress(addr); + return mPeerMgr->setProxyServerAddress(type, addr); } else { @@ -1017,7 +1078,7 @@ bool p3Peers::GetPGPBase64StringAndCheckSum( const RsPgpId& gpg_id, uint32_t crc = PGPKeyManagement::compute24bitsCRC((unsigned char *)mem_block,mem_block_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) } ; Radix64::encode((const char *)tmp,3,gpg_base64_checksum) ; delete[] mem_block ; @@ -1107,6 +1168,7 @@ bool p3Peers::loadDetailsFromStringCert(const std::string &certstr, RsPeerDetai { pd.hiddenNodeAddress = domain; pd.hiddenNodePort = port; + pd.hiddenType = mPeerMgr->hiddenDomainToHiddenType(domain); } } else @@ -1311,7 +1373,7 @@ RsPeerDetails::RsPeerDetails() hasSignedMe(false),accept_connection(false), state(0),localAddr(""),localPort(0),extAddr(""),extPort(0),netMode(0),vs_disc(0), vs_dht(0), lastConnect(0),connectState(0),connectStateString(""),connectPeriod(0),foundDHT(false), - wasDeniedConnection(false), deniedTS(0) + wasDeniedConnection(false), deniedTS(0), hiddenType(RS_HIDDEN_TYPE_NONE) { } diff --git a/libretroshare/src/rsserver/p3peers.h b/libretroshare/src/rsserver/p3peers.h index 66540003e..3f4fb8763 100644 --- a/libretroshare/src/rsserver/p3peers.h +++ b/libretroshare/src/rsserver/p3peers.h @@ -94,9 +94,9 @@ virtual bool setDynDNS(const RsPeerId &id, const std::string &dyndns); virtual bool setNetworkMode(const RsPeerId &id, uint32_t netMode); virtual bool setVisState(const RsPeerId &id, uint16_t vs_disc, uint16_t vs_dht); -virtual bool getProxyServer(std::string &addr, uint16_t &port,uint32_t& status); -virtual bool setProxyServer(const std::string &addr, const uint16_t port); -virtual bool isProxyAddress(const sockaddr_storage&); +virtual bool getProxyServer(const uint32_t type, std::string &addr, uint16_t &port,uint32_t& status); +virtual bool setProxyServer(const uint32_t type,const std::string &addr, const uint16_t port); +virtual bool isProxyAddress(const uint32_t type,const sockaddr_storage&); virtual void getIPServersList(std::list& ip_servers) ; virtual void allowServerIPDetermination(bool) ; diff --git a/libretroshare/src/rsserver/rsaccounts.cc b/libretroshare/src/rsserver/rsaccounts.cc index f63dfce2e..f5f5d7002 100644 --- a/libretroshare/src/rsserver/rsaccounts.cc +++ b/libretroshare/src/rsserver/rsaccounts.cc @@ -994,7 +994,7 @@ bool RsAccountsDetail::GenerateSSLCertificate(const RsPgpId& pgp_id, const s return false; } - int nbits = 2048; + int nbits = 4096; std::string pgp_name = AuthGPG::getAuthGPG()->getGPGName(pgp_id); diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 6422bc1f4..129054fea 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -367,7 +367,11 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck #ifdef LOCALNET_TESTING >> parameter('R',"restrict-port" ,portRestrictions ,"port1-port2","Apply port restriction" ,false) #endif +#ifdef __APPLE__ + >> help('h',"help","Display this Help") ; +#else >> help() ; +#endif as.defaultErrorHandling(true) ; @@ -821,6 +825,7 @@ bool RsInit::SetHiddenLocation(const std::string& hiddenaddress, uint16_t port) RsFiles *rsFiles = NULL; RsTurtle *rsTurtle = NULL ; +RsReputations *rsReputations = NULL ; #ifdef ENABLE_GROUTER RsGRouter *rsGRouter = NULL ; #endif @@ -849,6 +854,7 @@ RsGRouter *rsGRouter = NULL ; #endif #endif +#include "services/p3gxsreputation.h" #include "services/p3serviceinfo.h" #include "services/p3heartbeat.h" #include "services/p3discovery2.h" @@ -1253,7 +1259,7 @@ int RsServer::StartupRetroShare() std::vector plugins_directories ; #ifndef WINDOWS_SYS - plugins_directories.push_back(std::string(LIB_DIR) + "/retroshare/extensions6/") ; + plugins_directories.push_back(std::string(PLUGIN_DIR)) ; #endif std::string extensions_dir = rsAccounts->PathBaseDirectory() + "/extensions6/" ; plugins_directories.push_back(extensions_dir) ; @@ -1359,6 +1365,11 @@ int RsServer::StartupRetroShare() mPosted->setNetworkExchangeService(posted_ns) ; + /**** Reputation system ****/ + + p3GxsReputation *mReputations = new p3GxsReputation(mLinkMgr) ; + rsReputations = mReputations ; + /**** Wiki GXS service ****/ @@ -1366,9 +1377,9 @@ int RsServer::StartupRetroShare() RS_SERVICE_GXS_TYPE_WIKI, NULL, rsInitConfig->gxs_passwd); +#ifdef RS_USE_WIKI p3Wiki *mWiki = new p3Wiki(wiki_ds, NULL, mGxsIdService); - - // create GXS photo service + // create GXS wiki service RsGxsNetService* wiki_ns = new RsGxsNetService( RS_SERVICE_GXS_TYPE_WIKI, wiki_ds, nxsMgr, mWiki, mWiki->getServiceInfo(), @@ -1376,6 +1387,7 @@ int RsServer::StartupRetroShare() pgpAuxUtils); mWiki->setNetworkExchangeService(wiki_ns) ; +#endif /**** Forum GXS service ****/ @@ -1445,7 +1457,9 @@ int RsServer::StartupRetroShare() pqih->addService(gxsid_ns, true); pqih->addService(gxscircles_ns, true); pqih->addService(posted_ns, true); +#ifdef RS_USE_WIKI pqih->addService(wiki_ns, true); +#endif pqih->addService(gxsforums_ns, true); pqih->addService(gxschannels_ns, true); //pqih->addService(photo_ns, true); @@ -1497,6 +1511,7 @@ int RsServer::StartupRetroShare() pqih -> addService(chatSrv,true); pqih -> addService(mStatusSrv,true); pqih -> addService(mGxsTunnels,true); + pqih -> addService(mReputations,true); // set interfaces for plugins // @@ -1518,6 +1533,7 @@ int RsServer::StartupRetroShare() interfaces.mGxsForums = mGxsForums; interfaces.mGxsChannels = mGxsChannels; interfaces.mGxsTunnels = mGxsTunnels; + interfaces.mReputations = mReputations; mPluginsManager->setInterfaces(interfaces); @@ -1606,12 +1622,13 @@ int RsServer::StartupRetroShare() mConfigMgr->addConfiguration("peers.cfg", mPeerMgr); mConfigMgr->addConfiguration("general.cfg", mGeneralConfig); mConfigMgr->addConfiguration("msgs.cfg", msgSrv); - mConfigMgr->addConfiguration("chat.cfg", chatSrv); - mConfigMgr->addConfiguration("p3History.cfg", mHistoryMgr); - mConfigMgr->addConfiguration("p3Status.cfg", mStatusSrv); - mConfigMgr->addConfiguration("turtle.cfg", tr); - mConfigMgr->addConfiguration("banlist.cfg", mBanList); - mConfigMgr->addConfiguration("servicecontrol.cfg", serviceCtrl); + mConfigMgr->addConfiguration("chat.cfg", chatSrv); + mConfigMgr->addConfiguration("p3History.cfg", mHistoryMgr); + mConfigMgr->addConfiguration("p3Status.cfg", mStatusSrv); + mConfigMgr->addConfiguration("turtle.cfg", tr); + mConfigMgr->addConfiguration("banlist.cfg", mBanList); + mConfigMgr->addConfiguration("servicecontrol.cfg", serviceCtrl); + mConfigMgr->addConfiguration("reputations.cfg", mReputations); #ifdef ENABLE_GROUTER mConfigMgr->addConfiguration("grouter.cfg", gr); #endif @@ -1627,7 +1644,9 @@ int RsServer::StartupRetroShare() mConfigMgr->addConfiguration("gxschannels.cfg", gxschannels_ns); mConfigMgr->addConfiguration("gxscircles.cfg", gxscircles_ns); mConfigMgr->addConfiguration("posted.cfg", posted_ns); +#ifdef RS_USE_WIKI mConfigMgr->addConfiguration("wiki.cfg", wiki_ns); +#endif //mConfigMgr->addConfiguration("photo.cfg", photo_ns); //mConfigMgr->addConfiguration("wire.cfg", wire_ns); #endif @@ -1736,7 +1755,9 @@ int RsServer::StartupRetroShare() // Must Set the GXS pointers before starting threads. rsIdentity = mGxsIdService; rsGxsCircles = mGxsCircles; +#if RS_USE_WIKI rsWiki = mWiki; +#endif rsPosted = mPosted; rsGxsForums = mGxsForums; rsGxsChannels = mGxsChannels; @@ -1747,7 +1768,9 @@ int RsServer::StartupRetroShare() startServiceThread(mGxsIdService); startServiceThread(mGxsCircles); startServiceThread(mPosted); +#if RS_USE_WIKI startServiceThread(mWiki); +#endif startServiceThread(mGxsForums); startServiceThread(mGxsChannels); @@ -1758,7 +1781,9 @@ int RsServer::StartupRetroShare() startServiceThread(gxsid_ns); startServiceThread(gxscircles_ns); startServiceThread(posted_ns); +#if RS_USE_WIKI startServiceThread(wiki_ns); +#endif startServiceThread(gxsforums_ns); startServiceThread(gxschannels_ns); diff --git a/libretroshare/src/rsserver/rsloginhandler.cc b/libretroshare/src/rsserver/rsloginhandler.cc index b8b9a66fd..4236709d7 100644 --- a/libretroshare/src/rsserver/rsloginhandler.cc +++ b/libretroshare/src/rsserver/rsloginhandler.cc @@ -4,7 +4,6 @@ #include "rsloginhandler.h" #include "util/rsdir.h" #include "rsaccounts.h" - #if defined(UBUNTU) || defined(__FreeBSD__) || defined(__OpenBSD__) #include @@ -118,6 +117,7 @@ bool RsLoginHandler::tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd std::cerr << "RsTryAutoLogin()" << std::endl; /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ +#ifndef __HAIKU__ #ifndef WINDOWS_SYS /* UNIX */ #if defined(UBUNTU) || defined(__FreeBSD__) || defined(__OpenBSD__) @@ -145,8 +145,9 @@ bool RsLoginHandler::tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd void *passwordData = NULL; UInt32 passwordLength = 0; - const char *userId = ssl_id.c_str(); - UInt32 uidLength = strlen(ssl_id.c_str()); + std::string idtemp = ssl_id.toStdString(); + const char *userId = idtemp.c_str(); + UInt32 uidLength = strlen(userId); SecKeychainItemRef itemRef = NULL; OSStatus status = SecKeychainFindGenericPassword ( @@ -348,6 +349,7 @@ bool RsLoginHandler::tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd LocalFree(DataOut.pbData); return isDecrypt; +#endif #endif /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ @@ -360,6 +362,7 @@ bool RsLoginHandler::enableAutoLogin(const RsPeerId& ssl_id,const std::string& s std::cerr << "RsStoreAutoLogin()" << std::endl; /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ +#ifndef __HAIKU__ #ifndef WINDOWS_SYS /* UNIX */ #if defined(UBUNTU) || defined(__FreeBSD__) || defined(__OpenBSD__) if(GNOME_KEYRING_RESULT_OK == gnome_keyring_store_password_sync(&my_schema, NULL, (gchar*)("RetroShare password for SSL Id "+ssl_id.toStdString()).c_str(),(gchar*)ssl_passwd.c_str(),"RetroShare SSL Id",ssl_id.toStdString().c_str(),NULL)) @@ -381,8 +384,9 @@ bool RsLoginHandler::enableAutoLogin(const RsPeerId& ssl_id,const std::string& s const void *password = ssl_passwd.c_str(); UInt32 passwordLength = strlen(ssl_passwd.c_str()); - const char *userid = ssl_id.c_str(); - UInt32 uidLength = strlen(ssl_id.c_str()); + std::string idtemp = ssl_id.toStdString(); + const char *userid = idtemp.c_str(); + UInt32 uidLength = strlen(userid); OSStatus status = SecKeychainAddGenericPassword ( NULL, // default keychain @@ -517,6 +521,7 @@ bool RsLoginHandler::enableAutoLogin(const RsPeerId& ssl_id,const std::string& s /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ return false; +#endif } bool RsLoginHandler::clearAutoLogin(const RsPeerId& ssl_id) @@ -540,8 +545,9 @@ bool RsLoginHandler::clearAutoLogin(const RsPeerId& ssl_id) void *passwordData = NULL; UInt32 passwordLength = 0; - const char *userId = ssl_id.c_str(); - UInt32 uidLength = strlen(ssl_id.c_str()); + std::string idtemp = ssl_id.toStdString(); + const char *userId = idtemp.c_str(); + UInt32 uidLength = strlen(userId); SecKeychainItemRef itemRef = NULL; OSStatus status = SecKeychainFindGenericPassword ( diff --git a/libretroshare/src/serialiser/rsgxsitems.cc b/libretroshare/src/serialiser/rsgxsitems.cc index 2fc738cab..9971514ec 100644 --- a/libretroshare/src/serialiser/rsgxsitems.cc +++ b/libretroshare/src/serialiser/rsgxsitems.cc @@ -24,7 +24,6 @@ this->mPublishTs = rGxsMeta.mPublishTs; this->mThreadId = rGxsMeta.mThreadId; this->mServiceString = rGxsMeta.mServiceString; - } diff --git a/libretroshare/src/serialiser/rsgxsreputationitems.cc b/libretroshare/src/serialiser/rsgxsreputationitems.cc index 7b56d4675..379cf4330 100644 --- a/libretroshare/src/serialiser/rsgxsreputationitems.cc +++ b/libretroshare/src/serialiser/rsgxsreputationitems.cc @@ -23,9 +23,10 @@ * */ +#include +#include #include "serialiser/rsbaseserial.h" -#include "serialiser/rsbanlistitems.h" -#include "serialiser/rstlvbanlist.h" +#include "serialiser/rsgxsreputationitems.h" /*** #define RSSERIAL_DEBUG 1 @@ -33,172 +34,444 @@ #include +// re-defined here, in order to avoid cross-includes +#define REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE 0x0100 + /*************************************************************************/ -#ifdef SUSPENDED -RsBanListItem::~RsBanListItem() +bool RsReputationItem::serialise_header(void *data,uint32_t& pktsize,uint32_t& tlvsize, uint32_t& offset) const { - return; + tlvsize = serial_size() ; + offset = 0; + + if (pktsize < tlvsize) + return false; /* not enough space */ + + pktsize = tlvsize; + + if(!setRsItemHeader(data, tlvsize, PacketId(), tlvsize)) + { + std::cerr << "RsReputationItem::serialise_header(): ERROR. Not enough size!" << std::endl; + return false ; + } +#ifdef RSSERIAL_DEBUG + std::cerr << "RsReputationItem::serialise() Header: " << ok << std::endl; +#endif + offset += 8; + + return true ; } -void RsBanListItem::clear() +/*************************************************************************/ + +void RsGxsReputationSetItem::clear() { - peerList.TlvClear(); + mOpinions.clear() ; } -std::ostream &RsBanListItem::print(std::ostream &out, uint16_t indent) +void RsGxsReputationUpdateItem::clear() { - printRsItemBase(out, "RsBanListItem", indent); + mOpinions.clear() ; +} + +/*************************************************************************/ +/*************************************************************************/ +/*************************************************************************/ + +std::ostream& RsGxsReputationConfigItem::print(std::ostream &out, uint16_t indent) +{ + printRsItemBase(out, "RsReputationConfigItem", indent); uint16_t int_Indent = indent + 2; - peerList.print(out, int_Indent); - printRsItemEnd(out, "RsBanListItem", indent); + out << "mPeerId: " << mPeerId << std::endl; + out << "last update: " << time(NULL) - mLatestUpdate << " secs ago." << std::endl; + out << "last query : " << time(NULL) - mLastQuery << " secs ago." << std::endl; + + printRsItemEnd(out, "RsReputationConfigItem", indent); return out; } +std::ostream& RsGxsReputationSetItem::print(std::ostream &out, uint16_t indent) +{ + printRsItemBase(out, "RsReputationSetItem", indent); + uint16_t int_Indent = indent + 2; -uint32_t RsBanListSerialiser::sizeList(RsBanListItem *item) + out << "GxsId: " << mGxsId << std::endl; + out << "mOwnOpinion: " << mOwnOpinion << std::endl; + out << "mOwnOpinionTS : " << time(NULL) - mOwnOpinionTS << " secs ago." << std::endl; + out << "Opinions from neighbors: " << std::endl; + + for(std::map::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it) + out << " " << it->first << ": " << it->second << std::endl; + + printRsItemEnd(out, "RsReputationSetItem", indent); + return out; +} +std::ostream& RsGxsReputationUpdateItem::print(std::ostream &out, uint16_t indent) +{ + printRsItemBase(out, "RsReputationUpdateItem", indent); + uint16_t int_Indent = indent + 2; + + out << "from: " << PeerId() << std::endl; + out << "last update: " << time(NULL) - mLatestUpdate << " secs ago." << std::endl; + + for(std::map::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it) + out << " " << it->first << ": " << it->second << std::endl; + + printRsItemEnd(out, "RsReputationUpdateItem", indent); + return out; +} +std::ostream& RsGxsReputationRequestItem::print(std::ostream &out, uint16_t indent) +{ + printRsItemBase(out, "RsReputationRequestItem", indent); + uint16_t int_Indent = indent + 2; + + out << "last update: " << time(NULL) - mLastUpdate << " secs ago." << std::endl; + + printRsItemEnd(out, "RsReputationRequestItem", indent); + return out; +} +/*************************************************************************/ + +uint32_t RsGxsReputationConfigItem::serial_size() const +{ + uint32_t s = 8; /* header */ + + s += mPeerId.serial_size() ; // PeerId + s += 4 ; // mLatestUpdate + s += 4 ; // mLastQuery + + return s ; +} + +uint32_t RsGxsReputationSetItem::serial_size() const { uint32_t s = 8; /* header */ - s += item->peerList.TlvSize(); + + s += mGxsId.serial_size() ; + s += 4 ; // mOwnOpinion + s += 4 ; // mOwnOpinionTS + s += 4 ; // mIdentityFlags + + s += 4 ; // mOpinions.size() + + s += (4+RsPeerId::serial_size()) * mOpinions.size() ; + + return s ; +} + +uint32_t RsGxsReputationUpdateItem::serial_size() const +{ + uint32_t s = 8; /* header */ + + s += 4 ; // mLatestUpdate + s += 4 ; // mOpinions.size(); + + s += (RsGxsId::serial_size() + 4) * mOpinions.size() ; + + return s ; +} + +uint32_t RsGxsReputationRequestItem::serial_size() const +{ + uint32_t s = 8; /* header */ + + s += 4 ; // mLastUpdate return s; } -/* serialise the data to the buffer */ -bool RsBanListSerialiser::serialiseList(RsBanListItem *item, void *data, uint32_t *pktsize) +/*************************************************************************/ + +bool RsGxsReputationConfigItem::serialise(void *data, uint32_t& pktsize) const { - uint32_t tlvsize = sizeList(item); - uint32_t offset = 0; + uint32_t tlvsize ; + uint32_t offset=0; - if (*pktsize < tlvsize) - return false; /* not enough space */ - - *pktsize = tlvsize; + if(!serialise_header(data,pktsize,tlvsize,offset)) + return false ; bool ok = true; - - ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); - -#ifdef RSSERIAL_DEBUG - std::cerr << "RsDsdvSerialiser::serialiseRoute() Header: " << ok << std::endl; - std::cerr << "RsDsdvSerialiser::serialiseRoute() Size: " << tlvsize << std::endl; -#endif - - /* skip the header */ - offset += 8; - - /* add mandatory parts first */ - ok &= item->peerList.SetTlv(data, tlvsize, &offset); + + ok &= mPeerId.serialise(data,tlvsize,offset) ; + ok &= setRawUInt32(data, tlvsize, &offset, mLatestUpdate); + ok &= setRawUInt32(data, tlvsize, &offset, mLastQuery); if (offset != tlvsize) { ok = false; -#ifdef RSSERIAL_DEBUG - std::cerr << "RsDsdvSerialiser::serialiseRoute() Size Error! " << std::endl; -#endif + std::cerr << "RsGxsReputationConfigItem::serialisedata() size error! " << std::endl; } return ok; } -RsBanListItem *RsBanListSerialiser::deserialiseList(void *data, uint32_t *pktsize) +bool RsGxsReputationSetItem::serialise(void *data, uint32_t& pktsize) const { - /* get the type and size */ - uint32_t rstype = getRsItemId(data); - uint32_t tlvsize = getRsItemSize(data); + uint32_t tlvsize ; + uint32_t offset=0; - uint32_t offset = 0; - - - if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_BANLIST != getRsItemService(rstype)) || - (RS_PKT_SUBTYPE_BANLIST_ITEM != getRsItemSubType(rstype))) - { - return NULL; /* wrong type */ - } - - if (*pktsize < tlvsize) /* check size */ - return NULL; /* not enough data */ - - /* set the packet length */ - *pktsize = tlvsize; + if(!serialise_header(data,pktsize,tlvsize,offset)) + return false ; bool ok = true; - - /* ready to load */ - RsBanListItem *item = new RsBanListItem(); - item->clear(); - - /* skip the header */ - offset += 8; - - /* add mandatory parts first */ - ok &= item->peerList.GetTlv(data, tlvsize, &offset); + + ok &= mGxsId.serialise(data,tlvsize,offset) ; + ok &= setRawUInt32(data, tlvsize, &offset, mOwnOpinion); + ok &= setRawUInt32(data, tlvsize, &offset, mOwnOpinionTS); + ok &= setRawUInt32(data, tlvsize, &offset, mIdentityFlags) ; + ok &= setRawUInt32(data, tlvsize, &offset, mOpinions.size()); + + for(std::map::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it) + { + ok &= it->first.serialise(data,tlvsize,offset) ; + ok &= setRawUInt32(data, tlvsize, &offset, it->second) ; + } if (offset != tlvsize) { - /* error */ - delete item; - return NULL; + ok = false; + std::cerr << "RsGxsReputationSetItem::serialisedata() size error! " << std::endl; } - if (!ok) - { - delete item; - return NULL; - } - - return item; + return ok; } +bool RsGxsReputationUpdateItem::serialise(void *data, uint32_t& pktsize) const +{ + uint32_t tlvsize ; + uint32_t offset=0; + if(!serialise_header(data,pktsize,tlvsize,offset)) + return false ; + + bool ok = true; + + ok &= setRawUInt32(data, tlvsize, &offset, mLatestUpdate); + ok &= setRawUInt32(data, tlvsize, &offset, mOpinions.size()); + + for(std::map::const_iterator it(mOpinions.begin());ok && it!=mOpinions.end();++it) + { + ok &= it->first.serialise(data, tlvsize, offset) ; + ok &= setRawUInt32(data, tlvsize, &offset, it->second) ; + } + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsGxsReputationUpdateItem::serialisedata() size error! " << std::endl; + } + + return ok; +} +/* serialise the data to the buffer */ +bool RsGxsReputationRequestItem::serialise(void *data, uint32_t& pktsize) const +{ + uint32_t tlvsize ; + uint32_t offset=0; + + if(!serialise_header(data,pktsize,tlvsize,offset)) + return false ; + + bool ok = true; + + ok &= setRawUInt32(data, tlvsize, &offset, mLastUpdate); + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsGxsReputationRequestItem::serialisedata() size error! " << std::endl; + } + + return ok; +} /*************************************************************************/ -uint32_t RsBanListSerialiser::size(RsItem *i) +RsGxsReputationConfigItem *RsGxsReputationSerialiser::deserialiseReputationConfigItem(void *data,uint32_t size) { - RsBanListItem *dri; + uint32_t offset = 8; // skip the header + uint32_t rssize = getRsItemSize(data); + bool ok = true ; - if (NULL != (dri = dynamic_cast(i))) - { - return sizeList(dri); - } - return 0; + RsGxsReputationConfigItem *item = new RsGxsReputationConfigItem() ; + + /* add mandatory parts first */ + ok &= item->mPeerId.deserialise(data, size, offset) ; + ok &= getRawUInt32(data, size, &offset, &item->mLatestUpdate); + ok &= getRawUInt32(data, size, &offset, &item->mLastQuery); + + if (offset != rssize || !ok) + { + std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl; + delete item; + return NULL ; + } + + return item; } -bool RsBanListSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize) +RsGxsReputationSetItem *RsGxsReputationSerialiser::deserialiseReputationSetItem_deprecated(void *data,uint32_t tlvsize) { - RsBanListItem *dri; + uint32_t offset = 8; // skip the header + uint32_t rssize = getRsItemSize(data); + bool ok = true ; - if (NULL != (dri = dynamic_cast(i))) - { - return serialiseList(dri, data, pktsize); - } - return false; + RsGxsReputationSetItem *item = new RsGxsReputationSetItem() ; + + /* add mandatory parts first */ + ok &= item->mGxsId.deserialise(data, tlvsize, offset) ; + ok &= getRawUInt32(data, tlvsize, &offset, &item->mOwnOpinion); + ok &= getRawUInt32(data, tlvsize, &offset, &item->mOwnOpinionTS); + + item->mIdentityFlags = REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE; // special value that means please update me. + + uint32_t S ; + ok &= getRawUInt32(data, tlvsize, &offset, &S); + + for(int i=0;ok && imOpinions[pid] = op ; + } + + if (offset != rssize || !ok) + { + std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl; + delete item; + return NULL ; + } + + return item; +} +RsGxsReputationSetItem *RsGxsReputationSerialiser::deserialiseReputationSetItem(void *data,uint32_t tlvsize) +{ + uint32_t offset = 8; // skip the header + uint32_t rssize = getRsItemSize(data); + bool ok = true ; + + RsGxsReputationSetItem *item = new RsGxsReputationSetItem() ; + + /* add mandatory parts first */ + ok &= item->mGxsId.deserialise(data, tlvsize, offset) ; + ok &= getRawUInt32(data, tlvsize, &offset, &item->mOwnOpinion); + ok &= getRawUInt32(data, tlvsize, &offset, &item->mOwnOpinionTS); + ok &= getRawUInt32(data, tlvsize, &offset, &item->mIdentityFlags); + + uint32_t S ; + ok &= getRawUInt32(data, tlvsize, &offset, &S); + + for(int i=0;ok && imOpinions[pid] = op ; + } + + if (offset != rssize || !ok) + { + std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl; + delete item; + return NULL ; + } + + return item; } -RsItem *RsBanListSerialiser::deserialise(void *data, uint32_t *pktsize) +RsGxsReputationUpdateItem *RsGxsReputationSerialiser::deserialiseReputationUpdateItem(void *data,uint32_t tlvsize) +{ + uint32_t offset = 8; // skip the header + uint32_t rssize = getRsItemSize(data); + bool ok = true ; + + RsGxsReputationUpdateItem *item = new RsGxsReputationUpdateItem() ; + + /* add mandatory parts first */ + ok &= getRawUInt32(data, tlvsize, &offset, &item->mLatestUpdate); + + uint32_t S ; + ok &= getRawUInt32(data, tlvsize, &offset, &S) ; + + for(uint32_t i=0;ok && imOpinions[gid] = op ; + + } + + if (offset != rssize || !ok) + { + std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl; + delete item; + return NULL ; + } + + return item; +} + +RsGxsReputationRequestItem *RsGxsReputationSerialiser::deserialiseReputationRequestItem(void *data,uint32_t tlvsize) +{ + uint32_t offset = 8; // skip the header + uint32_t rssize = getRsItemSize(data); + bool ok = true ; + + RsGxsReputationRequestItem *item = new RsGxsReputationRequestItem() ; + + /* add mandatory parts first */ + ok &= getRawUInt32(data, tlvsize, &offset, &item->mLastUpdate); + + if (offset != rssize || !ok) + { + std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl; + delete item; + return NULL ; + } + + return item; +} +/*************************************************************************/ + +RsItem *RsGxsReputationSerialiser::deserialise(void *data, uint32_t *pktsize) { /* get the type and size */ uint32_t rstype = getRsItemId(data); - if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_BANLIST != getRsItemService(rstype))) - { - return NULL; /* wrong type */ - } + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_GXS_TYPE_REPUTATION != getRsItemService(rstype))) + { + std::cerr << "RsReputationSerialiser::deserialise(): wrong item type " << std::hex << rstype << std::dec << std::endl; + return NULL; /* wrong type */ + } switch(getRsItemSubType(rstype)) { - case RS_PKT_SUBTYPE_BANLIST_ITEM: - return deserialiseList(data, pktsize); - break; + case RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM : return deserialiseReputationSetItem (data, *pktsize); + case RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM_deprecated: return deserialiseReputationSetItem_deprecated(data, *pktsize); + case RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM : return deserialiseReputationUpdateItem (data, *pktsize); + case RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM : return deserialiseReputationRequestItem (data, *pktsize); + case RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM : return deserialiseReputationConfigItem (data, *pktsize); + default: + std::cerr << "RsGxsReputationSerialiser::deserialise(): unknown item subtype " << std::hex<< rstype << std::dec << std::endl; return NULL; break; } } -#endif /*************************************************************************/ diff --git a/libretroshare/src/serialiser/rsgxsreputationitems.h b/libretroshare/src/serialiser/rsgxsreputationitems.h index b238217c9..84dcecdc9 100644 --- a/libretroshare/src/serialiser/rsgxsreputationitems.h +++ b/libretroshare/src/serialiser/rsgxsreputationitems.h @@ -32,88 +32,96 @@ #include "serialiser/rsserial.h" #include "retroshare/rsgxsifacetypes.h" -#define RS_PKT_SUBTYPE_GXSREPUTATION_CONFIG_ITEM 0x01 -#define RS_PKT_SUBTYPE_GXSREPUTATION_SET_ITEM 0x02 -#define RS_PKT_SUBTYPE_GXSREPUTATION_UPDATE_ITEM 0x03 -#define RS_PKT_SUBTYPE_GXSREPUTATION_REQUEST_ITEM 0x04 +#define RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM 0x01 +#define RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM_deprecated 0x02 +#define RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM 0x03 +#define RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM 0x04 +#define RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM 0x05 /**************************************************************************/ - -class RsGxsReputationConfigItem: public RsItem +class RsReputationItem: public RsItem { public: - RsGxsReputationConfigItem() - :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION, - RS_PKT_SUBTYPE_GXSREPUTATION_CONFIG_ITEM) - { - setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM); - return; - } + RsReputationItem(uint8_t reputation_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_REPUTATION,reputation_subtype) + { + setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM); + } -virtual ~RsGxsReputationConfigItem(); -virtual void clear(); -std::ostream &print(std::ostream &out, uint16_t indent = 0); + virtual ~RsReputationItem() {} - std::string mPeerId; + virtual bool serialise(void *data,uint32_t& size) const = 0 ; + virtual uint32_t serial_size() const = 0 ; + + virtual void clear() = 0 ; + virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) = 0; + + protected: + bool serialise_header(void *data, uint32_t& pktsize, uint32_t& tlvsize, uint32_t& offset) const; +}; + +class RsGxsReputationConfigItem: public RsReputationItem +{ +public: + RsGxsReputationConfigItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM) {} + + virtual ~RsGxsReputationConfigItem() {} + virtual void clear() {} + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + virtual bool serialise(void *data,uint32_t& size) const ; + virtual uint32_t serial_size() const ; + + RsPeerId mPeerId; uint32_t mLatestUpdate; // timestamp they returned. uint32_t mLastQuery; // when we sent out. }; -class RsGxsReputationSetItem: public RsItem +class RsGxsReputationSetItem: public RsReputationItem { - public: - RsGxsReputationSetItem() - :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION, - RS_PKT_SUBTYPE_GXSREPUTATION_SET_ITEM) - { - setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM); - return; - } +public: + RsGxsReputationSetItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM) {} -virtual ~RsGxsReputationSetItem(); -virtual void clear(); -std::ostream &print(std::ostream &out, uint16_t indent = 0); + virtual ~RsGxsReputationSetItem() {} + virtual void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); - std::string mGxsId; + virtual bool serialise(void *data,uint32_t& size) const ; + virtual uint32_t serial_size() const ; + + RsGxsId mGxsId; uint32_t mOwnOpinion; - uint32_t mOwnOpinionTs; - uint32_t mReputation; - std::map mOpinions; // RsPeerId -> Opinion. + uint32_t mOwnOpinionTS; + uint32_t mIdentityFlags ; + std::map mOpinions; // RsPeerId -> Opinion. }; -class RsGxsReputationUpdateItem: public RsItem +class RsGxsReputationUpdateItem: public RsReputationItem { - public: - RsGxsReputationUpdateItem() - :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION, - RS_PKT_SUBTYPE_GXSREPUTATION_UPDATE_ITEM) - { - setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM); - return; - } +public: + RsGxsReputationUpdateItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM) {} -virtual ~RsGxsReputationUpdateItem(); -virtual void clear(); -std::ostream &print(std::ostream &out, uint16_t indent = 0); + virtual ~RsGxsReputationUpdateItem() {} + virtual void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); - std::map mOpinions; // GxsId -> Opinion. - uint32_t mLatestUpdate; + virtual bool serialise(void *data,uint32_t& size) const ; + virtual uint32_t serial_size() const ; + + uint32_t mLatestUpdate; + std::map mOpinions; // GxsId -> Opinion. }; -class RsGxsReputationRequestItem: public RsItem +class RsGxsReputationRequestItem: public RsReputationItem { - public: - RsGxsReputationRequestItem() - :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION, - RS_PKT_SUBTYPE_GXSREPUTATION_REQUEST_ITEM) - { - setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM); - return; - } +public: + RsGxsReputationRequestItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM) {} -virtual ~RsGxsReputationRequestItem(); -virtual void clear(); -std::ostream &print(std::ostream &out, uint16_t indent = 0); + virtual ~RsGxsReputationRequestItem() {} + virtual void clear() {} + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + virtual bool serialise(void *data,uint32_t& size) const ; + virtual uint32_t serial_size() const ; uint32_t mLastUpdate; }; @@ -121,39 +129,27 @@ std::ostream &print(std::ostream &out, uint16_t indent = 0); class RsGxsReputationSerialiser: public RsSerialType { - public: - RsGxsReputationSerialiser() - :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION) - { return; } -virtual ~RsGxsReputationSerialiser() - { return; } - -virtual uint32_t size(RsItem *); -virtual bool serialise (RsItem *item, void *data, uint32_t *size); -virtual RsItem * deserialise(void *data, uint32_t *size); +public: + RsGxsReputationSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION){} - private: - -virtual uint32_t sizeConfig(RsGxsReputationConfigItem *); -virtual bool serialiseConfig(RsGxsReputationConfigItem *item, void *data, uint32_t *size); -virtual RsGxsReputationConfigItem *deserialiseConfig(void *data, uint32_t *size); - - -virtual uint32_t sizeSet(RsGxsReputationSetItem *); -virtual bool serialiseSet(RsGxsReputationSetItem *item, void *data, uint32_t *size); -virtual RsGxsReputationSetItem *deserialiseSet(void *data, uint32_t *size); - - -virtual uint32_t sizeUpdate(RsGxsReputationUpdateItem *); -virtual bool serialiseUpdate(RsGxsReputationUpdateItem *item, void *data, uint32_t *size); -virtual RsGxsReputationUpdateItem *deserialiseUpdate(void *data, uint32_t *size); - - -virtual uint32_t sizeRequest(RsGxsReputationRequestItem *); -virtual bool serialiseRequest(RsGxsReputationRequestItem *item, void *data, uint32_t *size); -virtual RsGxsReputationRequestItem *deserialiseRequest(void *data, uint32_t *size); + virtual ~RsGxsReputationSerialiser(){} + virtual uint32_t size(RsItem *item) + { + return dynamic_cast(item)->serial_size() ; + } + virtual bool serialise (RsItem *item, void *data, uint32_t *size) + { + return dynamic_cast(item)->serialise(data,*size) ; + } + virtual RsItem * deserialise(void *data, uint32_t *size); +private: + static RsGxsReputationConfigItem *deserialiseReputationConfigItem (void *data, uint32_t size); + static RsGxsReputationSetItem *deserialiseReputationSetItem (void *data, uint32_t size); + static RsGxsReputationSetItem *deserialiseReputationSetItem_deprecated (void *data, uint32_t size); + static RsGxsReputationUpdateItem *deserialiseReputationUpdateItem (void *data, uint32_t size); + static RsGxsReputationRequestItem *deserialiseReputationRequestItem (void *data, uint32_t size); }; /**************************************************************************/ diff --git a/libretroshare/src/serialiser/rsserial.cc b/libretroshare/src/serialiser/rsserial.cc index 4635fc2a2..1658cb5b4 100644 --- a/libretroshare/src/serialiser/rsserial.cc +++ b/libretroshare/src/serialiser/rsserial.cc @@ -427,7 +427,7 @@ RsItem * RsSerialiser::deserialise(void *data, uint32_t *size) std::cerr << "RsSerialiser::deserialise() pkt_size: " << pkt_size << " vs *size: " << *size; std::cerr << std::endl; - RsItem *item2 = (it->second)->deserialise(data, &pkt_size); + //RsItem *item2 = (it->second)->deserialise(data, &pkt_size); uint32_t failedtype = getRsItemId(data); std::cerr << "RsSerialiser::deserialise() FAILED PACKET Size: "; diff --git a/libretroshare/src/serialiser/rstlvbase.cc b/libretroshare/src/serialiser/rstlvbase.cc index 5bd704fe4..afc29a99e 100644 --- a/libretroshare/src/serialiser/rstlvbase.cc +++ b/libretroshare/src/serialiser/rstlvbase.cc @@ -523,9 +523,9 @@ static bool readHex(char s1,char s2,uint8_t& v) static bool find_decoded_string(const std::string& in,const std::string& suspicious_string) { - int ss_pointer = 0 ; + uint32_t ss_pointer = 0 ; - for(int i=0;i &lst) lst.clear() ; for(std::map::const_iterator it(mBanSet.begin());it!=mBanSet.end();++it) { - bool already_banned = false ; - if(!acceptedBanSet_locked(it->second)) continue ; @@ -498,7 +496,7 @@ bool p3BanList::addIpRange(const sockaddr_storage &addr, int masked_bytes,uint32 { RS_STACK_MUTEX(mBanMtx) ; - if(getBitRange(addr) > masked_bytes) + if(getBitRange(addr) > uint32_t(masked_bytes)) { std::cerr << "(EE) Input to p3BanList::addIpRange is inconsistent: ip=" << sockaddr_storage_iptostring(addr) << "/" << 32-8*masked_bytes << std::endl; return false ; @@ -955,7 +953,7 @@ bool p3BanList::addBanEntry(const RsPeerId &peerId, const struct sockaddr_storag { /* see if it needs an update */ if ((mit->second.reason != reason) || - (mit->second.level != level) || + (mit->second.level != uint32_t(level)) || (mit->second.mTs < time_stamp)) { /* update */ @@ -1044,7 +1042,7 @@ int p3BanList::condenseBanSources_locked() continue; } - int lvl = lit->second.level; + uint32_t lvl = lit->second.level; if (it->first != ownId) { /* as from someone else, increment level */ diff --git a/libretroshare/src/services/p3gxschannels.cc b/libretroshare/src/services/p3gxschannels.cc index 580cd5467..d25220662 100644 --- a/libretroshare/src/services/p3gxschannels.cc +++ b/libretroshare/src/services/p3gxschannels.cc @@ -337,7 +337,6 @@ bool p3GxsChannels::getPostData(const uint32_t &token, std::vectorfirst; std::vector& msgItems = mit->second; std::vector::iterator vit = msgItems.begin(); diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 731b968e7..ac9276f15 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -199,8 +199,7 @@ bool p3GxsForums::getGroupData(const uint32_t &token, std::vectormGroup; - item->mGroup.mMeta = item->meta; - grp.mMeta = item->mGroup.mMeta; + grp.mMeta = item->meta; delete item; groups.push_back(grp); } @@ -230,7 +229,6 @@ bool p3GxsForums::getMsgData(const uint32_t &token, std::vector & for(; mit != msgData.end(); ++mit) { - RsGxsGroupId grpId = mit->first; std::vector& msgItems = mit->second; std::vector::iterator vit = msgItems.begin(); diff --git a/libretroshare/src/services/p3gxsreputation.cc b/libretroshare/src/services/p3gxsreputation.cc index 943569732..c1eef988a 100644 --- a/libretroshare/src/services/p3gxsreputation.cc +++ b/libretroshare/src/services/p3gxsreputation.cc @@ -23,6 +23,7 @@ * */ +#include #include "pqi/p3linkmgr.h" #include "retroshare/rspeers.h" @@ -38,13 +39,6 @@ * #define DEBUG_REPUTATION 1 ****/ - -/* DEFINE INTERFACE POINTER! */ -//RsGxsReputation *rsGxsReputation = NULL; - -const int kMaximumPeerAge = 180; // half a year. -const int kMaximumSetSize = 100; - /************ IMPLEMENTATION NOTES ********************************* * * p3GxsReputation shares opinions / reputations with peers. @@ -61,8 +55,12 @@ const int kMaximumSetSize = 100; * last update -----------> * <----------- modified opinions. * - * This service will have to store a huge amount of data. - * need to workout how to reduce it. + * If not clever enough, this service will have to store a huge amount of data. + * To make things tractable we do this: + * - do not store reputations when no data is present, or when all friends are neutral + * - only send a neutral opinion when they are a true change over someone's opinion + * - only send a neutral opinion when it is a true change over someone's opinion + * - auto-clean reputations for default values * * std::map mReputations. * std::multimap mUpdated. @@ -70,70 +68,87 @@ const int kMaximumSetSize = 100; * std::map mConfig; * * Updates from p3GxsReputation -> p3IdService. - * - * * Updates from p3IdService -> p3GxsReputation. * + * Each peer locally stores reputations for all GXS ids. If not stored, a default value + * is used, corresponding to a neutral opinion. Peers also share their reputation level + * with their neighbor nodes. + * + * The calculation method is the following: + * + * Local values: + * Good: 2 + * Neutral: 1 + * Bad: 0 * + * Overall reputation score: + * + * if(own_opinion == 0) // means we dont' care + * r = average_of_friends_opinions + * else + * r = own_opinion + * + * Decisions based on reputation score: + * + * 0 x1 1 x2 2 + * | <-----------------------------------------------------------------------> | + * ---------+ + * Lobbies | Msgs dropped + * Forums | Msgs dropped + * Messages | Msgs dropped + * ---------+---------------------------------------------------------------------------- + * + * We select x1=0.5 + * + * => to kill an identity, either you, or at least 50% of your friends need to flag it + * as bad. + * Rules: + * * a single peer cannot drastically change the behavior of a given GXS id + * * it should be easy for many peers to globally kill a GXS id + * + * Typical examples: + * + * Friends | Friend average | Own | alpha | Score + * -----------+---------------------+----------+------------+-------------- + * 10 | 0.5 | 1 | 0.25 | 0.375 + * 10 | 1.0 | 1 | 0.25 | 1.0 + * 10 | 1.0 | 0 | 0.25 | 1.0 + * + * To check: + * [ ] Opinions are saved/loaded accross restart + * [ ] Opinions are transmitted to friends + * [ ] Opinions are transmitted to friends when updated + * + * To do: + * [ ] Add debug info + * [ ] Test the whole thing + * [X] Implement a system to allow not storing info when we don't have it */ -const int32_t REPUTATION_OFFSET = 100000; -const int32_t LOWER_LIMIT = -100; -const int32_t UPPER_LIMIT = 100; - -int32_t ConvertFromSerialised(uint32_t value, bool limit) -{ - int32_t converted = ((int32_t) value) - REPUTATION_OFFSET ; - if (limit) - { - if (converted < LOWER_LIMIT) - { - converted = LOWER_LIMIT; - } - if (converted > UPPER_LIMIT) - { - converted = UPPER_LIMIT; - } - } - return converted; -} - -uint32_t ConvertToSerialised(int32_t value, bool limit) -{ - if (limit) - { - if (value < LOWER_LIMIT) - { - value = LOWER_LIMIT; - } - if (value > UPPER_LIMIT) - { - value = UPPER_LIMIT; - } - } - - value += REPUTATION_OFFSET; - if (value < 0) - { - value = 0; - } - return (uint32_t) value; -} - +static const uint32_t LOWER_LIMIT = 0; // used to filter valid Opinion values from serialized data +static const uint32_t UPPER_LIMIT = 2; // used to filter valid Opinion values from serialized data +static const int kMaximumPeerAge = 180; // half a year. +static const int kMaximumSetSize = 100; // max set of updates to send at once. +static const int ACTIVE_FRIENDS_UPDATE_PERIOD = 600 ; // 10 minutes +static const int ACTIVE_FRIENDS_ONLINE_DELAY = 86400*7 ; // 1 week. +static const int kReputationRequestPeriod = 600; // 10 mins +static const int kReputationStoreWait = 180; // 3 minutes. +static const float REPUTATION_ASSESSMENT_THRESHOLD_X1 = 0.5f ; // reputation under which the peer gets killed p3GxsReputation::p3GxsReputation(p3LinkMgr *lm) :p3Service(), p3Config(), mReputationMtx("p3GxsReputation"), mLinkMgr(lm) { - addSerialType(new RsGxsReputationSerialiser()); + addSerialType(new RsGxsReputationSerialiser()); - mRequestTime = 0; - mStoreTime = 0; - mReputationsUpdated = false; + mRequestTime = 0; + mStoreTime = 0; + mReputationsUpdated = false; + mLastActiveFriendsUpdate = 0 ; + mAverageActiveFriends = 0 ; } - const std::string GXS_REPUTATION_APP_NAME = "gxsreputation"; const uint16_t GXS_REPUTATION_APP_MAJOR_VERSION = 1; const uint16_t GXS_REPUTATION_APP_MINOR_VERSION = 0; @@ -150,13 +165,41 @@ RsServiceInfo p3GxsReputation::getServiceInfo() GXS_REPUTATION_MIN_MINOR_VERSION); } - - int p3GxsReputation::tick() { processIncoming(); sendPackets(); + time_t now = time(NULL); + + if(mLastActiveFriendsUpdate + ACTIVE_FRIENDS_UPDATE_PERIOD < now) + { + updateActiveFriends() ; + cleanup() ; + + mLastActiveFriendsUpdate = now ; + } + + static time_t last_identity_flags_update = 0 ; + + // no more than once per 5 second chunk. + + if(now > 100+last_identity_flags_update) + { + last_identity_flags_update = now ; + + updateIdentityFlags() ; + } + +#ifdef DEBUG_REPUTATION + static time_t last_debug_print = time(NULL) ; + + if(now > 10+last_debug_print) + { + last_debug_print = now ; + debug_print() ; + } +#endif return 0; } @@ -165,7 +208,105 @@ int p3GxsReputation::status() return 1; } +void p3GxsReputation::updateIdentityFlags() +{ + std::list to_update ; + // we need to gather the list to be used in a non locked frame + { + RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ + +#ifdef DEBUG_REPUTATION + std::cerr << "Updating reputation identity flags" << std::endl; +#endif + + for( std::map::iterator rit = mReputations.begin();rit!=mReputations.end();++rit) + if(rit->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE) + to_update.push_back(rit->first) ; + } + + for(std::list::const_iterator rit(to_update.begin());rit!=to_update.end();++rit) + { + RsIdentityDetails details; + + if(!rsIdentity->getIdDetails(*rit,details)) + { +#ifdef DEBUG_REPUTATION + std::cerr << " cannot obtain info for " << *rit << ". Will do it later." << std::endl; +#endif + continue ; + } + + RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ + + std::map::iterator it = mReputations.find(*rit) ; + + if(it == mReputations.end()) + { + std::cerr << " Weird situation: item " << *rit << " has been deleted from the list??" << std::endl; + continue ; + } + it->second.mIdentityFlags = 0 ; + + if(details.mPgpLinked) it->second.mIdentityFlags |= REPUTATION_IDENTITY_FLAG_PGP_LINKED ; + if(details.mPgpKnown ) it->second.mIdentityFlags |= REPUTATION_IDENTITY_FLAG_PGP_KNOWN ; + +#ifdef DEBUG_REPUTATION + std::cerr << " updated flags for " << *rit << " to " << std::hex << it->second.mIdentityFlags << std::dec << std::endl; +#endif + + it->second.updateReputation() ; + IndicateConfigChanged(); + } +} + +void p3GxsReputation::cleanup() +{ + // remove opinions from friends that havn't been seen online for more than the specified delay + +#ifdef DEBUG_REPUTATION + std::cerr << "p3GxsReputation::cleanup() " << std::endl; +#endif + std::cerr << __PRETTY_FUNCTION__ << ": not implemented. TODO!" << std::endl; +} + +void p3GxsReputation::updateActiveFriends() +{ + RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ + + // keep track of who is recently connected. That will give a value to average friend + // for this, we count all friends that have been online in the last week. + + time_t now = time(NULL) ; + + std::list idList ; + mLinkMgr->getFriendList(idList) ; + + mAverageActiveFriends = 0 ; +#ifdef DEBUG_REPUTATION + std::cerr << " counting recently online peers." << std::endl; +#endif + + for(std::list::const_iterator it(idList.begin());it!=idList.end();++it) + { + RsPeerDetails details ; +#ifdef DEBUG_REPUTATION + std::cerr << " " << *it << ": last seen " << now - details.lastConnect << " secs ago" << std::endl; +#endif + + if(rsPeers->getPeerDetails(*it, details) && now < details.lastConnect + ACTIVE_FRIENDS_ONLINE_DELAY) + ++mAverageActiveFriends ; + } +#ifdef DEBUG_REPUTATION + std::cerr << " new count: " << mAverageActiveFriends << std::endl; +#endif + +} + +static RsReputations::Opinion safe_convert_uint32t_to_opinion(uint32_t op) +{ + return RsReputations::Opinion(std::min((uint32_t)op,UPPER_LIMIT)) ; +} /***** Implementation ******/ bool p3GxsReputation::processIncoming() @@ -184,40 +325,31 @@ bool p3GxsReputation::processIncoming() switch(item->PacketSubType()) { default: - case RS_PKT_SUBTYPE_GXSREPUTATION_CONFIG_ITEM: - case RS_PKT_SUBTYPE_GXSREPUTATION_SET_ITEM: + case RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM: + case RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM: std::cerr << "p3GxsReputation::processingIncoming() Unknown Item"; std::cerr << std::endl; itemOk = false; break; - case RS_PKT_SUBTYPE_GXSREPUTATION_REQUEST_ITEM: + case RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM: { - RsGxsReputationRequestItem *requestItem = - dynamic_cast(item); + RsGxsReputationRequestItem *requestItem = dynamic_cast(item); if (requestItem) - { SendReputations(requestItem); - } else - { itemOk = false; - } } break; - case RS_PKT_SUBTYPE_GXSREPUTATION_UPDATE_ITEM: + case RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM: { - RsGxsReputationUpdateItem *updateItem = - dynamic_cast(item); + RsGxsReputationUpdateItem *updateItem = dynamic_cast(item); + if (updateItem) - { RecvReputations(updateItem); - } else - { itemOk = false; - } } break; } @@ -237,8 +369,9 @@ bool p3GxsReputation::processIncoming() bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request) { - std::cerr << "p3GxsReputation::SendReputations()"; - std::cerr << std::endl; +#ifdef DEBUG_REPUTATION + std::cerr << "p3GxsReputation::SendReputations()" << std::endl; +#endif RsPeerId peerId = request->PeerId(); time_t last_update = request->mLastUpdate; @@ -252,12 +385,13 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request) int count = 0; int totalcount = 0; RsGxsReputationUpdateItem *pkt = new RsGxsReputationUpdateItem(); + pkt->PeerId(peerId); for(;tit != mUpdated.end(); ++tit) { /* find */ - std::map::iterator rit; - rit = mReputations.find(tit->second); + std::map::iterator rit = mReputations.find(tit->second); + if (rit == mReputations.end()) { std::cerr << "p3GxsReputation::SendReputations() ERROR Missing Reputation"; @@ -275,8 +409,9 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request) } RsGxsId gxsId = rit->first; - pkt->mOpinions[gxsId] = ConvertToSerialised(rit->second.mOwnOpinion, true); + pkt->mOpinions[gxsId] = rit->second.mOwnOpinion; pkt->mLatestUpdate = rit->second.mOwnOpinionTs; + if (pkt->mLatestUpdate == (uint32_t) now) { // if we could possibly get another Update at this point (same second). @@ -289,10 +424,13 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request) if (count > kMaximumSetSize) { +#ifdef DEBUG_REPUTATION std::cerr << "p3GxsReputation::SendReputations() Sending Full Packet"; std::cerr << std::endl; +#endif sendItem(pkt); + pkt = new RsGxsReputationUpdateItem(); pkt->PeerId(peerId); count = 0; @@ -301,8 +439,10 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request) if (!pkt->mOpinions.empty()) { +#ifdef DEBUG_REPUTATION std::cerr << "p3GxsReputation::SendReputations() Sending Final Packet"; std::cerr << std::endl; +#endif sendItem(pkt); } @@ -311,52 +451,125 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request) delete pkt; } +#ifdef DEBUG_REPUTATION std::cerr << "p3GxsReputation::SendReputations() Total Count: " << totalcount; std::cerr << std::endl; +#endif return true; } +void p3GxsReputation::locked_updateOpinion(const RsPeerId& from,const RsGxsId& about,RsReputations::Opinion op) +{ + /* find matching Reputation */ + std::map::iterator rit = mReputations.find(about); + + RsReputations::Opinion new_opinion = safe_convert_uint32t_to_opinion(op); + RsReputations::Opinion old_opinion = RsReputations::OPINION_NEUTRAL ; // default if not set + + bool updated = false ; + +#ifdef DEBUG_REPUTATION + std::cerr << "p3GxsReputation::update opinion of " << about << " from " << from << " to " << op << std::endl; +#endif + // now 4 cases; + // Opinion already stored + // New opinion is same: nothing to do + // New opinion is different: if neutral, remove entry + // Nothing stored + // New opinion is neutral: nothing to do + // New opinion is != 1: create entry and store + + if (rit == mReputations.end()) + { +#ifdef DEBUG_REPUTATION + std::cerr << " no preview record"<< std::endl; +#endif + + if(new_opinion != RsReputations::OPINION_NEUTRAL) + { + mReputations[about] = Reputation(about); + rit = mReputations.find(about); + } + else + { +#ifdef DEBUG_REPUTATION + std::cerr << " no changes!"<< std::endl; +#endif + return ; // nothing to do + } + } + + Reputation& reputation = rit->second; + + std::map::iterator it2 = reputation.mOpinions.find(from) ; + + if(it2 == reputation.mOpinions.end()) + { + if(new_opinion != RsReputations::OPINION_NEUTRAL) + { + reputation.mOpinions[from] = new_opinion; // filters potentially tweaked reputation score sent by friend + updated = true ; + } + } + else + { + old_opinion = it2->second ; + + if(new_opinion == RsReputations::OPINION_NEUTRAL) + { + reputation.mOpinions.erase(it2) ; // don't store when the opinion is neutral + updated = true ; + } + else if(new_opinion != old_opinion) + { + it2->second = new_opinion ; + updated = true ; + } + } + + if(reputation.mOpinions.empty() && reputation.mOwnOpinion == RsReputations::OPINION_NEUTRAL) + { + mReputations.erase(rit) ; +#ifdef DEBUG_REPUTATION + std::cerr << " own is neutral and no opinions from friends => remove entry" << std::endl; +#endif + updated = true ; + } + else if(updated) + { +#ifdef DEBUG_REPUTATION + std::cerr << " reputation changed. re-calculating." << std::endl; +#endif + reputation.updateReputation() ; + } + + if(updated) + IndicateConfigChanged() ; +} bool p3GxsReputation::RecvReputations(RsGxsReputationUpdateItem *item) { - std::cerr << "p3GxsReputation::RecvReputations()"; - std::cerr << std::endl; +#ifdef DEBUG_REPUTATION + std::cerr << "p3GxsReputation::RecvReputations() from " << item->PeerId() << std::endl; +#endif RsPeerId peerid = item->PeerId(); - std::map::iterator it; - for(it = item->mOpinions.begin(); it != item->mOpinions.end(); ++it) + for( std::map::iterator it = item->mOpinions.begin(); it != item->mOpinions.end(); ++it) { RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - /* find matching Reputation */ - std::map::iterator rit; - RsGxsId gxsId(it->first); - - rit = mReputations.find(gxsId); - if (rit == mReputations.end()) - { - mReputations[gxsId] = Reputation(gxsId); - rit = mReputations.find(gxsId); - } - - Reputation &reputation = rit->second; - reputation.mOpinions[peerid] = ConvertFromSerialised(it->second, true); - - int previous = reputation.mReputation; - if (previous != reputation.CalculateReputation()) - { - // updated from the network. - mUpdatedReputations.insert(gxsId); - } + locked_updateOpinion(peerid,it->first,safe_convert_uint32t_to_opinion(it->second)); } - updateLatestUpdate(peerid, item->mLatestUpdate); + + updateLatestUpdate(peerid,item->mLatestUpdate); + return true; } -bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid, time_t ts) +bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid,time_t latest_update) { RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ @@ -367,11 +580,12 @@ bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid, time_t ts) mConfig[peerid] = ReputationConfig(peerid); it = mConfig.find(peerid) ; } - it->second.mLatestUpdate = ts; + it->second.mLatestUpdate = latest_update ; mReputationsUpdated = true; // Switched to periodic save due to scale of data. - //IndicateConfigChanged(); + + IndicateConfigChanged(); return true; } @@ -380,14 +594,64 @@ bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid, time_t ts) * Opinion ****/ -bool p3GxsReputation::updateOpinion(const RsGxsId& gxsid, int opinion) +bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, RsReputations::ReputationInfo& info) { + if(gxsid.isNull()) + return false ; + + RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ + +#ifdef DEBUG_REPUTATION + std::cerr << "getReputationInfo() for " << gxsid << std::endl; +#endif + Reputation& rep(mReputations[gxsid]) ; + + info.mOwnOpinion = RsReputations::Opinion(rep.mOwnOpinion) ; + info.mOverallReputationScore = rep.mReputation ; + info.mFriendAverage = rep.mFriendAverage ; + + if(info.mOverallReputationScore > REPUTATION_ASSESSMENT_THRESHOLD_X1) + info.mAssessment = RsReputations::ASSESSMENT_OK ; + else + info.mAssessment = RsReputations::ASSESSMENT_BAD ; + +#ifdef DEBUG_REPUTATION + std::cerr << " information present. OwnOp = " << info.mOwnOpinion << ", overall score=" << info.mAssessment << std::endl; +#endif + + return true ; +} + +bool p3GxsReputation::isIdentityBanned(const RsGxsId &id) +{ + RsReputations::ReputationInfo info ; + + getReputationInfo(id,info) ; + +#ifdef DEBUG_REPUTATION + std::cerr << "isIdentityBanned(): returning " << (info.mAssessment == RsReputations::ASSESSMENT_BAD) << " for GXS id " << id << std::endl; +#endif + return info.mAssessment == RsReputations::ASSESSMENT_BAD ; +} + +bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::Opinion& opinion) +{ +#ifdef DEBUG_REPUTATION + std::cerr << "setOwnOpinion(): for GXS id " << gxsid << " to " << opinion << std::endl; +#endif + if(gxsid.isNull()) + { + std::cerr << " ID " << gxsid << " is rejected. Look for a bug in calling method." << std::endl; + return false ; + } + RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ std::map::iterator rit; /* find matching Reputation */ rit = mReputations.find(gxsid); + if (rit == mReputations.end()) { mReputations[gxsid] = Reputation(gxsid); @@ -420,14 +684,15 @@ bool p3GxsReputation::updateOpinion(const RsGxsId& gxsid, int opinion) time_t now = time(NULL); reputation.mOwnOpinion = opinion; reputation.mOwnOpinionTs = now; - reputation.CalculateReputation(); + reputation.updateReputation(); mUpdated.insert(std::make_pair(now, gxsid)); mUpdatedReputations.insert(gxsid); - mReputationsUpdated = true; + // Switched to periodic save due to scale of data. - //IndicateConfigChanged(); + IndicateConfigChanged(); + return true; } @@ -448,6 +713,9 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list &savelist) cleanup = true; RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ +#ifdef DEBUG_REPUTATION + std::cerr << "p3GxsReputation::saveList()" << std::endl; +#endif /* save */ std::map::iterator it; for(it = mConfig.begin(); it != mConfig.end(); ++it) @@ -459,7 +727,7 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list &savelist) } RsGxsReputationConfigItem *item = new RsGxsReputationConfigItem(); - item->mPeerId = it->first.toStdString(); + item->mPeerId = it->first; item->mLatestUpdate = it->second.mLatestUpdate; item->mLastQuery = it->second.mLastQuery; savelist.push_back(item); @@ -470,16 +738,16 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list &savelist) for(rit = mReputations.begin(); rit != mReputations.end(); ++rit, count++) { RsGxsReputationSetItem *item = new RsGxsReputationSetItem(); - item->mGxsId = rit->first.toStdString(); - item->mOwnOpinion = ConvertToSerialised(rit->second.mOwnOpinion, false); - item->mOwnOpinionTs = rit->second.mOwnOpinionTs; - item->mReputation = ConvertToSerialised(rit->second.mReputation, false); + item->mGxsId = rit->first; + item->mOwnOpinion = rit->second.mOwnOpinion; + item->mOwnOpinionTS = rit->second.mOwnOpinionTs; + item->mIdentityFlags = rit->second.mIdentityFlags; - std::map::iterator oit; + std::map::iterator oit; for(oit = rit->second.mOpinions.begin(); oit != rit->second.mOpinions.end(); ++oit) { // should be already limited. - item->mOpinions[oit->first.toStdString()] = ConvertToSerialised(oit->second, false); + item->mOpinions[oit->first] = (uint32_t)oit->second; } savelist.push_back(item); @@ -495,12 +763,16 @@ void p3GxsReputation::saveDone() bool p3GxsReputation::loadList(std::list& loadList) { +#ifdef DEBUG_REPUTATION + std::cerr << "p3GxsReputation::saveList()" << std::endl; +#endif std::list::iterator it; std::set peerSet; for(it = loadList.begin(); it != loadList.end(); ++it) { RsGxsReputationConfigItem *item = dynamic_cast(*it); + // Configurations are loaded first. (to establish peerSet). if (item) { @@ -510,14 +782,14 @@ bool p3GxsReputation::loadList(std::list& loadList) config.mPeerId = peerId; config.mLatestUpdate = item->mLatestUpdate; config.mLastQuery = 0; - + peerSet.insert(peerId); } + RsGxsReputationSetItem *set = dynamic_cast(*it); if (set) - { loadReputationSet(set, peerSet); - } + delete (*it); } @@ -530,6 +802,9 @@ bool p3GxsReputation::loadReputationSet(RsGxsReputationSetItem *item, const std: std::map::iterator rit; + if(item->mGxsId.isNull()) // just a protection against potential errors having put 00000 into ids. + return false ; + /* find matching Reputation */ RsGxsId gxsId(item->mGxsId); rit = mReputations.find(gxsId); @@ -542,26 +817,24 @@ bool p3GxsReputation::loadReputationSet(RsGxsReputationSetItem *item, const std: Reputation &reputation = mReputations[gxsId]; // install opinions. - std::map::const_iterator oit; + std::map::const_iterator oit; for(oit = item->mOpinions.begin(); oit != item->mOpinions.end(); ++oit) { // expensive ... but necessary. RsPeerId peerId(oit->first); if (peerSet.end() != peerSet.find(peerId)) - { - reputation.mOpinions[peerId] = ConvertFromSerialised(oit->second, true); - } + reputation.mOpinions[peerId] = safe_convert_uint32t_to_opinion(oit->second); } - reputation.mOwnOpinion = ConvertFromSerialised(item->mOwnOpinion, false); - reputation.mOwnOpinionTs = item->mOwnOpinionTs; + reputation.mOwnOpinion = item->mOwnOpinion; + reputation.mOwnOpinionTs = item->mOwnOpinionTS; // if dropping entries has changed the score -> must update. - int previous = ConvertFromSerialised(item->mReputation, false); - if (previous != reputation.CalculateReputation()) - { - mUpdatedReputations.insert(gxsId); - } + + //float old_reputation = reputation.mReputation ; + //mUpdatedReputations.insert(gxsId) ; + + reputation.updateReputation() ; mUpdated.insert(std::make_pair(reputation.mOwnOpinionTs, gxsId)); return true; @@ -572,9 +845,6 @@ bool p3GxsReputation::loadReputationSet(RsGxsReputationSetItem *item, const std: * Send Requests. ****/ -const int kReputationRequestPeriod = 3600; -const int kReputationStoreWait = 180; // 3 minutes. - int p3GxsReputation::sendPackets() { time_t now = time(NULL); @@ -585,7 +855,7 @@ int p3GxsReputation::sendPackets() storeTime = mStoreTime; } - if (now - requestTime > kReputationRequestPeriod) + if (now > requestTime + kReputationRequestPeriod) { sendReputationRequests(); @@ -629,48 +899,41 @@ void p3GxsReputation::sendReputationRequests() mLinkMgr->getOnlineList(idList); -#ifdef DEBUG_REPUTATION - std::cerr << "p3GxsReputation::sendReputationRequests()"; - std::cerr << std::endl; -#endif - /* prepare packets */ std::list::iterator it; for(it = idList.begin(); it != idList.end(); ++it) - { -#ifdef DEBUG_REPUTATION - std::cerr << "p3GxsReputation::sendReputationRequest() To: " << *it; - std::cerr << std::endl; -#endif sendReputationRequest(*it); - } } - - int p3GxsReputation::sendReputationRequest(RsPeerId peerid) { - std::cerr << "p3GxsReputation::sendReputationRequest(" << peerid << ")"; - std::cerr << std::endl; +#ifdef DEBUG_REPUTATION + std::cerr << " p3GxsReputation::sendReputationRequest(" << peerid << ") " ; +#endif + time_t now = time(NULL) ; /* */ - RsGxsReputationRequestItem *requestItem = - new RsGxsReputationRequestItem(); - + RsGxsReputationRequestItem *requestItem = new RsGxsReputationRequestItem(); requestItem->PeerId(peerid); { RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ /* find the last timestamp we have */ - std::map::iterator it; - it = mConfig.find(peerid); + std::map::iterator it = mConfig.find(peerid); + if (it != mConfig.end()) { +#ifdef DEBUG_REPUTATION + std::cerr << " lastUpdate = " << now - it->second.mLatestUpdate << " secs ago. Requesting only more recent." << std::endl; +#endif requestItem->mLastUpdate = it->second.mLatestUpdate; } else { +#ifdef DEBUG_REPUTATION + std::cerr << " lastUpdate = never. Requesting all!" << std::endl; +#endif // get whole list. requestItem->mLastUpdate = 0; } @@ -680,4 +943,90 @@ int p3GxsReputation::sendReputationRequest(RsPeerId peerid) return 1; } +void Reputation::updateReputation() +{ + // the calculation of reputation makes the whole thing + + int friend_total = 0; + + // accounts for all friends. Neutral opinions count for 1-1=0 + // because the average is performed over only accessible peers (not the total number) we need to shift to 1 + + for(std::map::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it) + friend_total += it->second - 1; + + if(mOpinions.empty()) // includes the case of no friends! + mFriendAverage = 1.0f ; + else + { + static const float REPUTATION_FRIEND_FACTOR_ANON = 2.0f ; + static const float REPUTATION_FRIEND_FACTOR_PGP_LINKED = 5.0f ; + static const float REPUTATION_FRIEND_FACTOR_PGP_KNOWN = 10.0f ; + + // For positive votes, start from 1 and slowly tend to 2 + // for negative votes, start from 1 and slowly tend to 0 + // depending on signature state, the ID is harder (signed ids) or easier (anon ids) to ban or to promote. + // + // when REPUTATION_FRIEND_VARIANCE = 3, that gives the following values: + // + // total votes | mFriendAverage anon | mFriendAverage PgpLinked | mFriendAverage PgpKnown | + // | F=2.0 | F=5.0 | F=10.0 | + // -------------+----------------------+---------------------------+--------------------------+ + // -10 | 0.00 Banned | 0.13 Banned | 0.36 Banned | + // -5 | 0.08 Banned | 0.36 Banned | 0.60 | + // -4 | 0.13 Banned | 0.44 Banned | 0.67 | + // -3 | 0.22 Banned | 0.54 | 0.74 | + // -2 | 0.36 Banned | 0.67 | 0.81 | + // -1 | 0.60 | 0.81 | 0.90 | + // 0 | 1.0 | 1.0 | 1.00 | + // 1 | 1.39 | 1.18 | 1.09 | + // 2 | 1.63 | 1.32 | 1.18 | + // 3 | 1.77 | 1.45 | 1.25 | + // 4 | 1.86 | 1.55 | 1.32 | + // 5 | 1.91 | 1.63 | 1.39 | + // + // Banning info is provided by the reputation system, and does not depend on PGP-sign state. + // + // However, each service might have its own rules for the different cases. For instance + // PGP-favoring forums might want a score > 1.4 for anon ids, and >= 1.0 for PGP-signed. + + float reputation_bias ; + + if(mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_KNOWN) + reputation_bias = REPUTATION_FRIEND_FACTOR_PGP_KNOWN ; + else if(mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_LINKED) + reputation_bias = REPUTATION_FRIEND_FACTOR_PGP_LINKED ; + else + reputation_bias = REPUTATION_FRIEND_FACTOR_ANON ; + + if(friend_total > 0) + mFriendAverage = 2.0f-exp(-friend_total / reputation_bias) ; + else + mFriendAverage = exp( friend_total / reputation_bias) ; + } + + // now compute a bias for PGP-signed ids. + + if(mOwnOpinion == RsReputations::OPINION_NEUTRAL) + mReputation = mFriendAverage ; + else + mReputation = (float)mOwnOpinion ; +} + +void p3GxsReputation::debug_print() +{ + std::cerr << "Reputations database: " << std::endl; + std::cerr << " Average number of peers: " << mAverageActiveFriends << std::endl; + + time_t now = time(NULL) ; + + for(std::map::const_iterator it(mReputations.begin());it!=mReputations.end();++it) + { + std::cerr << " ID=" << it->first << ", own: " << it->second.mOwnOpinion << ", Friend average: " << it->second.mFriendAverage << ", global_score: " << it->second.mReputation + << ", last own update: " << now - it->second.mOwnOpinionTs << " secs ago." << std::endl; + + for(std::map::const_iterator it2(it->second.mOpinions.begin());it2!=it->second.mOpinions.end();++it2) + std::cerr << " " << it2->first << ": " << it2->second << std::endl; + } +} diff --git a/libretroshare/src/services/p3gxsreputation.h b/libretroshare/src/services/p3gxsreputation.h index 7456b004a..6bda150ff 100644 --- a/libretroshare/src/services/p3gxsreputation.h +++ b/libretroshare/src/services/p3gxsreputation.h @@ -32,9 +32,14 @@ #include #include +#define REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE 0x0100 +#define REPUTATION_IDENTITY_FLAG_PGP_LINKED 0x0001 +#define REPUTATION_IDENTITY_FLAG_PGP_KNOWN 0x0002 + #include "serialiser/rsgxsreputationitems.h" #include "retroshare/rsidentity.h" +#include "retroshare/rsreputations.h" #include "services/p3service.h" @@ -58,19 +63,21 @@ class Reputation { public: Reputation() - :mOwnOpinion(0), mOwnOpinionTs(0), mReputation(0) { return; } + :mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputation(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE){ } + + Reputation(const RsGxsId& about) + :mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputation(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE){ } - Reputation(const RsGxsId& about) - :mGxsId(about), mOwnOpinion(0), mOwnOpinionTs(0), mReputation(0) { return; } + void updateReputation(); -int32_t CalculateReputation(); - - RsGxsId mGxsId; - std::map mOpinions; + std::map mOpinions; int32_t mOwnOpinion; time_t mOwnOpinionTs; - int32_t mReputation; + float mFriendAverage ; + float mReputation; + + uint32_t mIdentityFlags; }; @@ -80,37 +87,25 @@ int32_t CalculateReputation(); * */ -class p3GxsReputation: public p3Service, public p3Config /* , public pqiMonitor */ +class p3GxsReputation: public p3Service, public p3Config, public RsReputations /* , public pqiMonitor */ { public: p3GxsReputation(p3LinkMgr *lm); virtual RsServiceInfo getServiceInfo(); - /***** Interface for p3idservice *****/ - - virtual bool updateOpinion(const RsGxsId& gxsid, int opinion); - + /***** Interface for RsReputations *****/ + virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) ; + virtual bool getReputationInfo(const RsGxsId& id,ReputationInfo& info) ; + virtual bool isIdentityBanned(const RsGxsId& id) ; + /***** overloaded from p3Service *****/ - /*! - * This retrieves all chat msg items and also (important!) - * processes chat-status items that are in service item queue. chat msg item requests are also processed and not returned - * (important! also) notifications sent to notify base on receipt avatar, immediate status and custom status - * : notifyCustomState, notifyChatStatus, notifyPeerHasNewAvatar - * @see NotifyBase - - */ virtual int tick(); virtual int status(); - /*! * Interface stuff. */ - /*************** pqiMonitor callback ***********************/ - //virtual void statusChange(const std::list &plist); - - /************* from p3Config *******************/ virtual RsSerialiser *setupSerialiser() ; virtual bool saveList(bool& cleanup, std::list&) ; @@ -123,22 +118,28 @@ class p3GxsReputation: public p3Service, public p3Config /* , public pqiMonitor bool SendReputations(RsGxsReputationRequestItem *request); bool RecvReputations(RsGxsReputationUpdateItem *item); - bool updateLatestUpdate(RsPeerId peerid, time_t ts); + bool updateLatestUpdate(RsPeerId peerid, time_t latest_update); + void updateActiveFriends() ; + + // internal update of data. Takes care of cleaning empty boxes. + void locked_updateOpinion(const RsPeerId &from, const RsGxsId &about, RsReputations::Opinion op); + bool loadReputationSet(RsGxsReputationSetItem *item, const std::set &peerSet); - bool loadReputationSet(RsGxsReputationSetItem *item, - const std::set &peerSet); - - int sendPackets(); + int sendPackets(); + void cleanup(); void sendReputationRequests(); - int sendReputationRequest(RsPeerId peerid); - + int sendReputationRequest(RsPeerId peerid); + void debug_print() ; + void updateIdentityFlags(); private: RsMutex mReputationMtx; + time_t mLastActiveFriendsUpdate; time_t mRequestTime; time_t mStoreTime; bool mReputationsUpdated; + uint32_t mAverageActiveFriends ; p3LinkMgr *mLinkMgr; @@ -148,7 +149,7 @@ class p3GxsReputation: public p3Service, public p3Config /* , public pqiMonitor std::multimap mUpdated; // set of Reputations to send to p3IdService. - std::set mUpdatedReputations; + std::set mUpdatedReputations; }; #endif //SERVICE_RSGXSREPUTATION_HEADER diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 8eaa08928..64a02fa1b 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -56,6 +56,8 @@ #define ID_REQUEST_REPUTATION 0x0003 #define ID_REQUEST_OPINION 0x0004 +#define GXSID_MAX_CACHE_SIZE 5000 + static const uint32_t MAX_KEEP_UNUSED_KEYS = 30*86400 ; // remove unused keys after 30 days static const uint32_t MAX_DELAY_BEFORE_CLEANING = 601 ; // clean old keys every 10 mins @@ -144,8 +146,8 @@ RsIdentity *rsIdentity = NULL; p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *nes, PgpAuxUtils *pgpUtils) : RsGxsIdExchange(gds, nes, new RsGxsIdSerialiser(), RS_SERVICE_GXS_TYPE_GXSID, idAuthenPolicy()), RsIdentity(this), GxsTokenQueue(this), RsTickEvent(), - mPublicKeyCache(DEFAULT_MEM_CACHE_SIZE, "GxsIdPublicKeyCache"), - mPrivateKeyCache(DEFAULT_MEM_CACHE_SIZE, "GxsIdPrivateKeyCache"), + mPublicKeyCache(GXSID_MAX_CACHE_SIZE, "GxsIdPublicKeyCache"), + mPrivateKeyCache(GXSID_MAX_CACHE_SIZE, "GxsIdPrivateKeyCache"), mIdMtx("p3IdService"), mNes(nes), mPgpUtils(pgpUtils) { @@ -412,6 +414,8 @@ bool p3IdService:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details) // one utf8 symbol can be at most 4 bytes long - would be better to measure real unicode length !!! if(details.mNickname.length() > RSID_MAXIMUM_NICKNAME_SIZE*4) details.mNickname = "[too long a name]" ; + + rsReputations->getReputationInfo(id,details.mReputation) ; return true; } @@ -421,6 +425,9 @@ bool p3IdService:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details) { details = data.details; details.mLastUsageTS = locked_getLastUsageTS(id) ; + + rsReputations->getReputationInfo(id,details.mReputation) ; + return true; } } @@ -831,7 +838,7 @@ bool p3IdService::getReputation(const RsGxsId &id, GixsReputation &rep) if (mPublicKeyCache.fetch(id, data)) { rep.id = id; - rep.score = data.details.mReputation.mOverallScore; + rep.score = 0;//data.details.mReputation.mOverallScore; #ifdef DEBUG_IDS std::cerr << "p3IdService::getReputation() id: "; std::cerr << id.toStdString() << " score: " << @@ -1669,14 +1676,14 @@ void RsGxsIdCache::updateServiceString(std::string serviceString) } // copy over Reputation scores. - details.mReputation = ssdata.score.rep; + //details.mReputation = ssdata.score.rep; } else { details.mPgpKnown = false; details.mPgpId.clear(); - details.mReputation.updateIdScore(false, false); - details.mReputation.update(); + //details.mReputation.updateIdScore(false, false); + //details.mReputation.update(); } } diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 5fa3b0ada..d38a9117e 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -187,10 +187,6 @@ virtual std::string save() const; #define ID_LOCAL_STATUS_FULL_CALC_FLAG 0x00010000 #define ID_LOCAL_STATUS_INC_CALC_FLAG 0x00020000 - -#define MAX_CACHE_SIZE 100 // Small for testing.. -//#define MAX_CACHE_SIZE 10000 // More useful size - class RsGxsIdGroupItem; class RsGxsIdCache diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index 45e6ebfba..2b69cd205 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -187,19 +187,26 @@ void p3MsgService::processMsg(RsMsgItem *mi, bool incoming) msi->srcId = mi->PeerId(); mSrcIds.insert(std::pair(msi->msgId, msi)); IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ + + /**** STACK UNLOCKED ***/ } - // If the peer is allowed to push files, then auto-download the recommended files. - - if(rsPeers->servicePermissionFlags(mi->PeerId()) & RS_NODE_PERM_ALLOW_PUSH) - for(std::list::const_iterator it(mi->attachment.items.begin());it!=mi->attachment.items.end();++it) - rsFiles->FileRequest((*it).name,(*it).hash,(*it).filesize,std::string(),RS_FILE_REQ_ANONYMOUS_ROUTING,std::list()) ; + if (incoming) + { + // If the peer is allowed to push files, then auto-download the recommended files. + if(rsPeers->servicePermissionFlags(mi->PeerId()) & RS_NODE_PERM_ALLOW_PUSH) + { + std::list srcIds; + srcIds.push_back(mi->PeerId()); + for(std::list::const_iterator it(mi->attachment.items.begin());it!=mi->attachment.items.end();++it) + rsFiles->FileRequest((*it).name,(*it).hash,(*it).filesize,std::string(),RS_FILE_REQ_ANONYMOUS_ROUTING,srcIds) ; + } + } RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_ADD); - - /**** STACK UNLOCKED ***/ } + bool p3MsgService::checkAndRebuildPartialMessage(RsMsgItem *ci) { // Check is the item is ending an incomplete item. diff --git a/libretroshare/src/tcponudp/tou.cc b/libretroshare/src/tcponudp/tou.cc index 019eb72ce..e6fb7f480 100644 --- a/libretroshare/src/tcponudp/tou.cc +++ b/libretroshare/src/tcponudp/tou.cc @@ -35,6 +35,7 @@ static const int kInitStreamTable = 5; #include #include "udp/udpstack.h" +#include "pqi/pqinetwork.h" #include "tcpstream.h" #include #include @@ -42,6 +43,7 @@ static const int kInitStreamTable = 5; #include #define DEBUG_TOU_INTERFACE 1 +#define EUSERS 87 struct TcpOnUdp_t { diff --git a/libretroshare/src/tests/dbase/Makefile b/libretroshare/src/tests/dbase/Makefile deleted file mode 100644 index 5e881dff6..000000000 --- a/libretroshare/src/tests/dbase/Makefile +++ /dev/null @@ -1,55 +0,0 @@ - -RS_TOP_DIR = ../.. -DHT_TOP_DIR = ../../../../libbitdht/src -OPS_TOP_DIR = ../../../../openpgpsdk/src -##### Define any flags that are needed for this section ####### -############################################################### - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/config.mk -############################################################### - -TESTOBJ = fitest2.o fisavetest.o searchtest.o #ficachetest.o -#ficachetest.o - -TESTS = fitest2 fisavetest searchtest #ficachetest -#ficachetest - -ifeq ($(OS),Linux) - TESTOBJ += fimontest.o - TESTS += fimontest -endif - - -ifeq ($(OS),MacOSX) - TESTOBJ += fimontest.o - TESTS += fimontest -endif - - -all: tests - -fitest2 : fitest2.o $(OBJ) - $(CC) $(CFLAGS) -o fitest2 fitest2.o $(OBJ) $(LIBS) - -fisavetest : fisavetest.o $(OBJ) - $(CC) $(CFLAGS) -o fisavetest fisavetest.o $(OBJ) $(LIBS) - -fimontest : fimontest.o $(OBJ) - $(CC) $(CFLAGS) -o fimontest fimontest.o $(OBJ) $(LIBS) - -ficachetest : ficachetest.o $(OBJ) - $(CC) $(CFLAGS) -o ficachetest ficachetest.o $(OBJ) $(LIBS) - -searchtest : searchtest.o $(OBJ) - $(CC) $(CFLAGS) -o searchtest searchtest.o $(OBJ) $(LIBS) - -clobber: rmtestfiles - -rmtestfiles: - $(RM) test.index - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/rules.mk -############################################################### - diff --git a/libretroshare/src/tests/ft/Makefile b/libretroshare/src/tests/ft/Makefile deleted file mode 100644 index 4951fcbfa..000000000 --- a/libretroshare/src/tests/ft/Makefile +++ /dev/null @@ -1,60 +0,0 @@ - -RS_TOP_DIR = ../.. -DHT_TOP_DIR = ../../../../libbitdht/src -OPS_TOP_DIR = ../../../../openpgpsdk/src - -##### Define any flags that are needed for this section ####### -############################################################### - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/config.mk -############################################################### - -TESTOBJ = pqitestor.o ftfilemappertest.o ftfileprovidertest.o ftfilecreatortest.o ftextralisttest.o ftdataplextest.o fttransfermoduletest.o ftcrc32test.o ftcrossprovidercreatortest.o ftcontrollertest.o ftserver1test.o ftserver2test.o ftserver3test.o ftdata_dummy.o ftsearch_dummy.o - -TESTS = ftfileprovidertest ftfilecreatortest ftextralisttest ftdataplextest fttransfermoduletest ftcrc32test ftcrossprovidercreatortest ftcontrollertest ftserver1test ftserver2test fttransfermoduletest ftserver3test -#ftfilemappertest - -all: tests - -ftfilemappertest : ftfilemappertest.o - $(CC) $(CFLAGS) -o ftfilemappertest ftfilemappertest.o $(LIBS) - -ftcontrollertest : ftcontrollertest.o pqitestor.o - $(CC) $(CFLAGS) -o ftcontrollertest ftcontrollertest.o pqitestor.o $(LIBS) - -ftfilecreatortest : ftfilecreatortest.o - $(CC) $(CFLAGS) -o ftfilecreatortest ftfilecreatortest.o $(LIBS) - -ftcrossprovidercreatortest : ftcrossprovidercreatortest.o - $(CC) $(CFLAGS) -o ftcrossprovidercreatortest ftcrossprovidercreatortest.o $(LIBS) - -ftfileprovidertest : ftfileprovidertest.o - $(CC) $(CFLAGS) -o ftfileprovidertest ftfileprovidertest.o $(LIBS) - -fttransfermoduletest : fttransfermoduletest.o - $(CC) $(CFLAGS) -o fttransfermoduletest ftdata_dummy.o ftsearch_dummy.o fttransfermoduletest.o $(LIBS) - -ftextralisttest : ftextralisttest.o - $(CC) $(CFLAGS) -o ftextralisttest ftextralisttest.o $(LIBS) - -ftdataplextest : ftdataplextest.o ftsearch_dummy.o ftdata_dummy.o - $(CC) $(CFLAGS) -o ftdataplextest ftdata_dummy.o ftdataplextest.o ftsearch_dummy.o $(LIBS) - -ftserver1test : ftserver1test.o pqitestor.o - $(CC) $(CFLAGS) -o ftserver1test ftserver1test.o pqitestor.o $(LIBS) - -ftserver2test : ftserver2test.o pqitestor.o - $(CC) $(CFLAGS) -o ftserver2test ftserver2test.o pqitestor.o $(LIBS) - -ftserver3test : ftserver3test.o pqitestor.o - $(CC) $(CFLAGS) -o ftserver3test ftserver3test.o pqitestor.o $(LIBS) - -ftcrc32test : ftcrc32test.o - $(CC) $(CFLAGS) -O0 -g -o ftcrc32test ftcrc32test.o $(LIBS) - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/rules.mk -############################################################### - - diff --git a/libretroshare/src/tests/general/Makefile b/libretroshare/src/tests/general/Makefile deleted file mode 100644 index c21a36ceb..000000000 --- a/libretroshare/src/tests/general/Makefile +++ /dev/null @@ -1,32 +0,0 @@ - -RS_TOP_DIR = ../.. -DHT_TOP_DIR = ../../../../libbitdht/src -OPS_TOP_DIR = ../../../../openpgpsdk/src -##### Define any flags that are needed for this section ####### -############################################################### - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/config.mk -############################################################### - -TESTOBJ = netsetup_test.o random_test.o memory_management_test.o pgpkey_test.o -TESTS = netsetup_test random_test memory_management_test pgpkey_test - -all: tests - -pgpkey_test: pgpkey_test.o - $(CC) $(CFLAGS) -o pgpkey_test pgpkey_test.o $(LIBS) - -netsetup_test: netsetup_test.o - $(CC) $(CFLAGS) -o netsetup_test netsetup_test.o $(LIBS) - -random_test: random_test.o - $(CC) $(CFLAGS) -o random_test random_test.o $(LIBS) - -memory_management_test: memory_management_test.o - $(CC) $(CFLAGS) -o memory_management_test memory_management_test.o $(LIBS) - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/rules.mk -############################################################### - diff --git a/libretroshare/src/tests/pgp/Makefile b/libretroshare/src/tests/pgp/Makefile deleted file mode 100644 index 0032a14fb..000000000 --- a/libretroshare/src/tests/pgp/Makefile +++ /dev/null @@ -1,39 +0,0 @@ - -RS_TOP_DIR = ../.. -DHT_TOP_DIR = ../../../../libbitdht/src -OPS_TOP_DIR = ../../../../openpgpsdk/src -OPENPGP_INCLUDE_DIR = ../../../../openpgpsdk/src - -##### Define any flags that are needed for this section ####### -############################################################### - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/config.mk -############################################################### - -TESTOBJ = test_pgp_handler.o test_pgp_signature_parsing.o test_key_parsing.o test_certificate.o test_identity_import.o -TESTS = test_pgp_handler test_pgp_signature_parsing test_key_parsing test_certificate test_identity_import - -#rsbaseitem_test - -all: tests - -test_certificate : test_certificate.o - $(CC) $(CFLAGS) -o test_certificate test_certificate.o $(OBJ) $(LIBS) -L../../../../openpgpsdk/src/lib/ -lops -lbz2 - -test_identity_import : test_identity_import.o - $(CC) $(CFLAGS) -o test_identity_import test_identity_import.o $(OBJ) $(LIBS) -L../../../../openpgpsdk/src/lib/ -lops -lbz2 - -test_pgp_handler : test_pgp_handler.o - $(CC) $(CFLAGS) -o test_pgp_handler test_pgp_handler.o $(OBJ) $(LIBS) -L../../../../openpgpsdk/src/lib/ -lops -lbz2 - -test_pgp_signature_parsing : test_pgp_signature_parsing.o - $(CC) $(CFLAGS) -o test_pgp_signature_parsing test_pgp_signature_parsing.o $(OBJ) $(LIBS) -L../../../../openpgpsdk/src/lib/ -lops -lbz2 - -test_key_parsing : test_key_parsing.o - $(CC) $(CFLAGS) -o test_key_parsing test_key_parsing.o ../../../../openpgpsdk/src/lib/libops.a -lssl -lcrypto -lbz2 - -############################################################### -include $(RS_TOP_DIR)/scripts/rules.mk -############################################################### - diff --git a/libretroshare/src/tests/pqi/Makefile b/libretroshare/src/tests/pqi/Makefile deleted file mode 100644 index 533a07f2b..000000000 --- a/libretroshare/src/tests/pqi/Makefile +++ /dev/null @@ -1,93 +0,0 @@ - -RS_TOP_DIR = ../.. -DHT_TOP_DIR = ../../../../libbitdht/src/ -OPS_TOP_DIR = ../../../../openpgpsdk/src/ - -##### Define any flags that are needed for this section ####### -############################################################### - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/config.mk -############################################################### - -# Generic Test Harnesses. -TESTOBJ = conn_harness.o ppg_harness.o - -TESTOBJ += pqiqos_test.o -TESTOBJ += net_test.o dht_test.o net_test1.o netiface_test.o dht_test.o -TESTOBJ += pkt_test.o pqiarchive_test.o pqiperson_test.o -TESTOBJ += extaddrfinder_test.o dnsresolver_test.o pqiipset_test.o -TESTOBJ += p3connmgr_reset_test.o p3connmgr_connect_test.o -#conn_test.o - -TESTS = net_test net_test1 netiface_test pqiarchive_test pqiperson_test dnsresolver_test extaddrfinder_test -TESTS += pqiipset_test -TESTS += pqiqos_test -TESTS += p3connmgr_reset_test p3connmgr_connect_test -#TESTS = p3connmgr_test1 - -MANUAL_TESTS = dht_test -#conn_test - -all: tests $(MANUAL_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) - -pqiarchive_test: pqiarchive_test.o pkt_test.o - $(CC) $(CFLAGS) -o pqiarchive_test pkt_test.o pqiarchive_test.o $(LIBS) - -pqiperson_test: pqiperson_test.o testconnect.o - $(CC) $(CFLAGS) -o pqiperson_test pqiperson_test.o testconnect.o $(LIBS) -lstdc++ - -extaddrfinder_test: extaddrfinder_test.o - $(CC) $(CFLAGS) -DEXTADDRSEARCH_DEBUG=1 -o extaddrfinder_test extaddrfinder_test.o $(LIBS) - -pqiqos_test: pqiqos_test.o - $(CC) $(CFLAGS) -o pqiqos_test pqiqos_test.o $(LIBS) - -dnsresolver_test: dnsresolver_test.o - $(CC) $(CFLAGS) -o dnsresolver_test dnsresolver_test.o $(LIBS) - -pqiipset_test: pqiipset_test.o - $(CC) $(CFLAGS) -o pqiipset_test pqiipset_test.o $(LIBS) - -p3connmgr_reset_test: p3connmgr_reset_test.o - $(CC) $(CFLAGS) -o p3connmgr_reset_test p3connmgr_reset_test.o $(LIBS) - -p3connmgr_connect_test: p3connmgr_connect_test.o conn_harness.o ppg_harness.o - $(CC) $(CFLAGS) -o p3connmgr_connect_test p3connmgr_connect_test.o conn_harness.o ppg_harness.o $(LIBS) - - -p3connmgr_test1: p3connmgr_test1.o - $(CC) $(CFLAGS) -o p3connmgr_test1 p3connmgr_test1.o $(LIBS) - - - -clobber: remove_extra_files - -remove_extra_files: - -$(RM) $(MANUAL_TESTS) - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/rules.mk -############################################################### - diff --git a/libretroshare/src/tests/pqi/TestNotes.txt b/libretroshare/src/tests/pqi/TestNotes.txt index 880eae3ca..655c9d7bc 100644 --- a/libretroshare/src/tests/pqi/TestNotes.txt +++ b/libretroshare/src/tests/pqi/TestNotes.txt @@ -70,9 +70,7 @@ Description: (1) isExternalNet() (2) isPrivateNet() (3) isLoopbackNet() -(4) sameNet() (5) isValidNet() -(6) isSameSubnet() (7) pqi_inet_netof() ------------------------------------------------------------ diff --git a/libretroshare/src/tests/pqi/net_test.cc b/libretroshare/src/tests/pqi/net_test.cc index 50dd6477a..8df64d440 100644 --- a/libretroshare/src/tests/pqi/net_test.cc +++ b/libretroshare/src/tests/pqi/net_test.cc @@ -211,46 +211,6 @@ bool test_local_address_manipulation() return true; } - - -#if 0 - -std::ostream &showSocketError(std::ostream &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 addr1 ); -int inaddr_cmp(struct sockaddr_in addr1, unsigned long); - -std::list getLocalInterfaces(); // returns all possible addrs. -bool isExternalNet(struct in_addr *addr); // if Valid & is not Private or Loopback. -bool isPrivateNet(struct in_addr *addr); // if inside 10.0.0.0 or - // other then firewalled. -bool isLoopbackNet(struct in_addr *addr); -bool sameNet(struct in_addr *addr, struct in_addr *addr2); -bool isValidNet(struct in_addr *addr); - - // checks (addr1 & 255.255.255.0) == (addr2 & 255.255.255.0) -bool isSameSubnet(struct in_addr *addr1, struct in_addr *addr2); - - -struct in_addr getPreferredInterface(); // returns best addr. - -in_addr_t pqi_inet_netof(struct in_addr addr); // our implementation. - -bool LookupDNSAddr(std::string name, struct sockaddr_in &addr); - -/* universal socket interface */ - -int unix_close(int sockfd); -int unix_socket(int domain, int type, int protocol); -int unix_fcntl_nonblock(int sockfd); -int unix_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen); -int unix_getsockopt_error(int sockfd, int *err); - -#endif - - bool test_bind_addr(struct sockaddr_in addr); bool test_address_listen() diff --git a/libretroshare/src/tests/pqi/net_test1.cc b/libretroshare/src/tests/pqi/net_test1.cc index 599bacbf2..13c7c51ba 100644 --- a/libretroshare/src/tests/pqi/net_test1.cc +++ b/libretroshare/src/tests/pqi/net_test1.cc @@ -53,9 +53,7 @@ const char * invalid_addrstr = "AAA.BBB.256.256"; int test_isExternalNet(); int test_isPrivateNet(); int test_isLoopbackNet(); -int test_sameNet(); int test_isValidNet(); -int test_isSameSubnet(); int test_pqi_inet_netof(); INITTEST(); @@ -67,9 +65,7 @@ int main(int argc, char **argv) test_isExternalNet(); test_isPrivateNet(); test_isLoopbackNet(); - test_sameNet(); test_isValidNet(); - test_isSameSubnet(); test_pqi_inet_netof(); FINALREPORT("net_test1"); @@ -158,42 +154,6 @@ int test_isLoopbackNet() return 1; } -int test_sameNet() -{ - struct in_addr localnet1_addr; - struct in_addr localnet2_addr; - struct in_addr localnet3_addr; - struct in_addr localnet4_addr; - struct in_addr localnet5_addr; - struct in_addr localnet6_addr; - struct in_addr localnet7_addr; - struct in_addr localnet8_addr; - struct in_addr external_addr; - - inet_aton(localnet1_addrstr, &localnet1_addr); - inet_aton(localnet2_addrstr, &localnet2_addr); - inet_aton(localnet3_addrstr, &localnet3_addr); - inet_aton(localnet4_addrstr, &localnet4_addr); - inet_aton(localnet5_addrstr, &localnet5_addr); - inet_aton(localnet6_addrstr, &localnet6_addr); - inet_aton(localnet7_addrstr, &localnet7_addr); - inet_aton(localnet8_addrstr, &localnet8_addr); - inet_aton(external_addrstr, &external_addr); - - CHECK(sameNet(&localnet1_addr, &localnet5_addr)==true); - CHECK(sameNet(&localnet2_addr, &localnet6_addr)==true); - CHECK(sameNet(&localnet3_addr, &localnet7_addr)==true); - CHECK(sameNet(&localnet4_addr, &localnet8_addr)==true); - CHECK(sameNet(&localnet1_addr, &external_addr)==false); - CHECK(sameNet(&localnet2_addr, &external_addr)==false); - CHECK(sameNet(&localnet3_addr, &external_addr)==false); - CHECK(sameNet(&localnet4_addr, &external_addr)==false); - - REPORT("sameNet()"); - - return 1; -} - int test_isValidNet() { struct in_addr localnet1_addr; @@ -211,25 +171,6 @@ int test_isValidNet() return 1; } -int test_isSameSubnet() -{ - struct in_addr localnet1_addr; - struct in_addr classc1_addr; - struct in_addr classc2_addr; - - inet_aton(localnet1_addrstr, &localnet1_addr); - //random class C addresses - inet_aton("197.67.28.93", &classc1_addr); - inet_aton("197.67.28.3", &classc2_addr); - - CHECK(isSameSubnet(&localnet1_addr, &classc1_addr)==false); - CHECK(isSameSubnet(&classc1_addr, &classc2_addr)==true); - - REPORT("isSameSubnet()"); - - return 1; -} - int test_pqi_inet_netof() { struct in_addr localnet1_addr; diff --git a/libretroshare/src/tests/serialiser/Makefile b/libretroshare/src/tests/serialiser/Makefile deleted file mode 100644 index 287e59058..000000000 --- a/libretroshare/src/tests/serialiser/Makefile +++ /dev/null @@ -1,92 +0,0 @@ - -RS_TOP_DIR = ../.. -DHT_TOP_DIR = ../../../../libbitdht/src -OPS_TOP_DIR = ../../../../openpgpsdk/src - -##### Define any flags that are needed for this section ####### -############################################################### - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/config.mk -############################################################### - -OBJ = rstlvutil.o - -TESTOBJ = tlvbase_test.o tlvbase_test2.o rstunnelitem_test.o -TESTOBJ += tlvitems_test.o tlvstack_test.o rsserial_test.o -TESTOBJ += rstlvwidetest.o tlvrandom_test.o rsturtleitem_test.o -TESTOBJ += tlvtypes_test.o support.o distribitem_test.o rsmsgitem_test.o -TESTOBJ += rsstatusitem_test.o rsconfigitem_test.o -TESTOBJ += rsgrouteritem_test.o $(OBJ) - -TESTS = tlvbase_test tlvbase_test2 -#rstlvwidetest -TESTS += tlvitems_test tlvstack_test -#rstunnelitem_test -TESTS += tlvrandom_test rsturtleitem_test -#rsserial_test -TESTS += tlvtypes_test -#rsmsgitem_test -#distribitem_test -TESTS += rsstatusitem_test -#rsconfigitem_test -#TESTS += rsgrouteritem_test - -#rsbaseitem_test - -all: tests - -tests: $(OBJ) - -tlvbase_test : tlvbase_test.o - $(CC) $(CFLAGS) -o tlvbase_test tlvbase_test.o $(OBJ) $(LIBS) - -tlvbase_test2 : tlvbase_test2.o - $(CC) $(CFLAGS) -o tlvbase_test2 tlvbase_test2.o $(OBJ) $(LIBS) - -tlvitems_test : tlvitems_test.o - $(CC) $(CFLAGS) -o tlvitems_test tlvitems_test.o $(OBJ) $(LIBS) - -tlvstack_test : tlvstack_test.o - $(CC) $(CFLAGS) -o tlvstack_test tlvstack_test.o $(OBJ) $(LIBS) - -rsserial_test : rsserial_test.o - $(CC) $(CFLAGS) -o rsserial_test rsserial_test.o $(OBJ) $(LIBS) - -rsgrouteritem_test : rsgrouteritem_test.o - $(CC) $(CFLAGS) -o rsgrouteritem_test rsgrouteritem_test.o $(OBJ) $(LIBS) - -rsbaseitem_test : rsbaseitem_test.o - $(CC) $(CFLAGS) -o rsbaseitem_test rsbaseitem_test.o $(OBJ) $(LIBS) - -#rstlvwidetest : rstlvwidetest.o -# $(CC) $(CFLAGS) -o rstlvwidetest rstlvwidetest.o $(OBJ) $(LIBS) - -tlvrandom_test : tlvrandom_test.o - $(CC) $(CFLAGS) -o tlvrandom_test tlvrandom_test.o $(OBJ) $(LIBS) - -rsturtleitem_test : rsturtleitem_test.o support.o - $(CC) $(CFLAGS) -o rsturtleitem_test rsturtleitem_test.o support.o $(OBJ) $(LIBS) - -rstunnelitem_test : rstunnelitem_test.o support.o - $(CC) $(CFLAGS) -o rstunnelitem_test rstunnelitem_test.o support.o $(OBJ) $(LIBS) - -tlvtypes_test : tlvtypes_test.o - $(CC) $(CFLAGS) -o tlvtypes_test tlvtypes_test.o $(OBJ) $(LIBS) - -distribitem_test : distribitem_test.o support.o - $(CC) $(CFLAGS) -o distribitem_test distribitem_test.o support.o $(OBJ) $(LIBS) - -rsmsgitem_test : rsmsgitem_test.o support.o - $(CC) $(CFLAGS) -o rsmsgitem_test rsmsgitem_test.o support.o $(OBJ) $(LIBS) - -rsstatusitem_test : rsstatusitem_test.o support.o - $(CC) $(CFLAGS) -o rsstatusitem_test rsstatusitem_test.o support.o $(OBJ) $(LIBS) - -rsconfigitem_test : rsconfigitem_test.o - $(CC) $(CFLAGS) -o rsconfigitem_test rsconfigitem_test.o support.o $(OBJ) $(LIBS) - -############################################################### -include $(RS_TOP_DIR)/scripts/rules.mk -############################################################### - diff --git a/libretroshare/src/tests/services/Makefile b/libretroshare/src/tests/services/Makefile deleted file mode 100644 index a57378ba4..000000000 --- a/libretroshare/src/tests/services/Makefile +++ /dev/null @@ -1,33 +0,0 @@ - -RS_TOP_DIR = ../.. -DHT_TOP_DIR = ../../../../libbitdht/src -OPS_TOP_DIR = ../../../../openpgpsdk/src - -##### Define any flags that are needed for this section ####### -############################################################### - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/config.mk -############################################################### - - -TESTOBJ = servicetest.o forumservicetest.o chatservicetest.o -TESTOBJ += chattest.o distribtest.o - -TESTS = chattest distribtest - -all: tests - -distribtest: distribtest.o servicetest.o forumservicetest.o - $(CC) $(CFLAGS) -o distribtest distribtest.o servicetest.o \ - forumservicetest.o $(OBJ) $(LIBS) - -chattest: chattest.o servicetest.o chatservicetest.o - $(CC) $(CFLAGS) -o chattest chattest.o servicetest.o \ - chatservicetest.o $(OBJ) $(LIBS) - - -############################################################### -include $(RS_TOP_DIR)/scripts/rules.mk -############################################################### - diff --git a/libretroshare/src/tests/tcponudp/Makefile b/libretroshare/src/tests/tcponudp/Makefile deleted file mode 100644 index aa8835e9b..000000000 --- a/libretroshare/src/tests/tcponudp/Makefile +++ /dev/null @@ -1,83 +0,0 @@ - -RS_TOP_DIR = ../.. -DHT_TOP_DIR = ../../../../libbitdht/src -OPS_TOP_DIR = ../../../../openpgpsdk/src -##### Define any flags that are needed for this section ####### -############################################################### - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/config.mk -############################################################### - -#BIOOBJ = bss_tou.o - -#RSOBJ = tou_net.o udplayer.o udpsorter.o udptestfn.o extaddrfinder.o -#RSOBJ += tcppacket.o tcpstream.o tou.o $(BIOOBJ) - -OBJ = udptestfn.o - -EXECS = udpsock_test udpsort_test udp_server test_tou -EXECS += pair_tou stacks_tou bidir_tou timed_tou -#pair_tou reset_tou internal_tou largefile_tou - -TESTOBJ = udpsock_test.o udpsort_test.o udp_server.o test_tou.o -TESTOBJ += pair_tou.o udptestfn.o -TESTOBJ += stacks_tou.o bidir_tou.o timed_tou.o - -#TESTOBJ += pair_tou.o reset_tou.o largefile_tou.o -#internal_tou.o - -TESTS = udpsock_test udpsort_test udp_server test_tou -TESTS += stacks_tou bidir_tou timed_tou -#TESTS += pair_tou -# Unfortunately the design of tou has changed over time. -# and these tests cannot be performed at the moment. -#TESTS += reset_tou largefile_tou -#internal_tou - -all: tests $(EXECS) - -udpsock_test : $(OBJ) udpsock_test.o - $(CC) $(CFLAGS) -o udpsock_test udpsock_test.o $(OBJ) $(LIBS) - -udpsort_test : $(OBJ) udpsort_test.o - $(CC) $(CFLAGS) -o udpsort_test udpsort_test.o $(OBJ) $(LIBS) - -udp_server: $(OBJ) udp_server.o - $(CC) $(CFLAGS) -o udp_server udp_server.o $(OBJ) $(LIBS) - -test_tou : $(OBJ) test_tou.o - $(CC) $(CFLAGS) -o test_tou test_tou.o $(OBJ) $(LIBS) - -pair_tou : $(OBJ) pair_tou.o - $(CC) $(CFLAGS) -o pair_tou pair_tou.o $(OBJ) $(LIBS) - -stacks_tou : $(OBJ) stacks_tou.o - $(CC) $(CFLAGS) -o stacks_tou stacks_tou.o $(OBJ) $(LIBS) - -bidir_tou : $(OBJ) bidir_tou.o - $(CC) $(CFLAGS) -o bidir_tou bidir_tou.o $(OBJ) $(LIBS) - -timed_tou : $(OBJ) timed_tou.o - $(CC) $(CFLAGS) -o timed_tou timed_tou.o $(OBJ) $(LIBS) - -reset_tou : $(OBJ) reset_tou.o - $(CC) $(CFLAGS) -o reset_tou reset_tou.o $(OBJ) $(LIBS) - -internal_tou : $(OBJ) internal_tou.o - $(CC) $(CFLAGS) -o internal_tou internal_tou.o $(OBJ) $(LIBS) - -largefile_tou : $(OBJ) largefile_tou.o - $(CC) $(CFLAGS) -o largefile_tou largefile_tou.o $(OBJ) $(LIBS) - - -# Extra Rule for BIOFLAGS -.c.o: - $(BIOCC) $(BIOCFLAGS) -c $< - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/rules.mk -############################################################### - -CFLAGS += -DRS_USE_BITDHT -I$(DHT_TOP_DIR) - diff --git a/libretroshare/src/tests/upnp/Makefile b/libretroshare/src/tests/upnp/Makefile deleted file mode 100644 index 1c1d8626f..000000000 --- a/libretroshare/src/tests/upnp/Makefile +++ /dev/null @@ -1,23 +0,0 @@ - -RS_TOP_DIR = ../.. -DHT_TOP_DIR = ../../../../libbitdht/src -OPS_TOP_DIR = ../../../../openpgpsdk/src -##### Define any flags that are needed for this section ####### -############################################################### - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/config.mk -############################################################### - -TESTOBJ = -TESTS = - -all: upnpforward - -upnpforward: upnpforward.o - $(CC) $(CFLAGS) -o upnpforward upnpforward.o $(LIBS) - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/rules.mk -############################################################### - diff --git a/libretroshare/src/tests/util/Makefile b/libretroshare/src/tests/util/Makefile deleted file mode 100644 index 8ec44d149..000000000 --- a/libretroshare/src/tests/util/Makefile +++ /dev/null @@ -1,31 +0,0 @@ - -RS_TOP_DIR = ../.. -DHT_TOP_DIR = ../../../../libbitdht/src -OPS_TOP_DIR = ../../../../openpgpsdk/src -##### Define any flags that are needed for this section ####### -############################################################### - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/config.mk -############################################################### - -TESTOBJ = dirtest.o compress_test.o sha1_test.o aes_test.o dchat_decrypt.o -TESTS = dirtest sha1_test aes_test compress_test dchat_decrypt - -all: tests - -sha1_test: sha1_test.o - $(CC) $(CFLAGS) -o sha1_test sha1_test.o $(LIBS) -compress_test: compress_test.o - $(CC) $(CFLAGS) -o compress_test compress_test.o $(LIBS) -dirtest: dirtest.o - $(CC) $(CFLAGS) -o dirtest dirtest.o $(LIBS) -dirtest: aes_test.o - $(CC) $(CFLAGS) -o aes_test aes_test.o $(LIBS) -dchat_decrypt: dchat_decrypt.o - $(CC) $(CFLAGS) -o dchat_decrypt dchat_decrypt.o $(LIBS) - -############################################################### -include $(RS_TOP_DIR)/tests/scripts/rules.mk -############################################################### - diff --git a/libretroshare/src/turtle/Makefile b/libretroshare/src/turtle/Makefile deleted file mode 100644 index 745a340ac..000000000 --- a/libretroshare/src/turtle/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -RS_TOP_DIR = .. -##### Define any flags that are needed for this section ####### -############################################################### - -############################################################### -include $(RS_TOP_DIR)/scripts/config.mk -############################################################### - -RSOBJ = p3turtle.o rsturtleitem.o - -#TESTOBJ = - -#TESTS = - -all: librs tests - -#tlvbase_test : tlvbase_test.o -# $(CC) $(CFLAGS) -o tlvbase_test tlvbase_test.o $(OBJ) $(LIBS) - -############################################################### -include $(RS_TOP_DIR)/scripts/rules.mk -############################################################### - diff --git a/libretroshare/src/turtle/p3turtle.cc b/libretroshare/src/turtle/p3turtle.cc index 7f615bdb3..aaac2ef08 100644 --- a/libretroshare/src/turtle/p3turtle.cc +++ b/libretroshare/src/turtle/p3turtle.cc @@ -289,7 +289,11 @@ void p3turtle::locked_addDistantPeer(const TurtleFileHash&,TurtleTunnelId tid) unsigned char tmp[RsPeerId::SIZE_IN_BYTES] ; memset(tmp,0,RsPeerId::SIZE_IN_BYTES) ; - ((uint32_t*)tmp)[0] = tid ; + assert(sizeof(tid) == 4) ; + + for(int i=0;i<4;++i) + tmp[i] = uint8_t( (tid >> ((3-i)*8)) & 0xff ) ; + RsPeerId virtual_peer_id(tmp) ; _virtual_peers[virtual_peer_id] = tid ; diff --git a/libretroshare/src/upnp/Makefile b/libretroshare/src/upnp/Makefile deleted file mode 100644 index d579a2273..000000000 --- a/libretroshare/src/upnp/Makefile +++ /dev/null @@ -1,28 +0,0 @@ - -RS_TOP_DIR = .. -##### Define any flags that are needed for this section ####### -############################################################### - -EXTRA_CFLAGS += -I$(UPNPC_DIR) -DMINIUPNP_EXPORTS - -############################################################### -include $(RS_TOP_DIR)/scripts/config.mk -############################################################### - -CFLAGS += $(EXTRA_CFLAGS) - -RSOBJ = upnphandler.o upnputil.o - -TESTOBJ = upnptest.o - -TESTS = upnptest - -all: librs tests - -upnptest: $(OBJ) upnptest.o - $(CC) $(CFLAGS) -o upnptest $(OBJ) upnptest.o $(LIBS) - -############################################################### -include $(RS_TOP_DIR)/scripts/rules.mk -############################################################### - diff --git a/libretroshare/src/upnp/upnphandler_linux.cc b/libretroshare/src/upnp/upnphandler_linux.cc index e95fe839b..13f70f041 100644 --- a/libretroshare/src/upnp/upnphandler_linux.cc +++ b/libretroshare/src/upnp/upnphandler_linux.cc @@ -103,10 +103,18 @@ bool upnphandler::background_setup_upnp(bool start, bool stop) data->start = start; data->stop = stop; - pthread_create(&tid, 0, &doSetupUPnP, (void *) data); + if(! pthread_create(&tid, 0, &doSetupUPnP, (void *) data)) + { pthread_detach(tid); /* so memory is reclaimed in linux */ return true; + } + else + { + delete data ; + std::cerr << "(EE) Could not start background upnp thread!" << std::endl; + return false ; + } } bool upnphandler::start_upnp() diff --git a/libretroshare/src/upnp/upnphandler_miniupnp.cc b/libretroshare/src/upnp/upnphandler_miniupnp.cc index 3c2442527..1c176337b 100644 --- a/libretroshare/src/upnp/upnphandler_miniupnp.cc +++ b/libretroshare/src/upnp/upnphandler_miniupnp.cc @@ -30,13 +30,81 @@ bool upnphandler::initUPnPState() { /* allocate memory */ uPnPConfigData *upcd = new uPnPConfigData; - -#if MINIUPNPC_VERSION >= 11 - /* Starting from version 1.1, miniupnpc api has a new parameter (int sameport) */ - upcd->devlist = upnpDiscover(2000, NULL, NULL, 0); +#if MINIUPNPC_API_VERSION >= 14 //1.9 2015/07/23 + /* $Id: miniupnpc.h,v 1.44 2015/07/23 20:40:10 nanard Exp $ */ + //upnpDiscover(int delay, const char * multicastif, + // const char * minissdpdsock, int sameport, + // int ipv6, unsigned char ttl, + // int * error); + unsigned char ttl = 2; /* defaulting to 2 */ + upcd->devlist = upnpDiscover(2000, NULL, + NULL, 0, + 0, ttl, + NULL); #else - upcd->devlist = upnpDiscover(2000, NULL, NULL); -#endif +#if MINIUPNPC_API_VERSION >= 8 //1.5 2011/04/18 + /* $Id: miniupnpc.h,v 1.41 2015/05/22 10:23:48 nanard Exp $ */ + /* $Id: miniupnpc.h,v 1.23 2011/04/11 08:21:46 nanard Exp $ */ + //upnpDiscover(int delay, const char * multicastif, + // const char * minissdpdsock, int sameport, + // int ipv6, + // int * error); + upcd->devlist = upnpDiscover(2000, NULL, + NULL, 0, + 0, + NULL); +#else +#if MINIUPNPC_API_VERSION >= 6//1.5 2011/03/14 + /* $Id: miniupnpc.h,v 1.21 2011/03/14 13:37:12 nanard Exp $ */ + //upnpDiscover(int delay, const char * multicastif, + // const char * minissdpdsock, int sameport, + // int * error); + upcd->devlist = upnpDiscover(2000, NULL, + NULL, 0, + NULL); +#else +#if MINIUPNPC_API_VERSION >= -4//1.1 2008/09/25 + /* $Id: miniupnpc.h,v 1.20 2011/02/07 16:46:05 nanard Exp $ */ + /* $Id: miniupnpc.h,v 1.18 2008/09/25 18:02:50 nanard Exp $ */ + //upnpDiscover(int delay, const char * multicastif, + // const char * minissdpdsock, int sameport); + upcd->devlist = upnpDiscover(2000, NULL, + NULL, 0); +#else +#if MINIUPNPC_API_VERSION >= -5//1.0 2007/12/19 + /* $Id: miniupnpc.h,v 1.17 2007/12/19 14:58:54 nanard Exp $ */ + //upnpDiscover(int delay, const char * multicastif, + // const char * minissdpdsock); + upcd->devlist = upnpDiscover(2000, NULL, + NULL); +#else +#if MINIUPNPC_API_VERSION >= -6//1.0 2007/10/16 + /* $Id: miniupnpc.h,v 1.15 2007/10/16 15:07:32 nanard Exp $ */ + //LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif); + upcd->devlist = upnpDiscover(2000, NULL); +#else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 + /* $Id: miniupnpc.h,v 1.14 2007/10/01 13:42:52 nanard Exp $ */ + /* $Id: miniupnpc.h,v 1.9 2006/09/04 09:30:17 nanard Exp $ */ + //struct UPNPDev * upnpDiscover(int); + upcd->devlist = upnpDiscover(2000); +#else +#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version + //2006/09/04 to 2007/10/01 => -7//Start return struct UPNPDev * for upnpDiscover + //2007/10/16 => -6 upnpDiscover + //2007/12/19 => -5 upnpDiscover + //2008/09/25 => -4 upnpDiscover + //2009/04/17 => -3 UPNP_AddPortMapping + //2010/12/09 => -2 //struct IGDdatas_service CIF; + //2011/02/15 => -1 UPNP_AddPortMapping + //2011/03/14 => 6 //Start of MINIUPNPC_API_VERSION +#endif//>=-7 +#endif//>=-6 +#endif//>=-5 +#endif//>=-4 +#endif//>=6 +#endif//>=8 +#endif//>=14 if(upcd->devlist) { @@ -236,10 +304,17 @@ bool upnphandler::background_setup_upnp(bool start, bool stop) data->start = start; data->stop = stop; - pthread_create(&tid, 0, &doSetupUPnP, (void *) data); - pthread_detach(tid); /* so memory is reclaimed in linux */ - - return true; + if(!pthread_create(&tid, 0, &doSetupUPnP, (void *) data)) + { + pthread_detach(tid); /* so memory is reclaimed in linux */ + return true; + } + else + { + delete data ; + std::cerr << "(EE) Failed to start upnp thread." << std::endl; + return false ; + } } bool upnphandler::start_upnp() @@ -305,12 +380,16 @@ bool upnphandler::start_upnp() std::cerr << std::endl; if (!SetRedirectAndTest(&(config -> urls), &(config->data), - in_addr, in_port1, eport1, eprot1)) + in_addr, in_port1, eport1, eprot1, + NULL /*leaseDuration*/, NULL /*description*/, + 0)) { upnpState = RS_UPNP_S_TCP_FAILED; } else if (!SetRedirectAndTest(&(config -> urls), &(config->data), - in_addr, in_port2, eport2, eprot2)) + in_addr, in_port2, eport2, eprot2, + NULL /*leaseDuration*/, NULL /*description*/, + 0)) { upnpState = RS_UPNP_S_UDP_FAILED; } @@ -323,8 +402,16 @@ bool upnphandler::start_upnp() /* now store the external address */ char externalIPAddress[32]; UPNP_GetExternalIPAddress(config -> urls.controlURL, - config->data.servicetype, - externalIPAddress); +#if MINIUPNPC_API_VERSION >= -2//1.4 2010/12/09 + config->data.first.servicetype, +#else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 + config->data.servicetype, +#else +#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version +#endif +#endif + externalIPAddress); sockaddr_clear(&upnp_eaddr); diff --git a/libretroshare/src/upnp/upnputil.c b/libretroshare/src/upnp/upnputil.c index cd7f7da20..448a15c85 100644 --- a/libretroshare/src/upnp/upnputil.c +++ b/libretroshare/src/upnp/upnputil.c @@ -1,8 +1,13 @@ //this file uses miniupnp +//From https://github.com/miniupnp/miniupnp/blob/master/miniupnpc/upnpc.c #include "upnp/upnputil.h" -/* protofix() checks if protocol is "UDP" or "TCP" +#if MINIUPNPC_API_VERSION >= -4//1.0 2008/02/18 +#include +#endif + +/* protofix() checks if protocol is "UDP" or "TCP" * returns NULL if not */ const char * protofix(const char * proto) { @@ -10,13 +15,13 @@ const char * protofix(const char * proto) static const char proto_udp[4] = { 'U', 'D', 'P', 0}; int i, b; for(i=0, b=1; i<4; i++) - b = b && ( (proto[i] == proto_tcp[i]) - || (proto[i] == (proto_tcp[i] | 32)) ); + b = b && ( (proto[i] == proto_tcp[i]) + || (proto[i] == (proto_tcp[i] | 32)) ); if(b) return proto_tcp; for(i=0, b=1; i<4; i++) b = b && ( (proto[i] == proto_udp[i]) - || (proto[i] == (proto_udp[i] | 32)) ); + || (proto[i] == (proto_udp[i] | 32)) ); if(b) return proto_udp; return 0; @@ -25,42 +30,129 @@ const char * protofix(const char * proto) void DisplayInfos(struct UPNPUrls * urls, struct IGDdatas * data) { - char externalIPAddress[16]; + char externalIPAddress[40]; char connectionType[64]; char status[64]; - char lastconnerror[64]; + char lastconnerr[64]; unsigned int uptime; unsigned int brUp, brDown; - UPNP_GetConnectionTypeInfo(urls->controlURL, - data->servicetype, - connectionType); + time_t timenow, timestarted; + int r; +#if MINIUPNPC_API_VERSION >= -2//1.4 2010/12/09 + const char * servicetype = data->first.servicetype; + const char * servicetype_CIF = data->CIF.servicetype; +#else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 + const char * servicetype = data->servicetype; + const char * servicetype_CIF = data->servicetype_CIF; +#else +#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version +#endif//>=-7 +#endif//>=-2 + +#if MINIUPNPC_API_VERSION >= -3//1.0 2009/04/17 + if(UPNP_GetConnectionTypeInfo(urls->controlURL, + servicetype, + connectionType) != UPNPCOMMAND_SUCCESS) +#else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 + UPNP_GetConnectionTypeInfo(urls->controlURL, servicetype, + connectionType); if(connectionType[0]) - printf("Connection Type : %s\n", connectionType); - else +#endif//>=-7 +#endif//>=-3 printf("GetConnectionTypeInfo failed.\n"); - UPNP_GetStatusInfo(urls->controlURL, data->servicetype, status, &uptime, lastconnerror); - printf("Status : %s, uptime=%u LastConnError %s\n", status, uptime, lastconnerror); - UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->servicetype_CIF, - &brDown, &brUp); + else + printf("Connection Type : %s\n", connectionType); + +#if MINIUPNPC_API_VERSION >= -4//1.0 2008/02/18 + if(UPNP_GetStatusInfo(urls->controlURL, servicetype, + status, &uptime, lastconnerr) != UPNPCOMMAND_SUCCESS) + printf("GetStatusInfo failed.\n"); + else + printf("Status : %s, uptime=%us, LastConnectionError : %s\n", + status, uptime, lastconnerr); + timenow = time(NULL); + timestarted = timenow - uptime; + printf(" Time started : %s", ctime(×tarted)); +#else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 + UPNP_GetStatusInfo(urls->controlURL, servicetype, + status, &uptime, lastconnerr); + printf("Status : %s, uptime=%u, LastConnectionError : %s\n", + status, uptime, lastconnerr); +#endif//>=-7 +#endif//>=-4 + +#if MINIUPNPC_API_VERSION >= -4//1.0 2008/02/18 + if(UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, servicetype_CIF, + &brDown, &brUp) != UPNPCOMMAND_SUCCESS) { + printf("GetLinkLayerMaxBitRates failed.\n"); + } else { + printf("MaxBitRateDown : %u bps", brDown); + if(brDown >= 1000000) { + printf(" (%u.%u Mbps)", brDown / 1000000, (brDown / 100000) % 10); + } else if(brDown >= 1000) { + printf(" (%u Kbps)", brDown / 1000); + } + printf(" MaxBitRateUp %u bps", brUp); + if(brUp >= 1000000) { + printf(" (%u.%u Mbps)", brUp / 1000000, (brUp / 100000) % 10); + } else if(brUp >= 1000) { + printf(" (%u Kbps)", brUp / 1000); + } + printf("\n"); + } +#else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 + UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, + servicetype_CIF, + &brDown, &brUp); printf("MaxBitRateDown : %u bps MaxBitRateUp %u bps\n", brDown, brUp); +#endif//>=-7 +#endif//>=-4 + +#if MINIUPNPC_API_VERSION >= -5//1.0 2007/12/19 + r = UPNP_GetExternalIPAddress(urls->controlURL, + servicetype, + externalIPAddress); + if(r != UPNPCOMMAND_SUCCESS) { + printf("GetExternalIPAddress failed. (errorcode=%d)\n", r); + } else { + printf("ExternalIPAddress = %s\n", externalIPAddress); + } +#else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 UPNP_GetExternalIPAddress(urls->controlURL, - data->servicetype, - externalIPAddress); + servicetype, + externalIPAddress); if(externalIPAddress[0]) printf("ExternalIPAddress = %s\n", externalIPAddress); else printf("GetExternalIPAddress failed.\n"); +#endif//>=-7 +#endif//>=-4 } void GetConnectionStatus(struct UPNPUrls * urls, - struct IGDdatas * data) + struct IGDdatas * data) { unsigned int bytessent, bytesreceived, packetsreceived, packetssent; +#if MINIUPNPC_API_VERSION >= -2//1.4 2010/12/09 + const char * servicetype_CIF = data->CIF.servicetype; +#else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 + const char * servicetype_CIF = data->servicetype_CIF; +#else +#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version +#endif//>=-7 +#endif//>=-2 + DisplayInfos(urls, data); - bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->servicetype_CIF); - bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->servicetype_CIF); - packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->servicetype_CIF); - packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->servicetype_CIF); + bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, servicetype_CIF); + bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, servicetype_CIF); + packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, servicetype_CIF); + packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, servicetype_CIF); printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived); printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived); } @@ -71,7 +163,7 @@ void ListRedirections(struct UPNPUrls * urls, int r; int i = 0; char index[6]; - char intClient[16]; + char intClient[40]; char intPort[6]; char extPort[6]; char protocol[4]; @@ -79,6 +171,16 @@ void ListRedirections(struct UPNPUrls * urls, char enabled[6]; char rHost[64]; char duration[16]; +#if MINIUPNPC_API_VERSION >= -2//1.4 2010/12/09 + const char * servicetype = data->first.servicetype; +#else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 + const char * servicetype = data->servicetype; +#else +#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version +#endif//>=-7 +#endif//>=-2 + /*unsigned int num=0; UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num); printf("PortMappingNumberOfEntries : %u\n", num);*/ @@ -87,17 +189,22 @@ void ListRedirections(struct UPNPUrls * urls, rHost[0] = '\0'; enabled[0] = '\0'; duration[0] = '\0'; desc[0] = '\0'; extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0'; - r = UPNP_GetGenericPortMappingEntry(urls->controlURL, data->servicetype, - index, - extPort, intClient, intPort, - protocol, desc, enabled, - rHost, duration); + r = UPNP_GetGenericPortMappingEntry(urls->controlURL, + servicetype, + index, + extPort, intClient, intPort, + protocol, desc, enabled, + rHost, duration); if(r==0) - printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n" + printf("%02d - %s %5s->%s:%-5s" + "\tenabled=%s leaseDuration=%s\n" " desc='%s' rHost='%s'\n", i, protocol, extPort, intClient, intPort, - enabled, duration, - desc, rHost); + enabled, duration, + desc, rHost); + else + printf("GetGenericPortMappingEntry() returned %d (%s)\n", + r, strupnperror(r)); i++; } while(r==0); } @@ -109,17 +216,30 @@ void ListRedirections(struct UPNPUrls * urls, * 4 - get this port mapping from the IGD */ int SetRedirectAndTest(struct UPNPUrls * urls, struct IGDdatas * data, - const char * iaddr, - const char * iport, - const char * eport, - const char * proto) + const char * iaddr, + const char * iport, + const char * eport, + const char * proto, + const char * leaseDuration, + const char * description, + int addAny) { - char externalIPAddress[16]; - char intClient[16]; + char externalIPAddress[40]; + char intClient[40]; char intPort[6]; -// char leaseDuration[] = "3600"; /* 60 mins */ + char reservedPort[6]; + char duration[16]; int r; int ok = 1; +#if MINIUPNPC_API_VERSION >= -2//1.4 2010/12/09 + const char * servicetype = data->first.servicetype; +#else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 + const char * servicetype = data->servicetype; +#else +#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version +#endif +#endif if(!iaddr || !iport || !eport || !proto) { @@ -132,56 +252,166 @@ int SetRedirectAndTest(struct UPNPUrls * urls, fprintf(stderr, "invalid protocol\n"); return 0; } - + +#if MINIUPNPC_API_VERSION >= -5//1.0 2007/12/19 + r = UPNP_GetExternalIPAddress(urls->controlURL, + servicetype, + externalIPAddress); + if(r != UPNPCOMMAND_SUCCESS) + printf("GetExternalIPAddress failed. (errorcode=%d)\n", r); + else + printf("ExternalIPAddress = %s\n", externalIPAddress); +#else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 UPNP_GetExternalIPAddress(urls->controlURL, - data->servicetype, - externalIPAddress); + servicetype, + externalIPAddress); if(externalIPAddress[0]) printf("ExternalIPAddress = %s\n", externalIPAddress); else printf("GetExternalIPAddress failed.\n"); +#endif//>=-7 +#endif//>=-4 -// Unix at the moment! -#if MINIUPNPC_VERSION >= 13 - /* Starting from miniupnpc version 1.2, lease duration parameter is gone */ - r = UPNP_AddPortMapping(urls->controlURL, data->servicetype, - eport, iport, iaddr, 0, proto, NULL); -#else - #if MINIUPNPC_VERSION >= 12 - /* Starting from miniupnpc version 1.2, lease duration parameter is gone */ - r = UPNP_AddPortMapping(urls->controlURL, data->servicetype, - eport, iport, iaddr, 0, proto); - #else - /* The lease parameter is also gone in minupnpc 1.0 */ - r = UPNP_AddPortMapping(urls->controlURL, data->servicetype, - eport, iport, iaddr,0, 0, proto); - #endif +#if MINIUPNPC_API_VERSION >= 11 + if (addAny) { + r = UPNP_AddAnyPortMapping(urls->controlURL, data->first.servicetype, + eport, iport, iaddr, description, + proto, 0, leaseDuration, reservedPort); + if(r==UPNPCOMMAND_SUCCESS) + eport = reservedPort; + else + printf("AddAnyPortMapping(%s, %s, %s) failed with code %d (%s)\n", + eport, iport, iaddr, r, strupnperror(r)); + } else #endif - -// r = UPNP_AddPortMapping(urls->controlURL, data->servicetype, -// eport, iport, iaddr, 0, leaseDuration, proto); - -// r = UPNP_AddPortMapping(urls->controlURL, data->servicetype, -// eport, iport, iaddr, 0, proto); - if(r==0) { - printf("AddPortMapping(%s, %s, %s) failed\n", eport, iport, iaddr); - //this seems to trigger for unknown reasons sometimes. - //rely on Checking it afterwards... - //should check IP address then! - //ok = 0; +#if MINIUPNPC_API_VERSION >= -1 + /* $Id: upnpcommands.h,v 1.30 2015/07/15 12:21:28 nanard Exp $ */ + /* $Id: upnpcommands.h,v 1.20 2011/02/15 11:13:22 nanard Exp $ */ + //UPNP_AddPortMapping(const char * controlURL, const char * servicetype, + // const char * extPort, + // const char * inPort, + // const char * inClient, + // const char * desc, + // const char * proto, + // const char * remoteHost, + // const char * leaseDuration); + r = UPNP_AddPortMapping(urls->controlURL, servicetype, + eport, iport, iaddr, NULL, proto, NULL, NULL); +#else +#if MINIUPNPC_API_VERSION >= -3 //1.0 2009/04/17 + /* $Id: upnpcommands.h,v 1.18 2010/06/09 10:59:09 nanard Exp $ */ + /* $Id: upnpcommands.h,v 1.17 2009/04/17 21:21:19 nanard Exp $ */ + //UPNP_AddPortMapping(const char * controlURL, const char * servicetype, + // const char * extPort, + // const char * inPort, + // const char * inClient, + // const char * desc, + // const char * proto, + // const char * remoteHost); + r = UPNP_AddPortMapping(urls->controlURL, servicetype, + eport, iport, iaddr, NULL, proto, NULL); +#else +#if MINIUPNPC_API_VERSION >= -7//Before 1.0 + /* $Id: upnpcommands.h,v 1.14 2008/09/25 18:02:50 nanard Exp $ */ + /* $Id: upnpcommands.h,v 1.7 2006/07/09 12:00:54 nanard Exp $ */ + //UPNP_AddPortMapping(const char * controlURL, const char * servicetype, + // const char * extPort, + // const char * inPort, + // const char * inClient, + // const char * desc, + // const char * proto); + r = UPNP_AddPortMapping(urls->controlURL, servicetype, + eport, iport, iaddr, NULL, proto); +#else +#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version +#endif//>=-7 +#endif//>=-3 +#endif//>=-1 + +#if MINIUPNPC_API_VERSION >= -5//2007/12/19 + if(r!=UPNPCOMMAND_SUCCESS){ +#else +#if MINIUPNPC_API_VERSION >= -7//Before 1.0 + if(r==0){ +#else +#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version +#endif//>=-7 +#endif//>=-5 + printf("AddPortMapping(%s, %s, %s) failed and returns %d\n", eport, iport, iaddr, r); + //this seems to trigger for unknown reasons sometimes. + //rely on Checking it afterwards... + //should check IP address then! + ok = 0; + } } +#if MINIUPNPC_API_VERSION >= 10//1.0 2006/09/04 + /* $Id: upnpcommands.h,v 1.30 2015/07/15 12:21:28 nanard Exp $ */ + /* $Id: upnpcommands.h,v 1.26 2014/01/31 13:18:26 nanard Exp $ */ + //UPNP_GetSpecificPortMappingEntry(const char * controlURL, + // const char * servicetype, + // const char * extPort, + // const char * proto, + // const char * remoteHost, + // char * intClient, + // char * intPort, + // char * desc, + // char * enabled, + // char * leaseDuration); + r = UPNP_GetSpecificPortMappingEntry(urls->controlURL, + data->first.servicetype, + eport, proto, NULL/*remoteHost*/, + intClient, intPort, NULL/*desc*/, + NULL/*enabled*/, duration); +#else +#if MINIUPNPC_API_VERSION >= 6//1.0 2006/09/04 + /* $Id: upnpcommands.h,v 1.24 2012/03/05 19:42:47 nanard Exp $ */ + /* $Id: upnpcommands.h,v 1.22 2011/03/14 13:36:01 nanard Exp $ */ + //UPNP_GetSpecificPortMappingEntry(const char * controlURL, + // const char * servicetype, + // const char * extPort, + // const char * proto, + // char * intClient, + // char * intPort, + // char * desc, + // char * enabled, + // char * leaseDuration); + r = UPNP_GetSpecificPortMappingEntry(urls->controlURL, + data->first.servicetype, + eport, proto, + intClient, intPort, NULL/*desc*/, + NULL/*enabled*/, duration); +#else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 + /* $Id: upnpcommands.h,v 1.20 2011/02/15 11:13:22 nanard Exp $ */ + /* $Id: upnpcommands.h,v 1.7 2006/07/09 12:00:54 nanard Exp $ */ + //UPNP_GetSpecificPortMappingEntry(const char * controlURL, + // const char * servicetype, + // const char * extPort, + // const char * proto, + // char * intClient, + // char * intPort); UPNP_GetSpecificPortMappingEntry(urls->controlURL, - data->servicetype, - eport, proto, - intClient, intPort); - if(intClient[0]) - printf("InternalIP:Port = %s:%s\n", intClient, intPort); - else - { - printf("GetSpecificPortMappingEntry failed.\n"); + servicetype, + eport, + proto, + intClient, + intPort); + if(intClient[0]) r = UPNPCOMMAND_SUCCESS; +#endif//>=-7 +#endif//>=6 +#endif//>=10 + + if(r!=UPNPCOMMAND_SUCCESS) { + printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n", + r, strupnperror(r)); ok = 0; + } else if(intClient[0]) { + printf("InternalIP:Port = %s:%s\n", intClient, intPort); + printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n", + externalIPAddress, eport, proto, intClient, intPort, duration); } if ((strcmp(iaddr, intClient) != 0) || (strcmp(iport, intPort) != 0)) @@ -194,9 +424,6 @@ int SetRedirectAndTest(struct UPNPUrls * urls, ok = 0; } - printf("external %s:%s is redirected to internal %s:%s\n", - externalIPAddress, eport, intClient, intPort); - if (ok) { printf("uPnP Forward/Mapping Succeeded\n"); @@ -210,14 +437,17 @@ int SetRedirectAndTest(struct UPNPUrls * urls, } int TestRedirect(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * iaddr, - const char * iport, - const char * eport, - const char * proto) + struct IGDdatas * data, + const char * iaddr, + const char * iport, + const char * eport, + const char * proto) { - char intClient[16]; + char externalIPAddress[40]; + char intClient[40]; char intPort[6]; + char duration[16]; + int r = 0; int ok = 1; if(!iaddr || !iport || !eport || !proto) @@ -231,21 +461,83 @@ int TestRedirect(struct UPNPUrls * urls, fprintf(stderr, "invalid protocol\n"); return 0; } - - UPNP_GetSpecificPortMappingEntry(urls->controlURL, - data->servicetype, - eport, proto, - intClient, intPort); - if(intClient[0]) - printf("uPnP Check: InternalIP:Port = %s:%s\n", intClient, intPort); - else - { - printf("GetSpecificPortMappingEntry failed.\n"); - ok = 0; - } - printf("uPnP Check: External port %s is redirected to internal %s:%s\n", - eport, intClient, intPort); +#if MINIUPNPC_API_VERSION >= -2//1.4 2010/12/09 + const char * servicetype = data->first.servicetype; +#else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 + const char * servicetype = data->servicetype; +#else +#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version +#endif +#endif + +#if MINIUPNPC_API_VERSION >= 10//1.0 2006/09/04 + /* $Id: upnpcommands.h,v 1.30 2015/07/15 12:21:28 nanard Exp $ */ + /* $Id: upnpcommands.h,v 1.26 2014/01/31 13:18:26 nanard Exp $ */ + //UPNP_GetSpecificPortMappingEntry(const char * controlURL, + // const char * servicetype, + // const char * extPort, + // const char * proto, + // const char * remoteHost, + // char * intClient, + // char * intPort, + // char * desc, + // char * enabled, + // char * leaseDuration); + r = UPNP_GetSpecificPortMappingEntry(urls->controlURL, + servicetype, + eport, proto, NULL/*remoteHost*/, + intClient, intPort, NULL/*desc*/, + NULL/*enabled*/, duration); +#else +#if MINIUPNPC_API_VERSION >= 6//1.0 2006/09/04 + /* $Id: upnpcommands.h,v 1.24 2012/03/05 19:42:47 nanard Exp $ */ + /* $Id: upnpcommands.h,v 1.22 2011/03/14 13:36:01 nanard Exp $ */ + //UPNP_GetSpecificPortMappingEntry(const char * controlURL, + // const char * servicetype, + // const char * extPort, + // const char * proto, + // char * intClient, + // char * intPort, + // char * desc, + // char * enabled, + // char * leaseDuration); + r = UPNP_GetSpecificPortMappingEntry(urls->controlURL, + servicetype, + eport, proto, + intClient, intPort, NULL/*desc*/, + NULL/*enabled*/, duration); +#else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 + /* $Id: upnpcommands.h,v 1.20 2011/02/15 11:13:22 nanard Exp $ */ + /* $Id: upnpcommands.h,v 1.7 2006/07/09 12:00:54 nanard Exp $ */ + //UPNP_GetSpecificPortMappingEntry(const char * controlURL, + // const char * servicetype, + // const char * extPort, + // const char * proto, + // char * intClient, + // char * intPort); + UPNP_GetSpecificPortMappingEntry(urls->controlURL, + servicetype, + eport, + proto, + intClient, + intPort); + if(intClient[0]) r = UPNPCOMMAND_SUCCESS; +#endif//>=-7 +#endif//>=6 +#endif//>=10 + + if(r!=UPNPCOMMAND_SUCCESS) { + printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n", + r, strupnperror(r)); + ok = 0; + } else if(intClient[0]) { + printf("uPnP Check: InternalIP:Port = %s:%s\n", intClient, intPort); + printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n", + externalIPAddress, eport, proto, intClient, intPort, duration); + } if (ok) { @@ -259,13 +551,11 @@ int TestRedirect(struct UPNPUrls * urls, return ok; } - - int RemoveRedirect(struct UPNPUrls * urls, struct IGDdatas * data, - const char * eport, - const char * proto) + const char * eport, + const char * proto) { if(!proto || !eport) { @@ -278,11 +568,19 @@ RemoveRedirect(struct UPNPUrls * urls, fprintf(stderr, "protocol invalid\n"); return 0; } -#if MINIUPNPC_VERSION >= 13 +#if MINIUPNPC_API_VERSION >= -2//1.4 2010/12/09 + UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, NULL); +#else +#if MINIUPNPC_API_VERSION >= -3//1.3 2009/04/17 UPNP_DeletePortMapping(urls->controlURL, data->servicetype, eport, proto, NULL); #else +#if MINIUPNPC_API_VERSION >= -7//1.0 2006/09/04 UPNP_DeletePortMapping(urls->controlURL, data->servicetype, eport, proto); -#endif +#else +#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version +#endif//>= -7 +#endif//>= -3 +#endif//>= -2 return 1; } diff --git a/libretroshare/src/upnp/upnputil.h b/libretroshare/src/upnp/upnputil.h index 64dca304a..99ec61f4f 100644 --- a/libretroshare/src/upnp/upnputil.h +++ b/libretroshare/src/upnp/upnputil.h @@ -17,9 +17,24 @@ #include #define snprintf _snprintf #endif -#include -#include -#include +#include +#include +#include +#include + +//Define this variable follow the date of used MiniUPnP Library +//#define MINIUPNPC_API_VERSION -3 +#ifndef MINIUPNPC_API_VERSION +#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version + //2006/09/04 to 2007/10/01 => -7//Start return struct UPNPDev * for upnpDiscover + //2007/10/16 => -6 upnpDiscover + //2007/12/19 => -5 upnpDiscover + //2008/09/25 => -4 upnpDiscover + //2009/04/17 => -3 UPNP_AddPortMapping + //2010/12/09 => -2 //struct IGDdatas_service CIF; + //2011/02/15 => -1 UPNP_AddPortMapping + //2011/03/14 => 6 //Start of MINIUPNPC_API_VERSION +#endif//>=-7 /* Ensure linking names are okay on OSX platform. (C interface) */ @@ -41,11 +56,14 @@ void ListRedirections(struct UPNPUrls * urls, struct IGDdatas * data); int SetRedirectAndTest(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * iaddr, - const char * iport, - const char * eport, - const char * proto); + struct IGDdatas * data, + const char * iaddr, + const char * iport, + const char * eport, + const char * proto, + const char *leaseDuration, + const char *description, + int addAny); int TestRedirect(struct UPNPUrls * urls, struct IGDdatas * data, diff --git a/libretroshare/src/util/Makefile b/libretroshare/src/util/Makefile deleted file mode 100644 index 70f15b3be..000000000 --- a/libretroshare/src/util/Makefile +++ /dev/null @@ -1,27 +0,0 @@ - -RS_TOP_DIR = .. -##### Define any flags that are needed for this section ####### -############################################################### - -############################################################### -include $(RS_TOP_DIR)/scripts/config.mk -############################################################### - -RSOBJ = rsthreads.o rsprint.o rsnet.o rsdebug.o rsdir.o rsversion.o - -TESTOBJ = dirtest.o dir2test.o - -TESTS = dirtest dir2test - -all: librs tests - -dirtest: $(OBJ) dirtest.o - $(CC) $(CFLAGS) -o dirtest dirtest.o $(OBJ) $(LIBS) - -dir2test: $(OBJ) dir2test.o - $(CC) $(CFLAGS) -o dir2test dir2test.o $(OBJ) $(LIBS) - -############################################################### -include $(RS_TOP_DIR)/scripts/rules.mk -############################################################### - diff --git a/libretroshare/src/util/argstream.h b/libretroshare/src/util/argstream.h index c239398d7..83fb30f0a 100644 --- a/libretroshare/src/util/argstream.h +++ b/libretroshare/src/util/argstream.h @@ -141,9 +141,15 @@ namespace inline OptionHolder(char s, const char* l, const char* desc); +#ifdef __APPLE__ + friend OptionHolder help(char s, + const char* l, + const char* desc); +#else friend OptionHolder help(char s='h', const char* l="help", const char* desc="Display this help"); +#endif private: std::string shortName_; std::string longName_; diff --git a/libretroshare/src/util/dnsresolver.cc b/libretroshare/src/util/dnsresolver.cc index a91e34821..fbfac7d9c 100644 --- a/libretroshare/src/util/dnsresolver.cc +++ b/libretroshare/src/util/dnsresolver.cc @@ -62,25 +62,33 @@ void *solveDNSEntries(void *p) if(!next_call.empty()) { - hostent *pHost = gethostbyname(next_call.c_str()); + in_addr in ; + + bool succeed = rsGetHostByName(next_call.c_str(),in); + + { + RsStackMutex mut(dnsr->_rdnsMtx) ; - { - RsStackMutex mut(dnsr->_rdnsMtx) ; + DNSResolver::AddrInfo &info = (*dnsr->_addr_map)[next_call]; - DNSResolver::AddrInfo &info = (*dnsr->_addr_map)[next_call]; - - if(pHost) + if(succeed) + { + info.state = DNSResolver::DNS_HAVE ; + // IPv4 for the moment. + struct sockaddr_in *addrv4p = (struct sockaddr_in *) &(info.addr); + addrv4p->sin_family = AF_INET; + addrv4p->sin_addr= in ; + addrv4p->sin_port = htons(0); + + std::cerr << "LOOKUP succeeded: " << next_call.c_str() << " => " << rs_inet_ntoa(addrv4p->sin_addr) << std::endl; + } + else { - info.state = DNSResolver::DNS_HAVE ; - // IPv4 for the moment. - struct sockaddr_in *addrv4p = (struct sockaddr_in *) &(info.addr); - addrv4p->sin_family = AF_INET; - addrv4p->sin_addr.s_addr = *(unsigned long*) (pHost->h_addr); - addrv4p->sin_port = htons(0); - } - else info.state = DNSResolver::DNS_LOOKUP_ERROR ; - } + + std::cerr << "DNSResolver: lookup error for address \"" << next_call.c_str() << "\"" << std::endl; + } + } } } @@ -93,15 +101,18 @@ void *solveDNSEntries(void *p) void DNSResolver::start_request() { - { - RsStackMutex mut(_rdnsMtx) ; - *_thread_running = true ; - } + { + RsStackMutex mut(_rdnsMtx) ; + *_thread_running = true ; + } - void *data = (void *)this; - pthread_t tid ; - pthread_create(&tid, 0, &solveDNSEntries, data); - pthread_detach(tid); /* so memory is reclaimed in linux */ + void *data = (void *)this; + pthread_t tid ; + + if(! pthread_create(&tid, 0, &solveDNSEntries, data)) + pthread_detach(tid); /* so memory is reclaimed in linux */ + else + std::cerr << "(EE) Could not start DNS resolver thread!" << std::endl; } void DNSResolver::reset() diff --git a/libretroshare/src/util/extaddrfinder.cc b/libretroshare/src/util/extaddrfinder.cc index e67aee4a9..e01e37211 100644 --- a/libretroshare/src/util/extaddrfinder.cc +++ b/libretroshare/src/util/extaddrfinder.cc @@ -2,6 +2,7 @@ #include "pqi/pqinetwork.h" #include "util/rsstring.h" +#include "util/rsmemory.h" #ifndef WIN32 #include @@ -58,7 +59,6 @@ static void getPage(const std::string& server_name,std::string& page) int sockfd,n=0; // socket descriptor struct sockaddr_in serveur; // server's parameters memset(&serveur.sin_zero, 0, sizeof(serveur.sin_zero)); - struct hostent *hostinfo=NULL; // structure for storing the server's ip char buf[1024]; char request[1024]; @@ -78,20 +78,21 @@ static void getPage(const std::string& server_name,std::string& page) // get server's ipv4 adress - hostinfo = gethostbyname(server_name.c_str()); - - if (hostinfo == NULL) /* l'hôte n'existe pas */ + in_addr in ; + + if(!rsGetHostByName(server_name.c_str(),in)) /* l'hôte n'existe pas */ { std::cerr << "ExtAddrFinder: Unknown host " << server_name << std::endl; unix_close(sockfd); return ; } - serveur.sin_addr = *(struct in_addr*) hostinfo->h_addr; + serveur.sin_addr = in ; serveur.sin_port = htons(80); #ifdef EXTADDRSEARCH_DEBUG printf("Connection attempt\n"); #endif + std::cerr << "ExtAddrFinder: resolved hostname " << server_name << " to " << rs_inet_ntoa(in) << std::endl; if(unix_connect(sockfd,(struct sockaddr *)&serveur, sizeof(serveur)) == -1) { @@ -104,12 +105,18 @@ static void getPage(const std::string& server_name,std::string& page) #endif // envoi - sprintf( request, + if(snprintf( request, + 1024, "GET / HTTP/1.0\r\n" "Host: %s:%d\r\n" "Connection: Close\r\n" "\r\n", - server_name.c_str(), 80); + server_name.c_str(), 80) > 1020) + { + std::cerr << "ExtAddrFinder: buffer overrun. The server name \"" << server_name << "\" is too long. This is quite unexpected." << std::endl; + unix_close(sockfd); + return ; + } if(send(sockfd,request,strlen(request),0)== -1) { @@ -202,8 +209,11 @@ void ExtAddrFinder::start_request() { void *data = (void *)this; pthread_t tid ; - pthread_create(&tid, 0, &doExtAddrSearch, data); - pthread_detach(tid); /* so memory is reclaimed in linux */ + + if(! pthread_create(&tid, 0, &doExtAddrSearch, data)) + pthread_detach(tid); /* so memory is reclaimed in linux */ + else + std::cerr << "(EE) Could not start ExtAddrFinder thread." << std::endl; } bool ExtAddrFinder::hasValidIP(struct sockaddr_storage &addr) diff --git a/libretroshare/src/util/retrodb.cc b/libretroshare/src/util/retrodb.cc index b6633c3a5..291287973 100644 --- a/libretroshare/src/util/retrodb.cc +++ b/libretroshare/src/util/retrodb.cc @@ -598,7 +598,7 @@ bool RetroDb::tableExists(const std::string &tableName) /********************** RetroCursor ************************/ RetroCursor::RetroCursor(sqlite3_stmt *stmt) - : mStmt(NULL), mCount(0), mPosCounter(0) { + : mStmt(NULL) { open(stmt); } @@ -635,7 +635,6 @@ bool RetroCursor::moveToFirst(){ rc = sqlite3_step(mStmt); if(rc == SQLITE_ROW){ - mPosCounter = 0; return true; } @@ -673,17 +672,10 @@ bool RetroCursor::moveToLast(){ return false; }else{ - mPosCounter = mCount; return true; } } -int RetroCursor::getResultCount() const { - if(isOpen()) - return mCount; - else - return -1; -} int RetroCursor::columnCount() const { if(isOpen()) @@ -704,8 +696,6 @@ bool RetroCursor::close(){ int rc = sqlite3_finalize(mStmt); mStmt = NULL; - mPosCounter = 0; - mCount = 0; return (rc == SQLITE_OK); } @@ -725,12 +715,6 @@ bool RetroCursor::open(sqlite3_stmt *stm){ int rc = sqlite3_reset(mStmt); if(rc == SQLITE_OK){ - - while((rc = sqlite3_step(mStmt)) == SQLITE_ROW) - mCount++; - - sqlite3_reset(mStmt); - return true; } else{ @@ -753,7 +737,6 @@ bool RetroCursor::moveToNext(){ int rc = sqlite3_step(mStmt); if(rc == SQLITE_ROW){ - mPosCounter++; return true; }else if(rc == SQLITE_DONE){ // no more results @@ -772,16 +755,6 @@ bool RetroCursor::moveToNext(){ } } - -int32_t RetroCursor::getPosition() const { - - if(isOpen()) - return mPosCounter; - else - return -1; -} - - int32_t RetroCursor::getInt32(int columnIndex){ return sqlite3_column_int(mStmt, columnIndex); } diff --git a/libretroshare/src/util/retrodb.h b/libretroshare/src/util/retrodb.h index 8b79c0017..435b6e466 100644 --- a/libretroshare/src/util/retrodb.h +++ b/libretroshare/src/util/retrodb.h @@ -239,12 +239,6 @@ public: */ bool moveToLast(); - /*! - * gets current position of cursor - * @return current position of cursor - */ - int32_t getPosition() const; - /* data retrieval */ /*! @@ -260,11 +254,10 @@ public: /*! * - * @return -1 if cursor is in error, otherwise number of rows in result + * @return -1 if cursor is in error, otherwise number of columns in result */ - int32_t getResultCount() const; - int32_t columnCount() const ; + /*! * Current statement is closed and discarded (finalised) * before actual opening occurs @@ -274,8 +267,6 @@ public: bool open(sqlite3_stmt* stm); public: - - /*! * Returns the value of the requested column as a String. * @param columnIndex the zero-based index of the target column. @@ -326,17 +317,8 @@ public: getString(columnIndex, temp); str = T(temp); } - - private: - sqlite3_stmt* mStmt; - int mCount; /// number of results - int mPosCounter; }; - - - - #endif // RSSQLITE_H diff --git a/libretroshare/src/util/rsaes.cc b/libretroshare/src/util/rsaes.cc index 282234008..1703c4d77 100644 --- a/libretroshare/src/util/rsaes.cc +++ b/libretroshare/src/util/rsaes.cc @@ -61,7 +61,10 @@ bool RsAES::aes_crypt_8_16(const uint8_t *input_data,uint32_t input_data_length, int f_len = 0; if(output_data_length < (uint32_t)c_len) - return false ; + { + EVP_CIPHER_CTX_cleanup(&e_ctx) ; + return false ; + } /* update ciphertext, c_len is filled with the length of ciphertext generated, *len is the size of plaintext in bytes */ @@ -69,6 +72,7 @@ bool RsAES::aes_crypt_8_16(const uint8_t *input_data,uint32_t input_data_length, if(!EVP_EncryptUpdate(&e_ctx, output_data, &c_len, input_data, input_data_length)) { std::cerr << "RsAES: decryption failed at end. Check padding." << std::endl; + EVP_CIPHER_CTX_cleanup(&e_ctx) ; return false ; } @@ -76,6 +80,7 @@ bool RsAES::aes_crypt_8_16(const uint8_t *input_data,uint32_t input_data_length, if(!EVP_EncryptFinal_ex(&e_ctx, output_data+c_len, &f_len)) { std::cerr << "RsAES: decryption failed at end. Check padding." << std::endl; + EVP_CIPHER_CTX_cleanup(&e_ctx) ; return false ; } @@ -112,7 +117,10 @@ bool RsAES::aes_decrypt_8_16(const uint8_t *input_data,uint32_t input_data_lengt int f_len = 0; if(output_data_length < (uint32_t)c_len) + { + EVP_CIPHER_CTX_cleanup(&e_ctx) ; return false ; + } output_data_length = c_len ; @@ -122,6 +130,7 @@ bool RsAES::aes_decrypt_8_16(const uint8_t *input_data,uint32_t input_data_lengt if(! EVP_DecryptUpdate(&e_ctx, output_data, &c_len, input_data, input_data_length)) { std::cerr << "RsAES: decryption failed." << std::endl; + EVP_CIPHER_CTX_cleanup(&e_ctx) ; return false ; } @@ -129,6 +138,7 @@ bool RsAES::aes_decrypt_8_16(const uint8_t *input_data,uint32_t input_data_lengt if(!EVP_DecryptFinal_ex(&e_ctx, output_data+c_len, &f_len)) { std::cerr << "RsAES: decryption failed at end. Check padding." << std::endl; + EVP_CIPHER_CTX_cleanup(&e_ctx) ; return false ; } diff --git a/libretroshare/src/util/rsdir.cc b/libretroshare/src/util/rsdir.cc index 4e7ccaeb3..b396b1672 100644 --- a/libretroshare/src/util/rsdir.cc +++ b/libretroshare/src/util/rsdir.cc @@ -27,7 +27,7 @@ // Includes for directory creation. #include #include -#include +#include #include #include "util/rsdir.h" diff --git a/libretroshare/src/util/rsmemory.h b/libretroshare/src/util/rsmemory.h index a7ba409b8..c6b88ed2b 100644 --- a/libretroshare/src/util/rsmemory.h +++ b/libretroshare/src/util/rsmemory.h @@ -21,29 +21,37 @@ // class RsTemporaryMemory { - public: - RsTemporaryMemory(size_t s) - { - _mem = (unsigned char *)malloc(s) ; - } +public: + RsTemporaryMemory(size_t s) + { + _mem = (unsigned char *)malloc(s) ; - operator unsigned char *() { return _mem ; } + if(_mem) + _size = s ; + else + _size = 0 ; + } - ~RsTemporaryMemory() - { - if(_mem != NULL) - { - free(_mem) ; - _mem = NULL ; - } - } + operator unsigned char *() { return _mem ; } + + size_t size() const { return _size ; } - private: - unsigned char *_mem ; + ~RsTemporaryMemory() + { + if(_mem != NULL) + { + free(_mem) ; + _mem = NULL ; + } + } - // make it noncopyable - RsTemporaryMemory& operator=(const RsTemporaryMemory&) { return *this ;} - RsTemporaryMemory(const RsTemporaryMemory&) {} +private: + unsigned char *_mem ; + size_t _size ; + + // make it noncopyable + RsTemporaryMemory& operator=(const RsTemporaryMemory&) { return *this ;} + RsTemporaryMemory(const RsTemporaryMemory&) {} }; diff --git a/libretroshare/src/util/rsnet.cc b/libretroshare/src/util/rsnet.cc index 7ec34c625..0652adfea 100644 --- a/libretroshare/src/util/rsnet.cc +++ b/libretroshare/src/util/rsnet.cc @@ -26,6 +26,7 @@ #include "util/rsnet.h" #include "util/rsthreads.h" #include "util/rsstring.h" +#include "util/rsmemory.h" #ifdef WINDOWS_SYS #else @@ -72,6 +73,40 @@ void sockaddr_clear(struct sockaddr_in *addr) addr->sin_family = AF_INET; } +bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr) +{ +#if defined(WINDOWS_SYS) || defined(__APPLE__) || defined(__HAIKU__) + hostent *result = gethostbyname(hostname.c_str()) ; +#else + RsTemporaryMemory mem(8192) ; + + if(!mem) + { + std::cerr << __PRETTY_FUNCTION__ << ": Cannot allocate memory!" << std::endl; + return false; // Do something. + } + + int error = 0; + struct hostent pHost; + struct hostent *result; + + if(gethostbyname_r(hostname.c_str(), &pHost, (char*)(unsigned char*)mem, mem.size(), &result, &error) != 0) + { + std::cerr << __PRETTY_FUNCTION__ << ": cannot call gethostname_r. Internal error reported. Check buffer size." << std::endl; + return false ; + } +#endif + if(!result) + { + std::cerr << __PRETTY_FUNCTION__ << ": gethostname returned null result." << std::endl; + return false ; + } + // Use contents of result. + + returned_addr.s_addr = *(unsigned long*) (result->h_addr); + + return true ; +} bool isValidNet(const struct in_addr *addr) { diff --git a/libretroshare/src/util/rsnet.h b/libretroshare/src/util/rsnet.h index 2bc06e1cd..61c954822 100644 --- a/libretroshare/src/util/rsnet.h +++ b/libretroshare/src/util/rsnet.h @@ -70,6 +70,9 @@ bool isLoopbackNet(const struct in_addr *addr); bool isPrivateNet(const struct in_addr *addr); bool isExternalNet(const struct in_addr *addr); +// uses a re-entrant version of gethostbyname +bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr) ; + std::ostream& operator<<(std::ostream& o,const struct sockaddr_in&) ; /* thread-safe version of inet_ntoa */ @@ -104,8 +107,6 @@ bool operator<(const struct sockaddr_storage &a, const struct sockaddr_storage & bool sockaddr_storage_same(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); bool sockaddr_storage_samefamily(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); bool sockaddr_storage_sameip(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); -bool sockaddr_storage_samenet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); -bool sockaddr_storage_samesubnet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); // string, std::string sockaddr_storage_tostring(const struct sockaddr_storage &addr); diff --git a/libretroshare/src/util/rsnet_ss.cc b/libretroshare/src/util/rsnet_ss.cc index 0498ccb94..c7b94c89b 100644 --- a/libretroshare/src/util/rsnet_ss.cc +++ b/libretroshare/src/util/rsnet_ss.cc @@ -56,14 +56,10 @@ bool sockaddr_storage_ipv6_setport(struct sockaddr_storage &addr, uint16_t port) bool sockaddr_storage_ipv4_lessthan(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); bool sockaddr_storage_ipv4_same(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); bool sockaddr_storage_ipv4_sameip(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); -bool sockaddr_storage_ipv4_samenet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); -bool sockaddr_storage_ipv4_samesubnet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); bool sockaddr_storage_ipv6_lessthan(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); bool sockaddr_storage_ipv6_same(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); bool sockaddr_storage_ipv6_sameip(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); -bool sockaddr_storage_ipv6_samenet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); -bool sockaddr_storage_ipv6_samesubnet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); /********************************* Output ***********************************/ @@ -373,62 +369,6 @@ bool sockaddr_storage_sameip(const struct sockaddr_storage &addr, const struct s return false; } - -bool sockaddr_storage_samenet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_samenet()"; - std::cerr << std::endl; -#endif - - if (!sockaddr_storage_samefamily(addr, addr2)) - return false; - - switch(addr.ss_family) - { - case AF_INET: - return sockaddr_storage_ipv4_samenet(addr, addr2); - break; - case AF_INET6: - return sockaddr_storage_ipv6_samenet(addr, addr2); - break; - default: - std::cerr << "sockaddr_storage_samenet() INVALID Family - error"; - std::cerr << std::endl; - break; - } - return false; -} - -bool sockaddr_storage_samesubnet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_samesubnet()"; - std::cerr << std::endl; -#endif - - if (!sockaddr_storage_samefamily(addr, addr2)) - return false; - - switch(addr.ss_family) - { - case AF_INET: - return sockaddr_storage_ipv4_samesubnet(addr, addr2); - break; - case AF_INET6: - return sockaddr_storage_ipv6_samesubnet(addr, addr2); - break; - default: -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_samesubnet() INVALID Family - error"; - std::cerr << std::endl; -#endif - break; - } - return false; -} - - /********************************* Output ***********************************/ std::string sockaddr_storage_tostring(const struct sockaddr_storage &addr) @@ -813,38 +753,6 @@ bool sockaddr_storage_ipv4_sameip(const struct sockaddr_storage &addr, const str return (ptr1->sin_addr.s_addr == ptr2->sin_addr.s_addr); } - -bool sockaddr_storage_ipv4_samenet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ - (void) addr; - (void) addr2; - -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_samenet()"; - std::cerr << std::endl; -#endif - - - const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); - const struct sockaddr_in *ptr2 = to_const_ipv4_ptr(addr2); - return sameNet(&(ptr1->sin_addr),&(ptr2->sin_addr)); -} - -bool sockaddr_storage_ipv4_samesubnet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ - (void) addr; - (void) addr2; - -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_samesubnet() using pqinetwork::isSameSubnet()"; - std::cerr << std::endl; -#endif - - const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); - const struct sockaddr_in *ptr2 = to_const_ipv4_ptr(addr2); - return isSameSubnet((struct in_addr *) &(ptr1->sin_addr),(struct in_addr *) &(ptr2->sin_addr)); -} - // IPV6 bool sockaddr_storage_ipv6_lessthan(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) { @@ -906,34 +814,6 @@ bool sockaddr_storage_ipv6_sameip(const struct sockaddr_storage &addr, const str return true; } - -bool sockaddr_storage_ipv6_samenet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ - (void) addr; - (void) addr2; - -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv6_samenet() TODO"; - std::cerr << std::endl; -#endif - - return false; -} - -bool sockaddr_storage_ipv6_samesubnet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ - (void) addr; - (void) addr2; - -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv6_samesubnet() TODO"; - std::cerr << std::endl; -#endif - - return false; -} - - /********************************* Output ***********************************/ std::string sockaddr_storage_ipv4_iptostring(const struct sockaddr_storage &addr) { diff --git a/libretroshare/src/util/smallobject.cc b/libretroshare/src/util/smallobject.cc index 7c4ef0038..3d91e99f9 100644 --- a/libretroshare/src/util/smallobject.cc +++ b/libretroshare/src/util/smallobject.cc @@ -158,6 +158,15 @@ void FixedAllocator::deallocate(void *p) _chunks.pop_back(); } } +uint32_t FixedAllocator::currentSize() const +{ + uint32_t res = 0 ; + + for(uint32_t i=0;i<_chunks.size();++i) + res += (_numBlocks - _chunks[i]->_blocksAvailable) * _blockSize ; + + return res ; +} void FixedAllocator::printStatistics() const { std::cerr << " numBLocks=" << (int)_numBlocks << std::endl; @@ -181,10 +190,17 @@ SmallObjectAllocator::~SmallObjectAllocator() { RsStackMutex m(SmallObject::_mtx) ; - for(std::map::const_iterator it(_pool.begin());it!=_pool.end();++it) - delete it->second ; - + //std::cerr << __PRETTY_FUNCTION__ << " not deleting. Leaving it to the system." << std::endl; + _active = false ; + + uint32_t still_allocated = 0 ; + + for(std::map::const_iterator it(_pool.begin());it!=_pool.end();++it) + still_allocated += it->second->currentSize() ; + //delete it->second ; + + std::cerr << "Memory still in use at end of program: " << still_allocated << " bytes." << std::endl; } void *SmallObjectAllocator::allocate(size_t bytes) diff --git a/libretroshare/src/util/smallobject.h b/libretroshare/src/util/smallobject.h index cec0301f6..a5b11bcc9 100644 --- a/libretroshare/src/util/smallobject.h +++ b/libretroshare/src/util/smallobject.h @@ -68,8 +68,9 @@ namespace RsMemoryManagement return p >= c._data && (static_cast(p)-c._data)/_blockSize < _numBlocks ; } - void printStatistics() const ; - private: + void printStatistics() const ; + uint32_t currentSize() const; + private: size_t _blockSize ; unsigned char _numBlocks ; std::vector _chunks ; diff --git a/msys2_build_libs/Makefile b/msys2_build_libs/Makefile new file mode 100755 index 000000000..1b818d62d --- /dev/null +++ b/msys2_build_libs/Makefile @@ -0,0 +1,41 @@ +TCL_VERSION=8.6.2 +SQLCIPHER_VERSION=2.2.1 + +all: dirs sqlcipher copylibs + +dirs: + mkdir -p libs/include + mkdir -p libs/lib + mkdir -p libs/bin + +tcl$(TCL_VERSION)-src.tar.gz: + curl.exe -L http://prdownloads.sourceforge.net/tcl/tcl$(TCL_VERSION)-src.tar.gz -o tcl$(TCL_VERSION)-src.tar.gz + +sqlcipher-$(SQLCIPHER_VERSION).tar.gz: + curl.exe -L -k https://github.com/sqlcipher/sqlcipher/archive/v$(SQLCIPHER_VERSION).tar.gz -o sqlcipher-$(SQLCIPHER_VERSION).tar.gz + +sqlcipher: tcl$(TCL_VERSION)-src.tar.gz sqlcipher-$(SQLCIPHER_VERSION).tar.gz + # tcl + tar xvf tcl$(TCL_VERSION)-src.tar.gz + mkdir -p tcl$(TCL_VERSION)/build + cd tcl$(TCL_VERSION)/build && ../win/configure + cd tcl$(TCL_VERSION)/build && make + #sqlcipher + tar xvf sqlcipher-$(SQLCIPHER_VERSION).tar.gz + cd sqlcipher-$(SQLCIPHER_VERSION) && ln -s ../tcl$(TCL_VERSION)/build/tclsh86.exe tclsh + mkdir -p tcl$(TCL_VERSION)/lib + ln -s `pwd`/tcl$(TCL_VERSION)/library `pwd`/tcl$(TCL_VERSION)/lib/tcl8.6 + cd sqlcipher-$(SQLCIPHER_VERSION) && PATH=$$PATH:`pwd`/../tcl$(TCL_VERSION)/build && LIBS="-L`pwd`/../libs/lib -lgdi32 $$LIBS" && export LIBS && ./configure --disable-shared --enable-static --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC -I`pwd`/../libs/include -I`pwd`/../tcl$(TCL_VERSION)/generic" LDFLAGS="-L`pwd`/../libs/lib -lcrypto -lgdi32" --with-tcl="`pwd`/../tcl$(TCL_VERSION)/build" && make install prefix="`pwd`/install" + cp -r sqlcipher-$(SQLCIPHER_VERSION)/install/include/* libs/include/ + cp sqlcipher-$(SQLCIPHER_VERSION)/install/lib/libsqlcipher.a libs/lib/ + cp sqlcipher-$(SQLCIPHER_VERSION)/install/bin/sqlcipher.exe libs/bin/ + rm -r -f sqlcipher-$(SQLCIPHER_VERSION) + rm -r -f tcl$(TCL_VERSION) + touch sqlcipher + +copylibs: + read -p "Do you want to copy libs to retroshare? (yes|no)" answer; \ + if [ "$$answer" = "yes" ] ; then \ + cp -r libs ../../ ; \ + fi + diff --git a/openpgpsdk/src/openpgpsdk.pro b/openpgpsdk/src/openpgpsdk.pro index f54f5d7f8..2cee7847d 100644 --- a/openpgpsdk/src/openpgpsdk.pro +++ b/openpgpsdk/src/openpgpsdk.pro @@ -35,10 +35,8 @@ win32 { #QMAKE_CXXFLAGS_DEBUG += -O2 #QMAKE_CFLAGS_DEBUG += -O2 - LIBS_DIR = $$PWD/../../../libs - - DEPENDPATH += $$LIBS_DIR/include - INCLUDEPATH += $$LIBS_DIR/include + DEPENDPATH += $$INC_DIR + INCLUDEPATH += $$INC_DIR } # Input diff --git a/openpgpsdk/src/openpgpsdk/openssl_crypto.c b/openpgpsdk/src/openpgpsdk/openssl_crypto.c index 72f8045c1..c386f7ee0 100644 --- a/openpgpsdk/src/openpgpsdk/openssl_crypto.c +++ b/openpgpsdk/src/openpgpsdk/openssl_crypto.c @@ -595,11 +595,12 @@ int ops_rsa_public_encrypt(unsigned char *out,const unsigned char *in, n=RSA_public_encrypt(length,in,out,orsa,RSA_NO_PADDING); if (n==-1) - { - BIO *fd_out; - fd_out=BIO_new_fd(fileno(stderr), BIO_NOCLOSE); - ERR_print_errors(fd_out); - } + { + BIO *fd_out; + fd_out=BIO_new_fd(fileno(stderr), BIO_NOCLOSE); + ERR_print_errors(fd_out); + BIO_free(fd_out) ; + } orsa->n=orsa->e=NULL; RSA_free(orsa); diff --git a/plugins/Common/retroshare_plugin.pri b/plugins/Common/retroshare_plugin.pri index 3c9644c55..8a5e332b2 100644 --- a/plugins/Common/retroshare_plugin.pri +++ b/plugins/Common/retroshare_plugin.pri @@ -7,7 +7,7 @@ DEPENDPATH += ../../libretroshare/src/ ../../retroshare-gui/src/ INCLUDEPATH += ../../libretroshare/src/ ../../retroshare-gui/src/ unix { - target.path = "$${LIB_DIR}/retroshare/extensions6" + target.path = "$${PLUGIN_DIR}" INSTALLS += target } @@ -37,7 +37,7 @@ win32 { UI_DIR = temp/ui DEFINES += WINDOWS_SYS WIN32 STATICLIB MINGW WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T - DEFINES += MINIUPNPC_VERSION=13 + #DEFINES += MINIUPNPC_VERSION=13 # DESTDIR = lib # Switch off optimization for release version @@ -53,16 +53,16 @@ win32 { DEFINES += USE_CMD_ARGS #miniupnp implementation files - HEADERS += upnp/upnputil.h - SOURCES += upnp/upnputil.c + #HEADERS += upnp/upnputil.h + #SOURCES += upnp/upnputil.c - LIBS_DIR = $$PWD/../../../libs - - INCLUDEPATH += . $$LIBS_DIR/include $$LIBS_DIR/include/miniupnpc + DEPENDPATH += . $$INC_DIR + INCLUDEPATH += . $$INC_DIR PRE_TARGETDEPS += ../../retroshare-gui/src/lib/libretroshare-gui.a LIBS += -L"../../retroshare-gui/src/lib" -lretroshare-gui - LIBS += -L"$$LIBS_DIR/lib" + for(lib, LIB_DIR):LIBS += -L"$$lib" + for(bin, BIN_DIR):LIBS += -L"$$bin" LIBS += -lpthread } diff --git a/plugins/FeedReader/FeedReader.pro b/plugins/FeedReader/FeedReader.pro index 4cebc5f48..8a0862672 100644 --- a/plugins/FeedReader/FeedReader.pro +++ b/plugins/FeedReader/FeedReader.pro @@ -81,25 +81,36 @@ TRANSLATIONS += \ lang/FeedReader_zh_CN.ts linux-* { - LIBXML2_DIR = /usr/include/libxml2 + CONFIG += link_pkgconfig - DEPENDPATH += $${LIBXML2_DIR} - INCLUDEPATH += $${LIBXML2_DIR} - - LIBS += -lcurl -lxml2 -lxslt + PKGCONFIG *= libcurl libxml-2.0 libxslt } win32 { DEFINES += CURL_STATICLIB LIBXML_STATIC LIBXSLT_STATIC LIBEXSLT_STATIC - LIBS += -lcurl -lxml2 -lz -lxslt -lws2_32 -lwldap32 -lssl -lcrypto + #Have to reorder libs, else got /libs/lib/libcrypto.a(bio_lib.o):bio_lib.c:(.text+0x0): multiple definition of `BIO_new' + LIBS = -lcurl -lxml2 -lz -lxslt -lws2_32 -lwldap32 -lssl -lcrypto -lgdi32 $${LIBS} + exists(C:/msys32/mingw32/include) { + message(msys2 xml2 is installed.) + INC_DIR += "C:/msys32/mingw32/include/libxml2" + } + exists(C:/msys64/mingw32/include) { + message(msys2 xml2 is installed.) + INC_DIR += "C:/msys64/mingw32/include/libxml2" + } + DEPENDPATH += . $$INC_DIR + INCLUDEPATH += . $$INC_DIR } openbsd-* { LIBXML2_DIR = /usr/local/include/libxml2 +} + +haiku-* { + LIBXML2_DIR = pkg-config --cflags libxml-2.0 INCLUDEPATH += $${LIBXML2_DIR} LIBS += -lcurl -lxml2 -lxslt } - diff --git a/plugins/VOIP/VOIP.pro b/plugins/VOIP/VOIP.pro index e560a8501..746530290 100644 --- a/plugins/VOIP/VOIP.pro +++ b/plugins/VOIP/VOIP.pro @@ -19,21 +19,68 @@ INCLUDEPATH += ../../retroshare-gui/src/temp/ui ../../libretroshare/src #################################### Windows ##################################### linux-* { - INCLUDEPATH += /usr/include - LIBS += $$system(pkg-config --libs opencv) + CONFIG += link_pkgconfig + + PKGCONFIG += libavcodec libavutil + PKGCONFIG += speex speexdsp + PKGCONFIG += opencv +} else { + LIBS += -lspeex -lspeexdsp -lavcodec -lavutil } win32 { - # ffmpeg - QMAKE_CXXFLAGS += -D__STDC_CONSTANT_MACROS - LIBS_DIR = $$PWD/../../../libs - LIBS += -L"$$LIBS_DIR/lib/opencv" + DEPENDPATH += . $$INC_DIR + INCLUDEPATH += . $$INC_DIR - OPENCV_VERSION = 249 - LIBS += -lopencv_core$$OPENCV_VERSION -lopencv_highgui$$OPENCV_VERSION -lopencv_imgproc$$OPENCV_VERSION -llibjpeg -llibtiff -llibpng -llibjasper -lIlmImf -lole32 -loleaut32 -luuid -lavicap32 -lavifil32 -lvfw32 -lz + OPENCV_VERSION = "249" + USE_PRECOMPILED_LIBS = + for(lib, LIB_DIR) { +#message(Scanning $$lib) + exists( $$lib/opencv/libopencv_core249.a) { + isEmpty(USE_PRECOMPILED_LIBS) { + message(Get pre-compiled opencv 249 libraries here:) + message($$lib) + LIBS += -L"$$lib/opencv" + LIBS += -lopencv_core$$OPENCV_VERSION -lopencv_highgui$$OPENCV_VERSION -lopencv_imgproc$$OPENCV_VERSION + USE_PRECOMPILED_LIBS = 1 + } + } + exists( $$lib/opencv/libopencv_core.a) { + isEmpty(USE_PRECOMPILED_LIBS) { + message(Get pre-compiled opencv libraries here:) + message($$lib) + LIBS += -L"$$lib/opencv" + LIBS += -lopencv_core -lopencv_highgui -lopencv_imgproc + USE_PRECOMPILED_LIBS = 1 + } + } + exists( $$lib/libopencv_core.dll.a) { + isEmpty(USE_PRECOMPILED_LIBS) { + message(Get pre-compiled opencv libraries here:) + message($$lib) + LIBS += -L"$$lib/opencv" + LIBS += -lopencv_core -lopencv_highgui -lopencv_imgproc + USE_PRECOMPILED_LIBS = 1 + } + } + exists( $$lib/libopencv_videoio.dll.a) { + message(videoio found in opencv libraries.) + message($$lib) + LIBS += -lopencv_videoio + } + } + isEmpty(USE_PRECOMPILED_LIBS) { + message(Use system opencv libraries.) + LIBS += -lopencv_core -lopencv_highgui -lopencv_imgproc + } + LIBS += -lz -lole32 -loleaut32 -luuid -lvfw32 -llibjpeg -llibtiff -llibpng -llibjasper -lIlmImf + LIBS += -lavifil32 -lavicap32 -lavcodec -lavutil -lswresample } +# ffmpeg (and libavutil: https://github.com/ffms/ffms2/issues/11) +QMAKE_CXXFLAGS += -D__STDC_CONSTANT_MACROS + QMAKE_CXXFLAGS *= -Wall SOURCES = VOIPPlugin.cpp \ @@ -98,5 +145,3 @@ TRANSLATIONS += \ lang/VOIP_sv.ts \ lang/VOIP_tr.ts \ lang/VOIP_zh_CN.ts - -LIBS += -lspeex -lspeexdsp -lavformat -lavcodec -lavutil diff --git a/plugins/VOIP/VOIPPlugin.cpp b/plugins/VOIP/VOIPPlugin.cpp index 08a2dbac3..ff78a4113 100644 --- a/plugins/VOIP/VOIPPlugin.cpp +++ b/plugins/VOIP/VOIPPlugin.cpp @@ -20,6 +20,7 @@ ****************************************************************/ #include #include +#include #include #include #include @@ -90,14 +91,16 @@ VOIPPlugin::VOIPPlugin() mVOIPGUIHandler = new VOIPGUIHandler ; mVOIPNotify = new VOIPNotify ; - QObject::connect(mVOIPNotify,SIGNAL(voipInvitationReceived(const RsPeerId&)),mVOIPGUIHandler,SLOT(ReceivedInvitation(const RsPeerId&)),Qt::QueuedConnection) ; + QObject::connect(mVOIPNotify,SIGNAL(voipInvitationReceived(const RsPeerId&,int)),mVOIPGUIHandler,SLOT(ReceivedInvitation(const RsPeerId&,int)),Qt::QueuedConnection) ; QObject::connect(mVOIPNotify,SIGNAL(voipDataReceived(const RsPeerId&)),mVOIPGUIHandler,SLOT(ReceivedVoipData(const RsPeerId&)),Qt::QueuedConnection) ; - QObject::connect(mVOIPNotify,SIGNAL(voipAcceptReceived(const RsPeerId&)),mVOIPGUIHandler,SLOT(ReceivedVoipAccept(const RsPeerId&)),Qt::QueuedConnection) ; - QObject::connect(mVOIPNotify,SIGNAL(voipHangUpReceived(const RsPeerId&)),mVOIPGUIHandler,SLOT(ReceivedVoipHangUp(const RsPeerId&)),Qt::QueuedConnection) ; + QObject::connect(mVOIPNotify,SIGNAL(voipAcceptReceived(const RsPeerId&,int)),mVOIPGUIHandler,SLOT(ReceivedVoipAccept(const RsPeerId&,int)),Qt::QueuedConnection) ; + QObject::connect(mVOIPNotify,SIGNAL(voipHangUpReceived(const RsPeerId&,int)),mVOIPGUIHandler,SLOT(ReceivedVoipHangUp(const RsPeerId&,int)),Qt::QueuedConnection) ; QObject::connect(mVOIPNotify,SIGNAL(voipBandwidthInfoReceived(const RsPeerId&,int)),mVOIPGUIHandler,SLOT(ReceivedVoipBandwidthInfo(const RsPeerId&,int)),Qt::QueuedConnection) ; Q_INIT_RESOURCE(VOIP_images); Q_INIT_RESOURCE(VOIP_qss); + + avcodec_register_all(); } void VOIPPlugin::setInterfaces(RsPlugInInterfaces &interfaces) @@ -211,9 +214,26 @@ QTranslator* VOIPPlugin::qt_translator(QApplication */*app*/, const QString& lan return NULL; } -void VOIPPlugin::qt_sound_events(SoundEvents &/*events*/) const +void VOIPPlugin::qt_sound_events(SoundEvents &events) const { -// events.addEvent(QApplication::translate("VOIP", "VOIP"), QApplication::translate("VOIP", "Incoming call"), VOIP_SOUND_INCOMING_CALL); + QDir baseDir = QDir(QString::fromUtf8(RsAccounts::DataDirectory().c_str()) + "/sounds"); + + events.addEvent(QApplication::translate("VOIP", "VOIP") + , QApplication::translate("VOIP", "Incoming audio call") + , VOIP_SOUND_INCOMING_AUDIO_CALL + , QFileInfo(baseDir, "incomingcall.wav").absoluteFilePath()); + events.addEvent(QApplication::translate("VOIP", "VOIP") + , QApplication::translate("VOIP", "Incoming video call") + , VOIP_SOUND_INCOMING_VIDEO_CALL + , QFileInfo(baseDir, "incomingcall.wav").absoluteFilePath()); + events.addEvent(QApplication::translate("VOIP", "VOIP") + , QApplication::translate("VOIP", "Outgoing audio call") + , VOIP_SOUND_OUTGOING_AUDIO_CALL + , QFileInfo(baseDir, "outgoingcall.wav").absoluteFilePath()); + events.addEvent(QApplication::translate("VOIP", "VOIP") + , QApplication::translate("VOIP", "Outgoing video call") + , VOIP_SOUND_OUTGOING_VIDEO_CALL + , QFileInfo(baseDir, "outgoingcall.wav").absoluteFilePath()); } ToasterNotify *VOIPPlugin::qt_toasterNotify(){ diff --git a/plugins/VOIP/VOIPPlugin.h b/plugins/VOIP/VOIPPlugin.h index 3ea4aeefb..f399f05b5 100644 --- a/plugins/VOIP/VOIPPlugin.h +++ b/plugins/VOIP/VOIPPlugin.h @@ -37,6 +37,7 @@ class VOIPPlugin: public RsPlugin virtual ~VOIPPlugin() {} virtual p3Service *p3_service() const ; + virtual p3Config *p3_config() const { return mVOIP; } virtual uint16_t rs_service_id() const { return RS_SERVICE_TYPE_VOIP_PLUGIN ; } virtual ConfigPage *qt_config_page() const ; virtual QDialog *qt_about_page() const ; diff --git a/plugins/VOIP/gui/AudioInputConfig.cpp b/plugins/VOIP/gui/AudioInputConfig.cpp index d1503040b..b2add04e6 100644 --- a/plugins/VOIP/gui/AudioInputConfig.cpp +++ b/plugins/VOIP/gui/AudioInputConfig.cpp @@ -140,18 +140,18 @@ void AudioInputConfig::updateAvailableBW(double r) std::cerr << "Setting max bandwidth to " << r << " KB/s" << std::endl; videoProcessor->setMaximumBandwidth((uint32_t)(r*1024)) ; } - + void AudioInputConfig::togglePreview(bool b) { if(b) { videoInput->setEchoVideoTarget(NULL) ; - videoProcessor->setDisplayTarget(ui.videoDisplay) ; + videoProcessor->setDisplayTarget(ui.videoDisplay) ; } else { + videoProcessor->setDisplayTarget(NULL) ; videoInput->setEchoVideoTarget(ui.videoDisplay) ; - videoProcessor->setDisplayTarget(NULL) ; } } diff --git a/plugins/VOIP/gui/QVideoDevice.cpp b/plugins/VOIP/gui/QVideoDevice.cpp index b81b7b79c..5e6b66fce 100644 --- a/plugins/VOIP/gui/QVideoDevice.cpp +++ b/plugins/VOIP/gui/QVideoDevice.cpp @@ -31,21 +31,23 @@ void QVideoInputDevice::stop() } if(_capture_device != NULL) { - cvReleaseCapture(&_capture_device) ; + // the camera will be deinitialized automatically in VideoCapture destructor + _capture_device->release(); + delete _capture_device ; _capture_device = NULL ; } } void QVideoInputDevice::start() { - // make sure everything is re-initialised + // make sure everything is re-initialised // stop() ; - // Initialise la capture + // Initialise la capture static const int cam_id = 0 ; - _capture_device = cvCaptureFromCAM(cam_id); + _capture_device = new cv::VideoCapture(cam_id); - if(_capture_device == NULL) + if(!_capture_device->isOpened()) { std::cerr << "Cannot initialise camera. Something's wrong." << std::endl; return ; @@ -61,52 +63,51 @@ void QVideoInputDevice::grabFrame() { if(!_timer) return ; - - IplImage *img=cvQueryFrame(_capture_device); - if(img == NULL) + cv::Mat frame; + if(!_capture_device->read(frame)) { - std::cerr << "(EE) Cannot capture image from camera. Something's wrong." << std::endl; - return ; + std::cerr << "(EE) Cannot capture image from camera. Something's wrong." << std::endl; + return ; } + // get the image data - if(img->nChannels != 3) + if(frame.channels() != 3) { - std::cerr << "(EE) expected 3 channels. Got " << img->nChannels << std::endl; - return ; + std::cerr << "(EE) expected 3 channels. Got " << frame.channels() << std::endl; + return ; } // convert to RGB and copy to new buffer, because cvQueryFrame tells us to not modify the buffer cv::Mat img_rgb; - cv::cvtColor(cv::Mat(img), img_rgb, CV_BGR2RGB); - + cv::cvtColor(frame, img_rgb, CV_BGR2RGB); QImage image = QImage(img_rgb.data,img_rgb.cols,img_rgb.rows,QImage::Format_RGB888); - if(_video_processor != NULL) + if(_video_processor != NULL) { - _video_processor->processImage(image) ; + _video_processor->processImage(image) ; - emit networkPacketReady() ; + emit networkPacketReady() ; } - if(_echo_output_device != NULL) - _echo_output_device->showFrame(image) ; + if(_echo_output_device != NULL) + _echo_output_device->showFrame(image) ; } bool QVideoInputDevice::getNextEncodedPacket(RsVOIPDataChunk& chunk) { if(!_timer) return false ; - + if(_video_processor) - return _video_processor->nextEncodedPacket(chunk) ; - else + return _video_processor->nextEncodedPacket(chunk) ; + else return false ; } uint32_t QVideoInputDevice::currentBandwidth() const { - return _video_processor->currentBandwidthOut() ; + return _video_processor->currentBandwidthOut() ; } QVideoInputDevice::~QVideoInputDevice() @@ -117,19 +118,20 @@ QVideoInputDevice::~QVideoInputDevice() QVideoOutputDevice::QVideoOutputDevice(QWidget *parent) - : QLabel(parent) + : QLabel(parent) { showFrameOff() ; } void QVideoOutputDevice::showFrameOff() { - setPixmap(QPixmap(":/images/video-icon-big.png").scaled(320,256,Qt::KeepAspectRatio,Qt::SmoothTransformation)) ; + setPixmap(QPixmap(":/images/video-icon-big.png").scaled(QSize(height()*4/3,height()),Qt::KeepAspectRatio,Qt::SmoothTransformation)) ; + setAlignment(Qt::AlignCenter); } void QVideoOutputDevice::showFrame(const QImage& img) { std::cerr << "img.size = " << img.width() << " x " << img.height() << std::endl; - setPixmap(QPixmap::fromImage(img).scaled( QSize(height()*640/480,height()),Qt::IgnoreAspectRatio,Qt::SmoothTransformation)) ; + setPixmap(QPixmap::fromImage(img).scaled( QSize(height()*4/3,height()),Qt::IgnoreAspectRatio,Qt::SmoothTransformation)) ; } diff --git a/plugins/VOIP/gui/QVideoDevice.h b/plugins/VOIP/gui/QVideoDevice.h index cc92302a2..f1f4659ba 100644 --- a/plugins/VOIP/gui/QVideoDevice.h +++ b/plugins/VOIP/gui/QVideoDevice.h @@ -2,10 +2,12 @@ #include #include "interface/rsVOIP.h" + +#include "opencv2/opencv.hpp" + #include "gui/VideoProcessor.h" class VideoEncoder ; -class CvCapture ; // Responsible from displaying the video. The source of the video is // a VideoDecoder object, which uses a codec. @@ -61,7 +63,7 @@ protected slots: private: VideoProcessor *_video_processor ; QTimer *_timer ; - CvCapture *_capture_device ; + cv::VideoCapture *_capture_device ; QVideoOutputDevice *_echo_output_device ; diff --git a/plugins/VOIP/gui/VOIPChatWidgetHolder.cpp b/plugins/VOIP/gui/VOIPChatWidgetHolder.cpp index f8760132d..87a5d2f5e 100644 --- a/plugins/VOIP/gui/VOIPChatWidgetHolder.cpp +++ b/plugins/VOIP/gui/VOIPChatWidgetHolder.cpp @@ -18,22 +18,25 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. ****************************************************************/ -#include -#include +//C++ +#include +//Qt #include #include - +#include +#include +//VOIP #include #include "interface/rsVOIP.h" +#include "VOIPChatWidgetHolder.h" +#include "VideoProcessor.h" +#include "QVideoDevice.h" +//retroshare GUI #include "gui/SoundManager.h" #include "util/HandleRichText.h" #include "gui/common/StatusDefs.h" #include "gui/chat/ChatWidget.h" - -#include "VOIPChatWidgetHolder.h" -#include "VideoProcessor.h" -#include "QVideoDevice.h" - +//libretroshare #include #include @@ -45,77 +48,122 @@ VOIPChatWidgetHolder::VOIPChatWidgetHolder(ChatWidget *chatWidget, VOIPNotify *notify) : QObject(), ChatWidgetHolder(chatWidget), mVOIPNotify(notify) { - QIcon icon ; - icon.addPixmap(QPixmap(":/images/audio-volume-muted.png")) ; - icon.addPixmap(QPixmap(":/images/audio-volume-high.png"),QIcon::Normal,QIcon::On) ; - icon.addPixmap(QPixmap(":/images/audio-volume-high.png"),QIcon::Disabled,QIcon::On) ; - icon.addPixmap(QPixmap(":/images/audio-volume-high.png"),QIcon::Active,QIcon::On) ; - icon.addPixmap(QPixmap(":/images/audio-volume-high.png"),QIcon::Selected,QIcon::On) ; + int S = QFontMetricsF(chatWidget->font()).height() ; + QSize iconSize = QSize(3*S,3*S); + QSize buttonSize = QSize(iconSize + QSize(3,3)); + + QIcon iconaudioListenToggleButton ; + iconaudioListenToggleButton.addPixmap(QPixmap(":/images/audio-volume-muted.png")) ; + iconaudioListenToggleButton.addPixmap(QPixmap(":/images/audio-volume-high.png"),QIcon::Normal,QIcon::On) ; + iconaudioListenToggleButton.addPixmap(QPixmap(":/images/audio-volume-high.png"),QIcon::Disabled,QIcon::On) ; + iconaudioListenToggleButton.addPixmap(QPixmap(":/images/audio-volume-high.png"),QIcon::Active,QIcon::On) ; + iconaudioListenToggleButton.addPixmap(QPixmap(":/images/audio-volume-high.png"),QIcon::Selected,QIcon::On) ; audioListenToggleButton = new QToolButton ; - audioListenToggleButton->setIcon(icon) ; - audioListenToggleButton->setIconSize(QSize(42,42)) ; - audioListenToggleButton->setAutoRaise(true) ; + audioListenToggleButton->setIcon(iconaudioListenToggleButton) ; + audioListenToggleButton->setIconSize(iconSize) ; + audioListenToggleButton->setMinimumSize(buttonSize) ; + audioListenToggleButton->setMaximumSize(buttonSize) ; audioListenToggleButton->setCheckable(true); - audioListenToggleButton->setMinimumSize(QSize(44,44)) ; - audioListenToggleButton->setMaximumSize(QSize(44,44)) ; + audioListenToggleButton->setAutoRaise(true) ; audioListenToggleButton->setText(QString()) ; audioListenToggleButton->setToolTip(tr("Mute")); + audioListenToggleButton->setEnabled(false); - QIcon icon2 ; - icon2.addPixmap(QPixmap(":/images/call-start.png")) ; - icon2.addPixmap(QPixmap(":/images/call-hold.png"),QIcon::Normal,QIcon::On) ; - icon2.addPixmap(QPixmap(":/images/call-hold.png"),QIcon::Disabled,QIcon::On) ; - icon2.addPixmap(QPixmap(":/images/call-hold.png"),QIcon::Active,QIcon::On) ; - icon2.addPixmap(QPixmap(":/images/call-hold.png"),QIcon::Selected,QIcon::On) ; + QIcon iconaudioCaptureToggleButton ; + iconaudioCaptureToggleButton.addPixmap(QPixmap(":/images/call-start.png")) ; + iconaudioCaptureToggleButton.addPixmap(QPixmap(":/images/call-hold.png"),QIcon::Normal,QIcon::On) ; + iconaudioCaptureToggleButton.addPixmap(QPixmap(":/images/call-hold.png"),QIcon::Disabled,QIcon::On) ; + iconaudioCaptureToggleButton.addPixmap(QPixmap(":/images/call-hold.png"),QIcon::Active,QIcon::On) ; + iconaudioCaptureToggleButton.addPixmap(QPixmap(":/images/call-hold.png"),QIcon::Selected,QIcon::On) ; audioCaptureToggleButton = new QToolButton ; - audioCaptureToggleButton->setMinimumSize(QSize(44,44)) ; - audioCaptureToggleButton->setMaximumSize(QSize(44,44)) ; + audioCaptureToggleButton->setIcon(iconaudioCaptureToggleButton) ; + audioCaptureToggleButton->setIconSize(iconSize) ; + audioCaptureToggleButton->setMinimumSize(buttonSize) ; + audioCaptureToggleButton->setMaximumSize(buttonSize) ; + audioCaptureToggleButton->setCheckable(true) ; + audioCaptureToggleButton->setAutoRaise(true) ; audioCaptureToggleButton->setText(QString()) ; audioCaptureToggleButton->setToolTip(tr("Start Call")); - audioCaptureToggleButton->setIcon(icon2) ; - audioCaptureToggleButton->setIconSize(QSize(42,42)) ; - audioCaptureToggleButton->setAutoRaise(true) ; - audioCaptureToggleButton->setCheckable(true) ; - - hangupButton = new QToolButton ; - hangupButton->setIcon(QIcon(":/images/call-stop.png")) ; - hangupButton->setIconSize(QSize(42,42)) ; - hangupButton->setMinimumSize(QSize(44,44)) ; - hangupButton->setMaximumSize(QSize(44,44)) ; - hangupButton->setCheckable(false) ; - hangupButton->setAutoRaise(true) ; - hangupButton->setText(QString()) ; - hangupButton->setToolTip(tr("Hangup Call")); - hangupButton->hide(); - QIcon icon3 ; - icon3.addPixmap(QPixmap(":/images/video-icon-on.png")) ; - icon3.addPixmap(QPixmap(":/images/video-icon-off.png"),QIcon::Normal,QIcon::On) ; - icon3.addPixmap(QPixmap(":/images/video-icon-off.png"),QIcon::Disabled,QIcon::On) ; - icon3.addPixmap(QPixmap(":/images/video-icon-off.png"),QIcon::Active,QIcon::On) ; - icon3.addPixmap(QPixmap(":/images/video-icon-off.png"),QIcon::Selected,QIcon::On) ; + QIcon iconvideoCaptureToggleButton ; + iconvideoCaptureToggleButton.addPixmap(QPixmap(":/images/video-icon-on.png")) ; + iconvideoCaptureToggleButton.addPixmap(QPixmap(":/images/video-icon-off.png"),QIcon::Normal,QIcon::On) ; + iconvideoCaptureToggleButton.addPixmap(QPixmap(":/images/video-icon-off.png"),QIcon::Disabled,QIcon::On) ; + iconvideoCaptureToggleButton.addPixmap(QPixmap(":/images/video-icon-off.png"),QIcon::Active,QIcon::On) ; + iconvideoCaptureToggleButton.addPixmap(QPixmap(":/images/video-icon-off.png"),QIcon::Selected,QIcon::On) ; videoCaptureToggleButton = new QToolButton ; - videoCaptureToggleButton->setMinimumSize(QSize(44,44)) ; - videoCaptureToggleButton->setMaximumSize(QSize(44,44)) ; + videoCaptureToggleButton->setIcon(iconvideoCaptureToggleButton) ; + videoCaptureToggleButton->setIconSize(iconSize) ; + videoCaptureToggleButton->setMinimumSize(buttonSize) ; + videoCaptureToggleButton->setMaximumSize(buttonSize) ; + videoCaptureToggleButton->setCheckable(true) ; + videoCaptureToggleButton->setAutoRaise(true) ; videoCaptureToggleButton->setText(QString()) ; videoCaptureToggleButton->setToolTip(tr("Start Video Call")); - videoCaptureToggleButton->setIcon(icon3) ; - videoCaptureToggleButton->setIconSize(QSize(42,42)) ; - videoCaptureToggleButton->setAutoRaise(true) ; - videoCaptureToggleButton->setCheckable(true) ; - connect(videoCaptureToggleButton, SIGNAL(clicked()), this , SLOT(toggleVideoCapture())); + hangupButton = new QToolButton ; + hangupButton->setIcon(QIcon(":/images/call-stop.png")) ; + hangupButton->setIconSize(iconSize) ; + hangupButton->setMinimumSize(buttonSize) ; + hangupButton->setMaximumSize(buttonSize) ; + hangupButton->setCheckable(false) ; + hangupButton->setAutoRaise(true) ; + hangupButton->setText(QString()) ; + hangupButton->setToolTip(tr("Hangup Call")); + hangupButton->hide(); + + QIcon iconhideChatTextToggleButton ; + iconhideChatTextToggleButton.addPixmap(QPixmap(":/images/orange-bubble-64.png")) ; + iconhideChatTextToggleButton.addPixmap(QPixmap(":/images/white-bubble-64.png"),QIcon::Normal,QIcon::On) ; + iconhideChatTextToggleButton.addPixmap(QPixmap(":/images/white-bubble-64.png"),QIcon::Disabled,QIcon::On) ; + iconhideChatTextToggleButton.addPixmap(QPixmap(":/images/white-bubble-64.png"),QIcon::Active,QIcon::On) ; + iconhideChatTextToggleButton.addPixmap(QPixmap(":/images/white-bubble-64.png"),QIcon::Selected,QIcon::On) ; + + hideChatTextToggleButton = new QToolButton ; + hideChatTextToggleButton->setIcon(iconhideChatTextToggleButton) ; + hideChatTextToggleButton->setIconSize(iconSize) ; + hideChatTextToggleButton->setMinimumSize(buttonSize) ; + hideChatTextToggleButton->setMaximumSize(buttonSize) ; + hideChatTextToggleButton->setCheckable(true) ; + hideChatTextToggleButton->setAutoRaise(true) ; + hideChatTextToggleButton->setText(QString()) ; + hideChatTextToggleButton->setToolTip(tr("Hide Chat Text")); + hideChatTextToggleButton->setEnabled(false) ; + + QIcon iconfullscreenToggleButton ; + iconfullscreenToggleButton.addPixmap(QPixmap(":/images/channels32.png")) ; + iconfullscreenToggleButton.addPixmap(QPixmap(":/images/folder-draft24.png"),QIcon::Normal,QIcon::On) ; + iconfullscreenToggleButton.addPixmap(QPixmap(":/images/folder-draft24.png"),QIcon::Disabled,QIcon::On) ; + iconfullscreenToggleButton.addPixmap(QPixmap(":/images/folder-draft24.png"),QIcon::Active,QIcon::On) ; + iconfullscreenToggleButton.addPixmap(QPixmap(":/images/folder-draft24.png"),QIcon::Selected,QIcon::On) ; + + fullscreenToggleButton = new QToolButton ; + fullscreenToggleButton->setIcon(iconfullscreenToggleButton) ; + fullscreenToggleButton->setIconSize(iconSize) ; + fullscreenToggleButton->setMinimumSize(buttonSize) ; + fullscreenToggleButton->setMaximumSize(buttonSize) ; + fullscreenToggleButton->setCheckable(true) ; + fullscreenToggleButton->setAutoRaise(true) ; + fullscreenToggleButton->setText(QString()) ; + fullscreenToggleButton->setToolTip(tr("Fullscreen mode")); + fullscreenToggleButton->setEnabled(false) ; + connect(audioListenToggleButton, SIGNAL(clicked()), this , SLOT(toggleAudioListen())); connect(audioCaptureToggleButton, SIGNAL(clicked()), this , SLOT(toggleAudioCapture())); + connect(videoCaptureToggleButton, SIGNAL(clicked()), this , SLOT(toggleVideoCapture())); connect(hangupButton, SIGNAL(clicked()), this , SLOT(hangupCall())); + connect(hideChatTextToggleButton, SIGNAL(clicked()), this , SLOT(toggleHideChatText())); + connect(fullscreenToggleButton, SIGNAL(clicked()), this , SLOT(toggleFullScreen())); - mChatWidget->addVOIPBarWidget(audioListenToggleButton) ; - mChatWidget->addVOIPBarWidget(audioCaptureToggleButton) ; - mChatWidget->addVOIPBarWidget(hangupButton) ; - mChatWidget->addVOIPBarWidget(videoCaptureToggleButton) ; + mChatWidget->addTitleBarWidget(audioListenToggleButton) ; + mChatWidget->addTitleBarWidget(audioCaptureToggleButton) ; + mChatWidget->addTitleBarWidget(videoCaptureToggleButton) ; + mChatWidget->addTitleBarWidget(hangupButton) ; + mChatWidget->addTitleBarWidget(hideChatTextToggleButton) ; + mChatWidget->addTitleBarWidget(fullscreenToggleButton) ; outputAudioProcessor = NULL ; outputAudioDevice = NULL ; @@ -134,31 +182,359 @@ VOIPChatWidgetHolder::VOIPChatWidgetHolder(ChatWidget *chatWidget, VOIPNotify *n connect(inputVideoDevice, SIGNAL(networkPacketReady()), this, SLOT(sendVideoData())); - echoVideoDevice->setMinimumSize(320,256) ; - outputVideoDevice->setMinimumSize(320,256) ; + echoVideoDevice->setMinimumSize(320,240) ;//4/3 + outputVideoDevice->setMinimumSize(320,240) ;//4/3 + + echoVideoDevice->showFrameOff(); + outputVideoDevice->showFrameOff(); echoVideoDevice->setStyleSheet("border: 4px solid #CCCCCC; border-radius: 4px;"); outputVideoDevice->setStyleSheet("border: 4px solid #CCCCCC; border-radius: 4px;"); + /// FULLSCREEN /// + fullScreenFrame = new QFrame(); + + outputVideoDeviceFS = new QVideoOutputDevice(fullScreenFrame); + outputVideoDeviceFS->setGeometry(QRect(QPoint(0,0),fullScreenFrame->geometry().size())); + outputVideoDeviceFS->showFrameOff(); + + echoVideoDeviceFS = new QVideoOutputDevice(fullScreenFrame); + echoVideoDeviceFS->setGeometry(QRect(QPoint(fullScreenFrame->width(), fullScreenFrame->height()) - QPoint(320,240), QSize(320,240))); + echoVideoDeviceFS->showFrameOff(); + + toolBarFS = new QFrame(fullScreenFrame); + QHBoxLayout *toolBarFSLayout = new QHBoxLayout(toolBarFS); + + audioListenToggleButtonFS = new QToolButton(fullScreenFrame) ; + audioListenToggleButtonFS->setIcon(iconaudioListenToggleButton) ; + audioListenToggleButtonFS->setIconSize(iconSize) ; + audioListenToggleButtonFS->setMinimumSize(buttonSize) ; + audioListenToggleButtonFS->setMaximumSize(buttonSize) ; + audioListenToggleButtonFS->setCheckable(true); + audioListenToggleButtonFS->setAutoRaise(true) ; + audioListenToggleButtonFS->setText(QString()) ; + audioListenToggleButtonFS->setToolTip(tr("Mute")); + + audioCaptureToggleButtonFS = new QToolButton(fullScreenFrame) ; + audioCaptureToggleButtonFS->setIcon(iconaudioCaptureToggleButton) ; + audioCaptureToggleButtonFS->setIconSize(iconSize) ; + audioCaptureToggleButtonFS->setMinimumSize(buttonSize) ; + audioCaptureToggleButtonFS->setMaximumSize(buttonSize) ; + audioCaptureToggleButtonFS->setCheckable(true) ; + audioCaptureToggleButtonFS->setAutoRaise(true) ; + audioCaptureToggleButtonFS->setText(QString()) ; + audioCaptureToggleButtonFS->setToolTip(tr("Start Call")); + + videoCaptureToggleButtonFS = new QToolButton(fullScreenFrame) ; + videoCaptureToggleButtonFS->setIcon(iconvideoCaptureToggleButton) ; + videoCaptureToggleButtonFS->setIconSize(iconSize) ; + videoCaptureToggleButtonFS->setMinimumSize(buttonSize) ; + videoCaptureToggleButtonFS->setMaximumSize(buttonSize) ; + videoCaptureToggleButtonFS->setCheckable(true) ; + videoCaptureToggleButtonFS->setAutoRaise(true) ; + videoCaptureToggleButtonFS->setText(QString()) ; + videoCaptureToggleButtonFS->setToolTip(tr("Start Video Call")); + + hangupButtonFS = new QToolButton(fullScreenFrame) ; + hangupButtonFS->setIcon(QIcon(":/images/call-stop.png")) ; + hangupButtonFS->setIconSize(iconSize) ; + hangupButtonFS->setMinimumSize(buttonSize) ; + hangupButtonFS->setMaximumSize(buttonSize) ; + hangupButtonFS->setCheckable(false) ; + hangupButtonFS->setAutoRaise(true) ; + hangupButtonFS->setText(QString()) ; + hangupButtonFS->setToolTip(tr("Hangup Call")); + hangupButtonFS->hide(); + + fullscreenToggleButtonFS = new QToolButton(fullScreenFrame); + fullscreenToggleButtonFS->setIcon(iconfullscreenToggleButton); + fullscreenToggleButtonFS->setIconSize(iconSize); + fullscreenToggleButtonFS->setMinimumSize(buttonSize); + fullscreenToggleButtonFS->setMaximumSize(buttonSize); + fullscreenToggleButtonFS->setCheckable(true); + fullscreenToggleButtonFS->setAutoRaise(true); + fullscreenToggleButtonFS->setText(QString()); + fullscreenToggleButtonFS->setToolTip(tr("Fullscreen mode")); + fullscreenToggleButtonFS->setEnabled(false); + + connect(audioListenToggleButtonFS, SIGNAL(clicked()), this , SLOT(toggleAudioListenFS())); + connect(audioCaptureToggleButtonFS, SIGNAL(clicked()), this , SLOT(toggleAudioCaptureFS())); + connect(videoCaptureToggleButtonFS, SIGNAL(clicked()), this , SLOT(toggleVideoCaptureFS())); + connect(hangupButtonFS, SIGNAL(clicked()), this , SLOT(hangupCall())); + connect(fullscreenToggleButtonFS, SIGNAL(clicked()), this , SLOT(toggleFullScreenFS())); + + toolBarFSLayout->setDirection(QBoxLayout::LeftToRight); + toolBarFSLayout->setSpacing(2); + toolBarFSLayout->setSizeConstraint(QLayout::SetMinAndMaxSize); + toolBarFSLayout->addWidget(audioListenToggleButtonFS); + toolBarFSLayout->addWidget(audioCaptureToggleButtonFS); + toolBarFSLayout->addWidget(videoCaptureToggleButtonFS); + toolBarFSLayout->addWidget(hangupButtonFS); + toolBarFSLayout->addWidget(fullscreenToggleButtonFS); + toolBarFS->setLayout(toolBarFSLayout); + + fullScreenFrame->setParent(0); + fullScreenFrame->setWindowFlags(Qt::WindowStaysOnTopHint); + fullScreenFrame->setFocusPolicy(Qt::StrongFocus); + fullScreenFrame->setWindowState(Qt::WindowFullScreen); + fullScreenFrame->hide(); + fullScreenFrame->installEventFilter(this); + mChatWidget->addChatHorizontalWidget(videoWidget) ; inputVideoDevice->setEchoVideoTarget(echoVideoDevice) ; inputVideoDevice->setVideoProcessor(videoProcessor) ; videoProcessor->setDisplayTarget(outputVideoDevice) ; + + //Ring + pbAudioRing = new QProgressBar(); + pbAudioRing->setOrientation(Qt::Horizontal); + pbAudioRing->setRange(0, 99); + pbAudioRing->setTextVisible(false); + pbAudioRing->setHidden(true); + pbVideoRing = new QProgressBar(); + pbVideoRing->setOrientation(Qt::Horizontal); + pbVideoRing->setRange(0, 99); + pbVideoRing->setTextVisible(false); + pbVideoRing->setHidden(true); + mChatWidget->addChatBarWidget(pbAudioRing); + mChatWidget->addChatBarWidget(pbVideoRing); + + sendAudioRingTime = -1; + sendVideoRingTime = -1; + recAudioRingTime = -1; + recVideoRingTime = -1; + + timerAudioRing = new QTimer(this); + timerAudioRing->setInterval(300); + timerAudioRing->setSingleShot(true); + connect(timerAudioRing, SIGNAL(timeout()), this, SLOT(timerAudioRingTimeOut())); + timerVideoRing = new QTimer(this); + timerVideoRing->setInterval(300); + timerVideoRing->setSingleShot(true); + connect(timerVideoRing, SIGNAL(timeout()), this, SLOT(timerVideoRingTimeOut())); + + lastTimePlayOccurs = time(NULL); } VOIPChatWidgetHolder::~VOIPChatWidgetHolder() { + hangupCall(); + if(inputAudioDevice != NULL) inputAudioDevice->stop() ; delete inputVideoDevice ; delete videoProcessor ; + deleteButtonMap(); - button_map::iterator it = buttonMapTakeVideo.begin(); - while (it != buttonMapTakeVideo.end()) { - it = buttonMapTakeVideo.erase(it); - } + // stop and delete timers + timerAudioRing->stop(); + delete(timerAudioRing); + timerVideoRing->stop(); + delete(timerVideoRing); +} + +void VOIPChatWidgetHolder::deleteButtonMap(int flags) +{ + button_map::iterator it = buttonMapTakeCall.begin(); + while (it != buttonMapTakeCall.end()) { + if (((it.key().left(1) == "a") && (flags & RS_VOIP_FLAGS_AUDIO_DATA)) + || ((it.key().left(1) == "v") && (flags & RS_VOIP_FLAGS_VIDEO_DATA)) ) { + QPair pair = it.value(); + delete pair.second; + delete pair.first; + if (flags & RS_VOIP_FLAGS_AUDIO_DATA) recAudioRingTime = -1; + if (flags & RS_VOIP_FLAGS_VIDEO_DATA) recVideoRingTime = -1; + it = buttonMapTakeCall.erase(it); + } else { + ++it; + } + } +} + +void VOIPChatWidgetHolder::addNewAudioButtonMap(const RsPeerId &peer_id) +{ + if (mChatWidget) { + recAudioRingTime = 0; + timerAudioRingTimeOut(); + + QString buttonName = QString::fromUtf8(rsPeers->getPeerName(peer_id).c_str()); + if (buttonName.isEmpty()) buttonName = QString::fromStdString(peer_id.toStdString().c_str()); + if (buttonName.isEmpty()) buttonName = "VoIP"; + button_map::iterator it = buttonMapTakeCall.find(QString("a").append(buttonName)); + if (it == buttonMapTakeCall.end()){ + mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() + , tr("%1 inviting you to start an audio conversation. Do you want Accept or Decline the invitation?").arg(buttonName), ChatWidget::MSGTYPE_SYSTEM); + + RSButtonOnText *buttonT = mChatWidget->getNewButtonOnTextBrowser(tr("Accept Audio Call")); + buttonT->setToolTip(tr("Activate audio")); + buttonT->setStyleSheet(QString("border: 1px solid #199909;") + .append("font-size: 12pt; color: white;") + .append("min-width: 128px; min-height: 24px;") + .append("border-radius: 6px;") + .append("padding: 3px;") + .append("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(122, 230, 110, 255)," + "stop:0.494318 rgba(36, 191, 16, 255), stop:0.505682 rgba(26, 162, 9, 255), stop:1 rgba(17, 106, 6, 255));") + ); + + buttonT->updateImage(); + + connect(buttonT,SIGNAL(clicked()),this,SLOT(startAudioCapture())); + connect(buttonT,SIGNAL(mouseEnter()),this,SLOT(botMouseEnterTake())); + connect(buttonT,SIGNAL(mouseLeave()),this,SLOT(botMouseLeaveTake())); + + RSButtonOnText *buttonD = mChatWidget->getNewButtonOnTextBrowser(tr("Decline Audio Call")); + buttonD->setToolTip(tr("Refuse audio call")); + buttonD->setStyleSheet(QString("border: 1px solid #6a1106;") + .append("font-size: 12pt; color: white;") + .append("min-width: 128px; min-height: 24px;") + .append("border-radius: 6px;") + .append("padding: 3px;") + .append("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(230, 124, 110, 255), stop:0.494318 rgba(191, 35, 16, 255), " + "stop:0.505682 rgba(162, 26, 9, 255), stop:1 rgba(106, 17, 6, 255));") + ); + + buttonD->updateImage(); + + connect(buttonD,SIGNAL(clicked()),this,SLOT(hangupCallAudio())); + connect(buttonD,SIGNAL(mouseEnter()),this,SLOT(botMouseEnterDecline())); + connect(buttonD,SIGNAL(mouseLeave()),this,SLOT(botMouseLeaveDecline())); + + buttonMapTakeCall.insert(QString("a").append(buttonName), QPair(buttonT, buttonD)); + } + } +} + +void VOIPChatWidgetHolder::addNewVideoButtonMap(const RsPeerId &peer_id) +{ + if (mChatWidget) { + recVideoRingTime = 0; + timerVideoRingTimeOut(); + + QString buttonName = QString::fromUtf8(rsPeers->getPeerName(peer_id).c_str()); + if (buttonName.isEmpty()) buttonName = QString::fromStdString(peer_id.toStdString().c_str()); + if (buttonName.isEmpty()) buttonName = "VoIP"; + button_map::iterator it = buttonMapTakeCall.find(QString("v").append(buttonName)); + if (it == buttonMapTakeCall.end()){ + mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() + , tr("%1 inviting you to start a video conversation. Do you want Accept or Decline the invitation?").arg(buttonName), ChatWidget::MSGTYPE_SYSTEM); + + RSButtonOnText *buttonT = mChatWidget->getNewButtonOnTextBrowser(tr("Accept Video Call")); + buttonT->setToolTip(tr("Activate camera")); + buttonT->setStyleSheet(QString("border: 1px solid #199909;") + .append("font-size: 12pt; color: white;") + .append("min-width: 128px; min-height: 24px;") + .append("border-radius: 6px;") + .append("padding: 3px;") + .append("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(122, 230, 110, 255)," + "stop:0.494318 rgba(36, 191, 16, 255), stop:0.505682 rgba(26, 162, 9, 255), stop:1 rgba(17, 106, 6, 255));") + ); + + buttonT->updateImage(); + + connect(buttonT,SIGNAL(clicked()),this,SLOT(startVideoCapture())); + connect(buttonT,SIGNAL(mouseEnter()),this,SLOT(botMouseEnterTake())); + connect(buttonT,SIGNAL(mouseLeave()),this,SLOT(botMouseLeaveTake())); + + RSButtonOnText *buttonD = mChatWidget->getNewButtonOnTextBrowser(tr("Decline Video Call")); + buttonD->setToolTip(tr("Refuse video call")); + buttonD->setStyleSheet(QString("border: 1px solid #6a1106;") + .append("font-size: 12pt; color: white;") + .append("min-width: 128px; min-height: 24px;") + .append("border-radius: 6px;") + .append("padding: 3px;") + .append("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(230, 124, 110, 255), stop:0.494318 rgba(191, 35, 16, 255), " + "stop:0.505682 rgba(162, 26, 9, 255), stop:1 rgba(106, 17, 6, 255));") + ); + + buttonD->updateImage(); + + connect(buttonD,SIGNAL(clicked()),this,SLOT(hangupCallVideo())); + connect(buttonD,SIGNAL(mouseEnter()),this,SLOT(botMouseEnterDecline())); + connect(buttonD,SIGNAL(mouseLeave()),this,SLOT(botMouseLeaveDecline())); + + buttonMapTakeCall.insert(QString("v").append(buttonName), QPair(buttonT, buttonD)); + } + } +} + +bool VOIPChatWidgetHolder::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == fullScreenFrame) { + if (event->type() == QEvent::Close || event->type() == QEvent::MouseButtonDblClick) { + showNormalView(); + } + if (event->type() == QEvent::Resize) { + replaceFullscreenWidget(); + } + + } + // pass the event on to the parent class + return QObject::eventFilter(obj, event); +} + +void VOIPChatWidgetHolder::hangupCall() +{ + hangupCallAudio(); + hangupCallVideo(); + hangupButton->hide(); + hangupButtonFS->hide(); + deleteButtonMap(); +} + +void VOIPChatWidgetHolder::hangupCallAudio() +{ + bool atLeastOneChecked = false; + if (audioCaptureToggleButton->isChecked()) { + audioCaptureToggleButton->setChecked(false); + toggleAudioCapture(); + atLeastOneChecked = true; + } + if (!atLeastOneChecked) { + //Decline button ,Friend hang up or chat close + if (recAudioRingTime != -1) { + rsVOIP->sendVoipHangUpCall(mChatWidget->getChatId().toPeerId(), RS_VOIP_FLAGS_AUDIO_DATA); + deleteButtonMap(RS_VOIP_FLAGS_AUDIO_DATA); + } + sendAudioRingTime = -1; + recAudioRingTime = -1; + } +} + +void VOIPChatWidgetHolder::hangupCallVideo() +{ + bool atLeastOneChecked = false; + if (videoCaptureToggleButton->isChecked()) { + videoCaptureToggleButton->setChecked(false); + toggleVideoCapture(); + atLeastOneChecked = true; + } + if (fullscreenToggleButton->isChecked()) { + fullscreenToggleButton->setChecked(false); + toggleFullScreen(); + atLeastOneChecked = true; + } + if (hideChatTextToggleButton->isChecked()) { + hideChatTextToggleButton->setChecked(false); + toggleHideChatText(); + atLeastOneChecked = true; + } + if (!atLeastOneChecked) { + //Decline button ,Friend hang up or chat close + if (recVideoRingTime != -1) { + rsVOIP->sendVoipHangUpCall(mChatWidget->getChatId().toPeerId(), RS_VOIP_FLAGS_VIDEO_DATA); + deleteButtonMap(RS_VOIP_FLAGS_VIDEO_DATA); + } + sendVideoRingTime = -1; + recVideoRingTime = -1; + } +} + +void VOIPChatWidgetHolder::toggleAudioListenFS() +{ + audioListenToggleButton->setChecked(audioListenToggleButtonFS->isChecked()); + toggleAudioListen(); } void VOIPChatWidgetHolder::toggleAudioListen() @@ -172,193 +548,335 @@ void VOIPChatWidgetHolder::toggleAudioListen() outputAudioDevice->stop(); }*/ } -} - -void VOIPChatWidgetHolder::hangupCall() -{ - disconnect(inputAudioProcessor, SIGNAL(networkPacketReady()), this, SLOT(sendAudioData())); - if (inputAudioDevice) { - inputAudioDevice->stop(); - } - if (outputAudioDevice) { - outputAudioDevice->stop(); - } - - if (mChatWidget) { - mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime(), tr("Outgoing Call stopped."), ChatWidget::MSGTYPE_SYSTEM); - } - - audioListenToggleButton->setChecked(false); - audioCaptureToggleButton->setChecked(false); - hangupButton->hide(); + audioListenToggleButtonFS->setChecked(audioListenToggleButton->isChecked()); + audioListenToggleButtonFS->setToolTip(audioListenToggleButton->toolTip()); } void VOIPChatWidgetHolder::startAudioCapture() { + recAudioRingTime = -2; audioCaptureToggleButton->setChecked(true); toggleAudioCapture(); } +void VOIPChatWidgetHolder::toggleAudioCaptureFS() +{ + audioCaptureToggleButton->setChecked(audioCaptureToggleButtonFS->isChecked()); + toggleAudioCapture(); +} + void VOIPChatWidgetHolder::toggleAudioCapture() { - if (audioCaptureToggleButton->isChecked()) { - //activate audio output - audioListenToggleButton->setChecked(true); - audioCaptureToggleButton->setToolTip(tr("Hold Call")); - hangupButton->show(); + if (audioCaptureToggleButton->isChecked()) { + if (recAudioRingTime == -1) { + if (sendAudioRingTime == -1) { + sendAudioRingTime = 0; + timerAudioRingTimeOut(); + rsVOIP->sendVoipRinging(mChatWidget->getChatId().toPeerId(), RS_VOIP_FLAGS_AUDIO_DATA); + return; //Start Audio when accept received + } + } + if (recAudioRingTime != -1) + rsVOIP->sendVoipAcceptCall(mChatWidget->getChatId().toPeerId(), RS_VOIP_FLAGS_AUDIO_DATA); + recAudioRingTime = -1; //Stop ringing - //activate audio input - if (!inputAudioProcessor) { - inputAudioProcessor = new QtSpeex::SpeexInputProcessor(); - if (outputAudioProcessor) { - connect(outputAudioProcessor, SIGNAL(playingFrame(QByteArray*)), inputAudioProcessor, SLOT(addEchoFrame(QByteArray*))); - } - inputAudioProcessor->open(QIODevice::WriteOnly | QIODevice::Unbuffered); - } - if (!inputAudioDevice) { - inputAudioDevice = AudioDeviceHelper::getPreferedInputDevice(); - } - connect(inputAudioProcessor, SIGNAL(networkPacketReady()), this, SLOT(sendAudioData())); - inputAudioDevice->start(inputAudioProcessor); - - if (mChatWidget) { - mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime(), tr("Outgoing Call is started..."), ChatWidget::MSGTYPE_SYSTEM); - } - - button_map::iterator it = buttonMapTakeVideo.begin(); - while (it != buttonMapTakeVideo.end()) { - RSButtonOnText *button = it.value(); - delete button; - it = buttonMapTakeVideo.erase(it); - } - - } else { - disconnect(inputAudioProcessor, SIGNAL(networkPacketReady()), this, SLOT(sendAudioData())); - if (inputAudioDevice) { - inputAudioDevice->stop(); - } - audioCaptureToggleButton->setToolTip(tr("Resume Call")); - hangupButton->hide(); - } + //activate buttons + audioListenToggleButton->setEnabled(true); + audioListenToggleButton->setChecked(true); + audioListenToggleButtonFS->setEnabled(true); + audioListenToggleButtonFS->setChecked(true); + audioCaptureToggleButton->setToolTip(tr("Hold Call")); + hangupButton->show(); + hangupButtonFS->show(); + + //activate audio input + if (!inputAudioProcessor) { + inputAudioProcessor = new QtSpeex::SpeexInputProcessor(); + if (outputAudioProcessor) { + connect(outputAudioProcessor, SIGNAL(playingFrame(QByteArray*)), inputAudioProcessor, SLOT(addEchoFrame(QByteArray*))); + } + inputAudioProcessor->open(QIODevice::WriteOnly | QIODevice::Unbuffered); + } + if (!inputAudioDevice) { + inputAudioDevice = AudioDeviceHelper::getPreferedInputDevice(); + } + connect(inputAudioProcessor, SIGNAL(networkPacketReady()), this, SLOT(sendAudioData())); + inputAudioDevice->start(inputAudioProcessor); + + //send system message + if (mChatWidget) + mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime(), tr("Outgoing Call is started..."), ChatWidget::MSGTYPE_SYSTEM); + + deleteButtonMap(RS_VOIP_FLAGS_AUDIO_DATA); + } else { + //desactivate buttons + audioListenToggleButton->setEnabled(false); + audioListenToggleButton->setChecked(false); + audioListenToggleButtonFS->setEnabled(false); + audioListenToggleButtonFS->setChecked(false); + audioCaptureToggleButton->setToolTip(tr("Resume Call")); + if (!videoCaptureToggleButton->isChecked()) { + hangupButton->hide(); + hangupButtonFS->hide(); + } + + if (recAudioRingTime <= -1){ + //desactivate audio input + disconnect(inputAudioProcessor, SIGNAL(networkPacketReady()), this, SLOT(sendAudioData())); + if (inputAudioDevice) { + inputAudioDevice->stop(); + } + + //send system message + if (mChatWidget) + mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() + , tr("Outgoing Audio Call stopped."), ChatWidget::MSGTYPE_SYSTEM); + + rsVOIP->sendVoipHangUpCall(mChatWidget->getChatId().toPeerId(), RS_VOIP_FLAGS_AUDIO_DATA); + } + + sendAudioRingTime = -1; + recAudioRingTime = -1; + + } + audioCaptureToggleButtonFS->setChecked(audioCaptureToggleButton->isChecked()); + audioCaptureToggleButtonFS->setToolTip(audioCaptureToggleButton->toolTip()); } void VOIPChatWidgetHolder::startVideoCapture() { + recVideoRingTime = -2; videoCaptureToggleButton->setChecked(true); toggleVideoCapture(); } +void VOIPChatWidgetHolder::toggleVideoCaptureFS() +{ + videoCaptureToggleButton->setChecked(videoCaptureToggleButtonFS->isChecked()); + toggleVideoCapture(); +} + void VOIPChatWidgetHolder::toggleVideoCapture() { if (videoCaptureToggleButton->isChecked()) { + if (recVideoRingTime == -1) { + if (sendVideoRingTime == -1) { + sendVideoRingTime = 0; + timerVideoRingTimeOut(); + rsVOIP->sendVoipRinging(mChatWidget->getChatId().toPeerId(), RS_VOIP_FLAGS_VIDEO_DATA); + return; //Start Video when accept received + } + } + if (recVideoRingTime != -1) + rsVOIP->sendVoipAcceptCall(mChatWidget->getChatId().toPeerId(), RS_VOIP_FLAGS_VIDEO_DATA); + recVideoRingTime = -1; //Stop ringing + + //activate buttons + hideChatTextToggleButton->setEnabled(true); + fullscreenToggleButton->setEnabled(true); + fullscreenToggleButtonFS->setEnabled(true); + videoCaptureToggleButton->setToolTip(tr("Shut camera off")); + hangupButton->show(); + hangupButtonFS->show(); + //activate video input - // videoWidget->show(); inputVideoDevice->start() ; - videoCaptureToggleButton->setToolTip(tr("Shut camera off")); - - if (mChatWidget) + //send system message + if (mChatWidget) mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() , tr("You're now sending video..."), ChatWidget::MSGTYPE_SYSTEM); - button_map::iterator it = buttonMapTakeVideo.begin(); - while (it != buttonMapTakeVideo.end()) { - RSButtonOnText *button = it.value(); - delete button; - it = buttonMapTakeVideo.erase(it); - } - } - else - { - inputVideoDevice->stop() ; + deleteButtonMap(RS_VOIP_FLAGS_VIDEO_DATA); + } else { + //desactivate buttons + hideChatTextToggleButton->setEnabled(false); + hideChatTextToggleButton->setChecked(false); + toggleHideChatText(); + fullscreenToggleButton->setEnabled(false); + fullscreenToggleButton->setChecked(false); + fullscreenToggleButtonFS->setEnabled(false); + fullscreenToggleButtonFS->setChecked(false); + toggleFullScreen(); videoCaptureToggleButton->setToolTip(tr("Activate camera")); - outputVideoDevice->showFrameOff(); - videoWidget->hide(); - - if (mChatWidget) - mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() - , tr("Video call stopped"), ChatWidget::MSGTYPE_SYSTEM); + if (!audioCaptureToggleButton->isChecked()) { + hangupButton->hide(); + hangupButtonFS->hide(); + } + + if (recVideoRingTime<=-1){ + //desactivate video input + inputVideoDevice->stop() ; + outputVideoDevice->showFrameOff(); + videoWidget->hide(); + + //send system message + if (mChatWidget) + mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() + , tr("Video call stopped"), ChatWidget::MSGTYPE_SYSTEM); + + rsVOIP->sendVoipHangUpCall(mChatWidget->getChatId().toPeerId(), RS_VOIP_FLAGS_VIDEO_DATA); + } + + sendVideoRingTime = -1; + recVideoRingTime = -1; + } + videoCaptureToggleButtonFS->setChecked(videoCaptureToggleButton->isChecked()); + videoCaptureToggleButtonFS->setToolTip(videoCaptureToggleButton->toolTip()); } void VOIPChatWidgetHolder::addVideoData(const RsPeerId &peer_id, QByteArray* array) { - if (!videoCaptureToggleButton->isChecked()) - { - if (mChatWidget) { - QString buttonName = QString::fromUtf8(rsPeers->getPeerName(peer_id).c_str()); - if (buttonName.isEmpty()) buttonName = "VoIP";//TODO maybe change all with GxsId - button_map::iterator it = buttonMapTakeVideo.find(buttonName); - if (it == buttonMapTakeVideo.end()){ - mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() - , tr("%1 inviting you to start a video conversation. do you want Accept or Decline the invitation?").arg(buttonName), ChatWidget::MSGTYPE_SYSTEM); - RSButtonOnText *button = mChatWidget->getNewButtonOnTextBrowser(tr("Accept Video Call")); - button->setToolTip(tr("Activate camera")); - button->setStyleSheet(QString("border: 1px solid #199909;") - .append("font-size: 12pt; color: white;") - .append("min-width: 128px; min-height: 24px;") - .append("border-radius: 6px;") - .append("background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, " - "stop: 0 #22c70d, stop: 1 #116a06);") + sendVideoRingTime = -2;//Receive Video so Accepted + if (!videoCaptureToggleButton->isChecked()) { + addNewVideoButtonMap(peer_id); + return; + } - ); + RsVOIPDataChunk chunk ; + chunk.type = RsVOIPDataChunk::RS_VOIP_DATA_TYPE_VIDEO ; + chunk.size = array->size() ; + chunk.data = array->data() ; - button->updateImage(); + videoProcessor->receiveEncodedData(chunk) ; - connect(button,SIGNAL(clicked()),this,SLOT(startVideoCapture())); - connect(button,SIGNAL(mouseEnter()),this,SLOT(botMouseEnter())); - connect(button,SIGNAL(mouseLeave()),this,SLOT(botMouseLeave())); - - buttonMapTakeVideo.insert(buttonName, button); - } - } - - //TODO make a sound for the incoming call - // soundManager->play(VOIP_SOUND_INCOMING_CALL); - if (mVOIPNotify) mVOIPNotify->notifyReceivedVoipVideoCall(peer_id); - - } - else - { - RsVOIPDataChunk chunk ; - chunk.type = RsVOIPDataChunk::RS_VOIP_DATA_TYPE_VIDEO ; - chunk.size = array->size() ; - chunk.data = array->data() ; - - videoProcessor->receiveEncodedData(chunk) ; - } } -void VOIPChatWidgetHolder::botMouseEnter() +void VOIPChatWidgetHolder::toggleHideChatText() +{ + QBoxLayout *layout = static_cast(videoWidget->layout()); + + if (hideChatTextToggleButton->isChecked()) { + mChatWidget->hideChatText(true); + if (layout) layout->setDirection(QBoxLayout::LeftToRight); + hideChatTextToggleButton->setToolTip(tr("Show Chat Text")); + } else { + mChatWidget->hideChatText(false); + if (layout) layout->setDirection(QBoxLayout::TopToBottom); + hideChatTextToggleButton->setToolTip(tr("Hide Chat Text")); + fullscreenToggleButton->setChecked(false); + toggleFullScreen(); + } +} + +void VOIPChatWidgetHolder::toggleFullScreenFS() +{ + fullscreenToggleButton->setChecked(fullscreenToggleButtonFS->isChecked()); + toggleFullScreen(); +} + +void VOIPChatWidgetHolder::toggleFullScreen() +{ + if (fullscreenToggleButton->isChecked()) { + fullscreenToggleButton->setToolTip(tr("Return to normal view.")); + inputVideoDevice->setEchoVideoTarget(echoVideoDeviceFS) ; + videoProcessor->setDisplayTarget(outputVideoDeviceFS) ; + fullScreenFrame->show(); + } else { + mChatWidget->hideChatText(false); + fullscreenToggleButton->setToolTip(tr("Fullscreen mode")); + inputVideoDevice->setEchoVideoTarget(echoVideoDevice) ; + videoProcessor->setDisplayTarget(outputVideoDevice) ; + fullScreenFrame->hide(); + } + fullscreenToggleButtonFS->setChecked(fullscreenToggleButton->isChecked()); + fullscreenToggleButtonFS->setToolTip(fullscreenToggleButton->toolTip()); +} + +void VOIPChatWidgetHolder::replaceFullscreenWidget() +{ + if (QSize(toolBarFS->geometry().size() - fullScreenFrame->geometry().size()).isValid()){ + QRect fsRect = fullScreenFrame->geometry(); + fsRect.setSize(toolBarFS->geometry().size()); + fullScreenFrame->setGeometry(fsRect); + } + + outputVideoDeviceFS->setGeometry(QRect(QPoint(0,0),fullScreenFrame->geometry().size())); + echoVideoDeviceFS->setGeometry(QRect(QPoint(fullScreenFrame->width(), fullScreenFrame->height()) - QPoint(320,240), QSize(320,240))); + QRect toolBarFSGeo = QRect( (fullScreenFrame->width() - toolBarFS->geometry().width()) / 2 + , fullScreenFrame->height() - (toolBarFS->geometry().height() * 2) + , toolBarFS->geometry().width(), toolBarFS->geometry().height()); + toolBarFS->setGeometry(toolBarFSGeo); + + if (!videoCaptureToggleButton->isChecked()) { + outputVideoDeviceFS->showFrameOff(); + echoVideoDeviceFS->showFrameOff(); + } +} + +void VOIPChatWidgetHolder::showNormalView() +{ + hideChatTextToggleButton->setChecked(false); + toggleHideChatText(); + fullscreenToggleButton->setChecked(false); + fullscreenToggleButtonFS->setChecked(false); + toggleFullScreen(); +} + +void VOIPChatWidgetHolder::botMouseEnterTake() { RSButtonOnText *source = qobject_cast(QObject::sender()); if (source){ source->setStyleSheet(QString("border: 1px solid #333333;") - .append("font-size: 12pt; color: white;") - .append("min-width: 128px; min-height: 24px;") - .append("border-radius: 6px;") - .append("background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, " - "stop: 0 #444444, stop: 1 #222222);") + .append("font-size: 12pt; color: white;") + .append("min-width: 128px; min-height: 24px;") + .append("border-radius: 6px;") + .append("padding: 3px;") + .append("background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, " + "stop: 0 #444444, stop: 1 #222222);") - ); + ); //source->setDown(true); } } -void VOIPChatWidgetHolder::botMouseLeave() +void VOIPChatWidgetHolder::botMouseLeaveTake() { RSButtonOnText *source = qobject_cast(QObject::sender()); if (source){ - source->setStyleSheet(QString("border: 1px solid #199909;") - .append("font-size: 12pt; color: white;") - .append("min-width: 128px; min-height: 24px;") - .append("border-radius: 6px;") - .append("background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, " - "stop: 0 #22c70d, stop: 1 #116a06);") + source->setStyleSheet(QString("border: 1px solid #116a06;") + .append("font-size: 12pt; color: white;") + .append("min-width: 128px; min-height: 24px;") + .append("border-radius: 6px;") + .append("padding: 3px;") + .append("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(153, 240, 143, 255)," + "stop:0.494318 rgba(59, 201, 40, 255), stop:0.505682 rgba(46, 172, 29, 255), stop:1 rgba(30, 116, 20, 255));") + ); + //source->setDown(false); + } +} - ); +void VOIPChatWidgetHolder::botMouseEnterDecline() +{ + RSButtonOnText *source = qobject_cast(QObject::sender()); + if (source){ + source->setStyleSheet(QString("border: 1px solid #333333;") + .append("font-size: 12pt; color: white;") + .append("min-width: 128px; min-height: 24px;") + .append("border-radius: 6px;") + .append("padding: 3px;") + .append("background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, " + "stop: 0 #444444, stop: 1 #222222);") + ); + //source->setDown(true); + } +} + +void VOIPChatWidgetHolder::botMouseLeaveDecline() +{ + RSButtonOnText *source = qobject_cast(QObject::sender()); + if (source){ + source->setStyleSheet(QString("border: 1px solid #6a1106;") + .append("font-size: 12pt; color: white;") + .append("min-width: 128px; min-height: 24px;") + .append("border-radius: 6px;") + .append("padding: 3px;") + .append("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(240, 154, 143, 255), " + "stop:0.494318 rgba(201, 57, 40, 255), stop:0.505682 rgba(172, 45, 29, 255), stop:1 rgba(116, 30, 20, 255));") + ); //source->setDown(false); } } @@ -370,57 +888,9 @@ void VOIPChatWidgetHolder::setAcceptedBandwidth(uint32_t bytes_per_sec) void VOIPChatWidgetHolder::addAudioData(const RsPeerId &peer_id, QByteArray* array) { + sendAudioRingTime = -2;//Receive Audio so Accepted if (!audioCaptureToggleButton->isChecked()) { - //launch an animation. Don't launch it if already animating - if (!audioCaptureToggleButton->graphicsEffect() || - (audioCaptureToggleButton->graphicsEffect()->inherits("QGraphicsOpacityEffect") && - ((QGraphicsOpacityEffect*)audioCaptureToggleButton->graphicsEffect())->opacity() == 1) - ) { - QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(audioListenToggleButton); - audioCaptureToggleButton->setGraphicsEffect(effect); - QPropertyAnimation *anim = new QPropertyAnimation(effect, "opacity", effect); - anim->setStartValue(1); - anim->setKeyValueAt(0.5,0); - anim->setEndValue(1); - anim->setDuration(400); - anim->start(); - } - - if (mChatWidget) { - QString buttonName = QString::fromUtf8(rsPeers->getPeerName(peer_id).c_str()); - if (buttonName.isEmpty()) buttonName = "VoIP";//TODO maybe change all with GxsId - button_map::iterator it = buttonMapTakeVideo.find(buttonName); - if (it == buttonMapTakeVideo.end()){ - mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() - , tr("%1 inviting you to start a audio conversation. do you want Accept or Decline the invitation?").arg(buttonName), ChatWidget::MSGTYPE_SYSTEM); - RSButtonOnText *button = mChatWidget->getNewButtonOnTextBrowser(tr("Accept Call")); - button->setToolTip(tr("Activate audio")); - button->setStyleSheet(QString("border: 1px solid #199909;") - .append("font-size: 12pt; color: white;") - .append("min-width: 128px; min-height: 24px;") - .append("border-radius: 6px;") - .append("background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, " - "stop: 0 #22c70d, stop: 1 #116a06);") - - ); - - - button->updateImage(); - - connect(button,SIGNAL(clicked()),this,SLOT(startAudioCapture())); - connect(button,SIGNAL(mouseEnter()),this,SLOT(botMouseEnter())); - connect(button,SIGNAL(mouseLeave()),this,SLOT(botMouseLeave())); - - buttonMapTakeVideo.insert(buttonName, button); - } - } - - audioCaptureToggleButton->setToolTip(tr("Answer")); - - //TODO make a sound for the incoming call -// soundManager->play(VOIP_SOUND_INCOMING_CALL); - if (mVOIPNotify) mVOIPNotify->notifyReceivedVoipAudioCall(peer_id); - + addNewAudioButtonMap(peer_id); return; } @@ -462,7 +932,7 @@ void VOIPChatWidgetHolder::sendVideoData() RsVOIPDataChunk chunk ; while(inputVideoDevice && inputVideoDevice->getNextEncodedPacket(chunk)) - rsVOIP->sendVoipData(mChatWidget->getChatId().toPeerId(),chunk) ; + rsVOIP->sendVoipData(mChatWidget->getChatId().toPeerId(),chunk) ; } void VOIPChatWidgetHolder::sendAudioData() @@ -472,22 +942,241 @@ void VOIPChatWidgetHolder::sendAudioData() RsVOIPDataChunk chunk; chunk.size = qbarray.size(); chunk.data = (void*)qbarray.constData(); - chunk.type = RsVOIPDataChunk::RS_VOIP_DATA_TYPE_AUDIO ; + chunk.type = RsVOIPDataChunk::RS_VOIP_DATA_TYPE_AUDIO ; rsVOIP->sendVoipData(mChatWidget->getChatId().toPeerId(),chunk); } } void VOIPChatWidgetHolder::updateStatus(int status) { - audioListenToggleButton->setEnabled(true); - audioCaptureToggleButton->setEnabled(true); - hangupButton->setEnabled(true); - - switch (status) { - case RS_STATUS_OFFLINE: - audioListenToggleButton->setEnabled(false); - audioCaptureToggleButton->setEnabled(false); - hangupButton->setEnabled(false); + bool enabled = (status != RS_STATUS_OFFLINE); + + audioListenToggleButton->setEnabled(audioCaptureToggleButton->isChecked() && enabled); + audioListenToggleButtonFS->setEnabled(audioCaptureToggleButton->isChecked() && enabled); + audioCaptureToggleButton->setEnabled(enabled); + audioCaptureToggleButtonFS->setEnabled(enabled); + videoCaptureToggleButton->setEnabled(enabled); + videoCaptureToggleButtonFS->setEnabled(enabled); + hideChatTextToggleButton->setEnabled(videoCaptureToggleButton->isChecked() && enabled); + fullscreenToggleButton->setEnabled(videoCaptureToggleButton->isChecked() && enabled); + fullscreenToggleButtonFS->setEnabled(videoCaptureToggleButton->isChecked() && enabled); + hangupButton->setEnabled(enabled); + hangupButtonFS->setEnabled(enabled); +} + +void VOIPChatWidgetHolder::ReceivedInvitation(const RsPeerId &peer_id, int flags) +{ + switch(flags){ + case RS_VOIP_FLAGS_AUDIO_DATA: { + if (audioCaptureToggleButton->isChecked()) { + if (recAudioRingTime != -1) + toggleAudioCapture(); + } else { + addNewAudioButtonMap(peer_id); + } + } break; + case RS_VOIP_FLAGS_VIDEO_DATA: { + if (videoCaptureToggleButton->isChecked()) { + if (recVideoRingTime != -1) + toggleVideoCapture(); + } else { + addNewVideoButtonMap(peer_id); + } + } + break; + default: + std::cerr << "VOIPChatWidgetHolder::ReceivedInvitation(): Received unknown flags item # " << flags << ": not handled yet ! Sorry" << std::endl; + break ; + } +} + +void VOIPChatWidgetHolder::ReceivedVoipHangUp(const RsPeerId &peer_id, int flags) +{ + switch(flags){ + case RS_VOIP_FLAGS_AUDIO_DATA | RS_VOIP_FLAGS_VIDEO_DATA: { + if (mChatWidget) { + if (videoCaptureToggleButton->isChecked() || audioCaptureToggleButton->isChecked()) { + QString peerName = QString::fromUtf8(rsPeers->getPeerName(peer_id).c_str()); + mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() + , tr("%1 hang up. Your call is closed.").arg(peerName), ChatWidget::MSGTYPE_SYSTEM); + } + hangupCall(); + } + } + break; + case RS_VOIP_FLAGS_AUDIO_DATA: { + if (mChatWidget) { + if (audioCaptureToggleButton->isChecked()) { + QString peerName = QString::fromUtf8(rsPeers->getPeerName(peer_id).c_str()); + mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() + , tr("%1 hang up. Your audio call is closed.").arg(peerName), ChatWidget::MSGTYPE_SYSTEM); + } + hangupCallAudio(); + } + } + break; + case RS_VOIP_FLAGS_VIDEO_DATA: { + if (mChatWidget) { + if (videoCaptureToggleButton->isChecked()) { + QString peerName = QString::fromUtf8(rsPeers->getPeerName(peer_id).c_str()); + mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() + , tr("%1 hang up. Your video call is closed.").arg(peerName), ChatWidget::MSGTYPE_SYSTEM); + } + hangupCallVideo(); + } + } + break; + default: + std::cerr << "VOIPChatWidgetHolder::ReceivedVoipHangUp(): Received unknown flags item # " << flags << ": not handled yet ! Sorry" << std::endl; + break ; + } + //deleteButtonMap(); +} + +void VOIPChatWidgetHolder::ReceivedVoipAccept(const RsPeerId &peer_id, int flags) +{ + switch(flags){ + case RS_VOIP_FLAGS_AUDIO_DATA: { + if (mChatWidget) { + sendAudioRingTime = -2; + QString peerName = QString::fromUtf8(rsPeers->getPeerName(peer_id).c_str()); + mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() + , tr("%1 accepted your audio call.").arg(peerName), ChatWidget::MSGTYPE_SYSTEM); + if (audioCaptureToggleButton->isChecked()) + toggleAudioCapture(); + } + } + break; + case RS_VOIP_FLAGS_VIDEO_DATA: { + if (mChatWidget) { + sendVideoRingTime = -2; + QString peerName = QString::fromUtf8(rsPeers->getPeerName(peer_id).c_str()); + mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() + , tr("%1 accepted your video call.").arg(peerName), ChatWidget::MSGTYPE_SYSTEM); + if (videoCaptureToggleButton->isChecked()) + toggleVideoCapture(); + } + } + break; + default: + std::cerr << "VOIPChatWidgetHolder::ReceivedVoipHangUp(): Received unknown flags item # " << flags << ": not handled yet ! Sorry" << std::endl; + break ; + } +} + +void VOIPChatWidgetHolder::timerAudioRingTimeOut() +{ + //Sending or receiving (-2 connected, -1 reseted, >=0 in progress) + if (sendAudioRingTime >= 0) { + //Sending + ++sendAudioRingTime; + if (sendAudioRingTime == 100) sendAudioRingTime = 0; + pbAudioRing->setValue(sendAudioRingTime); + pbAudioRing->setToolTip(tr("Waiting your friend respond your audio call.")); + pbAudioRing->setVisible(true); + + if (time(NULL) > lastTimePlayOccurs) { + soundManager->play(VOIP_SOUND_OUTGOING_AUDIO_CALL); + lastTimePlayOccurs = time(NULL) + 1; + } + + timerAudioRing->start(); + } else if(recAudioRingTime >= 0) { + //Receiving + ++recAudioRingTime; + if (recAudioRingTime == 100) recAudioRingTime = 0; + pbAudioRing->setValue(recAudioRingTime); + pbAudioRing->setToolTip(tr("Your friend is calling you for audio. Respond.")); + pbAudioRing->setVisible(true); + + //launch an animation. Don't launch it if already animating + if (!audioCaptureToggleButton->graphicsEffect() + || (audioCaptureToggleButton->graphicsEffect()->inherits("QGraphicsOpacityEffect") + && ((QGraphicsOpacityEffect*)audioCaptureToggleButton->graphicsEffect())->opacity() == 1) + ) { + QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(audioListenToggleButton); + audioCaptureToggleButton->setGraphicsEffect(effect); + QPropertyAnimation *anim = new QPropertyAnimation(effect, "opacity", effect); + anim->setStartValue(1); + anim->setKeyValueAt(0.5,0); + anim->setEndValue(1); + anim->setDuration(timerAudioRing->interval()); + anim->start(); + } + audioCaptureToggleButton->setToolTip(tr("Answer")); + + if (time(NULL) > lastTimePlayOccurs) { + soundManager->play(VOIP_SOUND_INCOMING_AUDIO_CALL); + lastTimePlayOccurs = time(NULL) + 1; + } + + if (mVOIPNotify) mVOIPNotify->notifyReceivedVoipAudioCall(mChatWidget->getChatId().toPeerId()); + + timerAudioRing->start(); + } else { + //Nothing to do, reset stat + pbAudioRing->setHidden(true); + pbAudioRing->setValue(0); + pbAudioRing->setToolTip(""); + audioCaptureToggleButton->setGraphicsEffect(0); + } +} + +void VOIPChatWidgetHolder::timerVideoRingTimeOut() +{ + //Sending or receiving (-2 connected, -1 reseted, >=0 in progress) + if (sendVideoRingTime >= 0) { + //Sending + ++sendVideoRingTime; + if (sendVideoRingTime == 100) sendVideoRingTime = 0; + pbVideoRing->setValue(sendVideoRingTime); + pbVideoRing->setToolTip(tr("Waiting your friend respond your video call.")); + pbVideoRing->setVisible(true); + + if (time(NULL) > lastTimePlayOccurs) { + soundManager->play(VOIP_SOUND_OUTGOING_VIDEO_CALL); + lastTimePlayOccurs = time(NULL) + 1; + } + + timerVideoRing->start(); + } else if(recVideoRingTime >= 0) { + //Receiving + ++recVideoRingTime; + if (recVideoRingTime == 100) recVideoRingTime = 0; + pbVideoRing->setValue(recVideoRingTime); + pbVideoRing->setToolTip(tr("Your friend is calling you for video. Respond.")); + pbVideoRing->setVisible(true); + + //launch an animation. Don't launch it if already animating + if (!videoCaptureToggleButton->graphicsEffect() + || (videoCaptureToggleButton->graphicsEffect()->inherits("QGraphicsOpacityEffect") + && ((QGraphicsOpacityEffect*)videoCaptureToggleButton->graphicsEffect())->opacity() == 1) + ) { + QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(audioListenToggleButton); + videoCaptureToggleButton->setGraphicsEffect(effect); + QPropertyAnimation *anim = new QPropertyAnimation(effect, "opacity", effect); + anim->setStartValue(1); + anim->setKeyValueAt(0.5,0); + anim->setEndValue(1); + anim->setDuration(timerVideoRing->interval()); + anim->start(); + } + videoCaptureToggleButton->setToolTip(tr("Answer")); + + if (time(NULL) > lastTimePlayOccurs) { + soundManager->play(VOIP_SOUND_INCOMING_VIDEO_CALL); + lastTimePlayOccurs = time(NULL) + 1; + } + + if (mVOIPNotify) mVOIPNotify->notifyReceivedVoipVideoCall(mChatWidget->getChatId().toPeerId()); + + timerVideoRing->start(); + } else { + //Nothing to do, reset stat + pbVideoRing->setHidden(true); + pbVideoRing->setValue(0); + pbVideoRing->setToolTip(""); + videoCaptureToggleButton->setGraphicsEffect(0); } } diff --git a/plugins/VOIP/gui/VOIPChatWidgetHolder.h b/plugins/VOIP/gui/VOIPChatWidgetHolder.h index 350f49f2c..666b9c2ab 100644 --- a/plugins/VOIP/gui/VOIPChatWidgetHolder.h +++ b/plugins/VOIP/gui/VOIPChatWidgetHolder.h @@ -20,12 +20,16 @@ ****************************************************************/ #pragma once - -#include "gui/VOIPNotify.h" - +//Qt #include #include +#include +#include +//VOIP +#include "gui/VOIPNotify.h" #include +#include "services/rsVOIPItems.h" +//retroshare-gui #include #include @@ -36,7 +40,10 @@ class QVideoInputDevice ; class QVideoOutputDevice ; class VideoProcessor ; -#define VOIP_SOUND_INCOMING_CALL "VOIP_incoming_call" +#define VOIP_SOUND_INCOMING_AUDIO_CALL "VOIP_incoming_audio_call" +#define VOIP_SOUND_INCOMING_VIDEO_CALL "VOIP_incoming_video_call" +#define VOIP_SOUND_OUTGOING_AUDIO_CALL "VOIP_outgoing_audio_call" +#define VOIP_SOUND_OUTGOING_VIDEO_CALL "VOIP_outgoing_video_call" class VOIPChatWidgetHolder : public QObject, public ChatWidgetHolder { @@ -52,21 +59,46 @@ public: void addVideoData(const RsPeerId &peer_id, QByteArray* array) ; void setAcceptedBandwidth(uint32_t bytes_per_sec) ; + void ReceivedInvitation(const RsPeerId &peer_id, int flags) ; + void ReceivedVoipHangUp(const RsPeerId &peer_id, int flags) ; + void ReceivedVoipAccept(const RsPeerId &peer_id, int flags) ; + public slots: void sendAudioData(); void sendVideoData(); void startAudioCapture(); void startVideoCapture(); + void hangupCallAudio() ; + void hangupCallVideo() ; private slots: void toggleAudioListen(); + void toggleAudioListenFS(); void toggleAudioCapture(); + void toggleAudioCaptureFS(); void toggleVideoCapture(); + void toggleVideoCaptureFS(); + void toggleHideChatText(); + void toggleFullScreen(); + void toggleFullScreenFS(); void hangupCall() ; - void botMouseEnter(); - void botMouseLeave(); + void botMouseEnterTake(); + void botMouseLeaveTake(); + void botMouseEnterDecline(); + void botMouseLeaveDecline(); + void timerAudioRingTimeOut(); + void timerVideoRingTimeOut(); + +private: + void deleteButtonMap(int flags = RS_VOIP_FLAGS_AUDIO_DATA | RS_VOIP_FLAGS_VIDEO_DATA); + void addNewVideoButtonMap(const RsPeerId &peer_id); + void addNewAudioButtonMap(const RsPeerId &peer_id); + void replaceFullscreenWidget(); + void showNormalView(); protected: + bool eventFilter(QObject *obj, QEvent *event); + // Audio input/output QAudioInput* inputAudioDevice; QAudioOutput* outputAudioDevice; @@ -79,18 +111,45 @@ protected: QVideoOutputDevice *echoVideoDevice; QVideoInputDevice *inputVideoDevice; + //For FullScreen Mode + QFrame *fullScreenFrame; + QVideoOutputDevice *outputVideoDeviceFS; + QVideoOutputDevice *echoVideoDeviceFS; + Qt::WindowFlags outputVideoDeviceFlags; + QWidget *videoWidget ; // pointer to call show/hide VideoProcessor *videoProcessor; // Additional buttons to the chat bar QToolButton *audioListenToggleButton ; + QToolButton *audioListenToggleButtonFS ; QToolButton *audioCaptureToggleButton ; + QToolButton *audioCaptureToggleButtonFS ; QToolButton *videoCaptureToggleButton ; + QToolButton *videoCaptureToggleButtonFS ; + QToolButton *hideChatTextToggleButton ; + QToolButton *fullscreenToggleButton ; + QToolButton *fullscreenToggleButtonFS ; QToolButton *hangupButton ; + QToolButton *hangupButtonFS ; + QFrame *toolBarFS; - typedef QMap button_map; - button_map buttonMapTakeVideo; + typedef QMap > button_map; + button_map buttonMapTakeCall; + + //Waiting for peer accept + QProgressBar *pbAudioRing; + QProgressBar *pbVideoRing; + QTimer *timerAudioRing; + QTimer *timerVideoRing; + int sendAudioRingTime; //(-2 connected, -1 reseted, >=0 in progress) + int sendVideoRingTime; //(-2 connected, -1 reseted, >=0 in progress) + int recAudioRingTime; //(-2 connected, -1 reseted, >=0 in progress) + int recVideoRingTime; //(-2 connected, -1 reseted, >=0 in progress) + + //TODO, remove this when soundManager can manage multi events. + int lastTimePlayOccurs; VOIPNotify *mVOIPNotify; }; diff --git a/plugins/VOIP/gui/VOIPGUIHandler.cpp b/plugins/VOIP/gui/VOIPGUIHandler.cpp index 03703d71a..6a7d7d703 100644 --- a/plugins/VOIP/gui/VOIPGUIHandler.cpp +++ b/plugins/VOIP/gui/VOIPGUIHandler.cpp @@ -22,28 +22,89 @@ #include #include #include "VOIPGUIHandler.h" -#include #include + +#include #include "gui/chat/ChatWidget.h" #include "gui/settings/rsharesettings.h" -void VOIPGUIHandler::ReceivedInvitation(const RsPeerId &/*peer_id*/) +void VOIPGUIHandler::ReceivedInvitation(const RsPeerId &peer_id, int flags) { - std::cerr << "****** VOIPGUIHandler: received Invitation!" << std::endl; +#ifdef VOIPGUIHANDLER_DEBUG + std::cerr << "****** VOIPGUIHandler: received Invitation from peer " << peer_id.toStdString() << " with flags==" << flags << std::endl; +#endif + ChatDialog *di = ChatDialog::getChat(ChatId(peer_id), Settings->getChatFlags()); + if (di) { + ChatWidget *cw = di->getChatWidget(); + if(cw) { + const QList &chatWidgetHolderList = cw->chatWidgetHolderList(); + + foreach (ChatWidgetHolder *chatWidgetHolder, chatWidgetHolderList) + { + VOIPChatWidgetHolder *acwh = dynamic_cast(chatWidgetHolder) ; + + if (acwh) + acwh->ReceivedInvitation(peer_id, flags); + } + } + } else { + std::cerr << "VOIPGUIHandler::ReceivedInvitation() Error: received invitaion call for a chat dialog that does not stand VOIP (Peer id = " << peer_id.toStdString() << "!" << std::endl; + } } -void VOIPGUIHandler::ReceivedVoipHangUp(const RsPeerId &/*peer_id*/) +void VOIPGUIHandler::ReceivedVoipHangUp(const RsPeerId &peer_id, int flags) { - std::cerr << "****** VOIPGUIHandler: received HangUp!" << std::endl; +#ifdef VOIPGUIHANDLER_DEBUG + std::cerr << "****** VOIPGUIHandler: received HangUp from peer " << peer_id.toStdString() << " with flags==" << flags << std::endl; +#endif + ChatDialog *di = ChatDialog::getExistingChat(ChatId(peer_id)) ; + if (di) { + ChatWidget *cw = di->getChatWidget(); + if(cw) { + const QList &chatWidgetHolderList = cw->chatWidgetHolderList(); + + foreach (ChatWidgetHolder *chatWidgetHolder, chatWidgetHolderList) + { + VOIPChatWidgetHolder *acwh = dynamic_cast(chatWidgetHolder) ; + + if (acwh) + acwh->ReceivedVoipHangUp(peer_id, flags); + } + } + } else { + std::cerr << "VOIPGUIHandler::ReceivedVoipHangUp() Error: Received hangup call for a chat dialog that does not stand VOIP (Peer id = " << peer_id.toStdString() << "!" << std::endl; + } } -void VOIPGUIHandler::ReceivedVoipAccept(const RsPeerId &/*peer_id*/) +void VOIPGUIHandler::ReceivedVoipAccept(const RsPeerId &peer_id, int flags) { - std::cerr << "****** VOIPGUIHandler: received VoipAccept!" << std::endl; +#ifdef VOIPGUIHANDLER_DEBUG + std::cerr << "****** VOIPGUIHandler: received VoipAccept from peer " << peer_id.toStdString() << " with flags==" << flags << std::endl; +#endif + ChatDialog *di = ChatDialog::getExistingChat(ChatId(peer_id)) ; + if (di) { + ChatWidget *cw = di->getChatWidget(); + if(cw) { + const QList &chatWidgetHolderList = cw->chatWidgetHolderList(); + + foreach (ChatWidgetHolder *chatWidgetHolder, chatWidgetHolderList) + { + VOIPChatWidgetHolder *acwh = dynamic_cast(chatWidgetHolder) ; + + if (acwh) + acwh->ReceivedVoipAccept(peer_id, flags); + } + } + } else { + std::cerr << "VOIPGUIHandler::ReceivedVoipAccept() Error: Received accept call for a chat dialog that does not stand VOIP (Peer id = " << peer_id.toStdString() << "!" << std::endl; + } } void VOIPGUIHandler::ReceivedVoipData(const RsPeerId &peer_id) { +#ifdef VOIPGUIHANDLER_DEBUG + std::cerr << "****** VOIPGUIHandler: received VoipData from peer " << peer_id.toStdString() << std::endl; +#endif std::vector chunks ; if(!rsVOIP->getIncomingData(peer_id,chunks)) @@ -72,14 +133,14 @@ void VOIPGUIHandler::ReceivedVoipData(const RsPeerId &peer_id) else if(chunks[chunkIndex].type == RsVOIPDataChunk::RS_VOIP_DATA_TYPE_VIDEO) acwh->addVideoData(peer_id, &qb); else - std::cerr << "VOIPGUIHandler: Unknown data type received. type=" << chunks[chunkIndex].type << std::endl; + std::cerr << "VOIPGUIHandler::ReceivedVoipData(): Unknown data type received. type=" << chunks[chunkIndex].type << std::endl; } break; } } } } else { - std::cerr << "VOIPGUIHandler Error: received audio data for a chat dialog that does not stand Audio (Peer id = " << peer_id.toStdString() << "!" << std::endl; + std::cerr << "VOIPGUIHandler::ReceivedVoipData() Error: received data for a chat dialog that does not stand VOIP (Peer id = " << peer_id.toStdString() << "!" << std::endl; } for(unsigned int chunkIndex=0; chunkIndexgetChatWidget(); - if(!cw) - { - return ; - } + ChatWidget *cw = di->getChatWidget(); + if(!cw) + { + return ; + } - const QList &chatWidgetHolderList = cw->chatWidgetHolderList(); + const QList &chatWidgetHolderList = cw->chatWidgetHolderList(); - foreach (ChatWidgetHolder *chatWidgetHolder, chatWidgetHolderList) - { - VOIPChatWidgetHolder *acwh = dynamic_cast(chatWidgetHolder) ; + foreach (ChatWidgetHolder *chatWidgetHolder, chatWidgetHolderList) + { + VOIPChatWidgetHolder *acwh = dynamic_cast(chatWidgetHolder) ; - if (acwh) - acwh->setAcceptedBandwidth(bytes_per_sec); + if (acwh) + acwh->setAcceptedBandwidth(bytes_per_sec); + } + } else { + std::cerr << "VOIPGUIHandler::ReceivedVoipBandwidthInfo() Error: received bandwidth info for a chat dialog that does not stand VOIP (Peer id = " << peer_id.toStdString() << "!" << std::endl; } } void VOIPGUIHandler::AnswerAudioCall(const RsPeerId &peer_id) { +#ifdef VOIPGUIHANDLER_DEBUG + std::cerr << "VOIPGUIHandler::Answer to Audio Call for peer " << peer_id.toStdString() << std::endl; +#endif + ChatDialog *di = ChatDialog::getExistingChat(ChatId(peer_id)) ; if (di) { ChatWidget *cw = di->getChatWidget(); @@ -132,9 +199,8 @@ void VOIPGUIHandler::AnswerAudioCall(const RsPeerId &peer_id) } } } else { - std::cerr << "VOIPGUIHandler Error: answer audio call for a chat dialog that does not stand VOIP (Peer id = " << peer_id.toStdString() << "!" << std::endl; + std::cerr << "VOIPGUIHandler::AnswerAudioCall() Error: answer audio call for a chat dialog that does not stand VOIP (Peer id = " << peer_id.toStdString() << "!" << std::endl; } - } void VOIPGUIHandler::AnswerVideoCall(const RsPeerId &peer_id) @@ -154,7 +220,48 @@ void VOIPGUIHandler::AnswerVideoCall(const RsPeerId &peer_id) } } } else { - std::cerr << "VOIPGUIHandler Error: answer video call for a chat dialog that does not stand VOIP (Peer id = " << peer_id.toStdString() << "!" << std::endl; + std::cerr << "VOIPGUIHandler::AnswerVideoCall() Error: answer video call for a chat dialog that does not stand VOIP (Peer id = " << peer_id.toStdString() << "!" << std::endl; + } +} + +void VOIPGUIHandler::HangupAudioCall(const RsPeerId &peer_id) +{ + ChatDialog *di = ChatDialog::getExistingChat(ChatId(peer_id)) ; + if (di) { + ChatWidget *cw = di->getChatWidget(); + if(cw) { + const QList &chatWidgetHolderList = cw->chatWidgetHolderList(); + + foreach (ChatWidgetHolder *chatWidgetHolder, chatWidgetHolderList) + { + VOIPChatWidgetHolder *acwh = dynamic_cast(chatWidgetHolder) ; + + if (acwh) + acwh->hangupCallAudio(); + } + } + } else { + std::cerr << "VOIPGUIHandler::HangupAudioCall() Error: hangup audio call for a chat dialog that does not stand VOIP (Peer id = " << peer_id.toStdString() << "!" << std::endl; + } +} + +void VOIPGUIHandler::HangupVideoCall(const RsPeerId &peer_id) +{ + ChatDialog *di = ChatDialog::getExistingChat(ChatId(peer_id)) ; + if (di) { + ChatWidget *cw = di->getChatWidget(); + if(cw) { + const QList &chatWidgetHolderList = cw->chatWidgetHolderList(); + + foreach (ChatWidgetHolder *chatWidgetHolder, chatWidgetHolderList) + { + VOIPChatWidgetHolder *acwh = dynamic_cast(chatWidgetHolder) ; + + if (acwh) + acwh->hangupCallVideo(); + } + } + } else { + std::cerr << "VOIPGUIHandler::HangupVideoCall() Error: hangup video call for a chat dialog that does not stand VOIP (Peer id = " << peer_id.toStdString() << "!" << std::endl; } - } diff --git a/plugins/VOIP/gui/VOIPGUIHandler.h b/plugins/VOIP/gui/VOIPGUIHandler.h index 69396a084..bacd17451 100644 --- a/plugins/VOIP/gui/VOIPGUIHandler.h +++ b/plugins/VOIP/gui/VOIPGUIHandler.h @@ -32,6 +32,9 @@ #include #include +/*** +#define VOIPGUIHANDLER_DEBUG 1 +***/ class VOIPGUIHandler: public QObject { @@ -39,11 +42,13 @@ class VOIPGUIHandler: public QObject public: static void AnswerAudioCall(const RsPeerId &peer_id) ; static void AnswerVideoCall(const RsPeerId &peer_id) ; + static void HangupAudioCall(const RsPeerId &peer_id) ; + static void HangupVideoCall(const RsPeerId &peer_id) ; public slots: - void ReceivedInvitation(const RsPeerId &peer_id) ; + void ReceivedInvitation(const RsPeerId &peer_id, int flags) ; void ReceivedVoipData(const RsPeerId &peer_id) ; - void ReceivedVoipHangUp(const RsPeerId &peer_id) ; - void ReceivedVoipAccept(const RsPeerId &peer_id) ; + void ReceivedVoipHangUp(const RsPeerId &peer_id, int flags) ; + void ReceivedVoipAccept(const RsPeerId &peer_id, int flags) ; void ReceivedVoipBandwidthInfo(const RsPeerId &peer_id, int) ; }; diff --git a/plugins/VOIP/gui/VOIPNotify.cpp b/plugins/VOIP/gui/VOIPNotify.cpp index 3e954ea70..f2def5ee6 100644 --- a/plugins/VOIP/gui/VOIPNotify.cpp +++ b/plugins/VOIP/gui/VOIPNotify.cpp @@ -23,9 +23,9 @@ //Call qRegisterMetaType("RsPeerId"); to enable these SIGNALs -void VOIPNotify::notifyReceivedVoipAccept(const RsPeerId& peer_id) +void VOIPNotify::notifyReceivedVoipAccept(const RsPeerId& peer_id, const uint32_t flags) { - emit voipAcceptReceived(peer_id) ; + emit voipAcceptReceived(peer_id, flags) ; } void VOIPNotify::notifyReceivedVoipBandwidth(const RsPeerId &peer_id,uint32_t bytes_per_sec) { @@ -35,13 +35,13 @@ void VOIPNotify::notifyReceivedVoipData(const RsPeerId &peer_id) { emit voipDataReceived(peer_id) ; } -void VOIPNotify::notifyReceivedVoipHangUp(const RsPeerId &peer_id) +void VOIPNotify::notifyReceivedVoipHangUp(const RsPeerId &peer_id, const uint32_t flags) { - emit voipHangUpReceived(peer_id) ; + emit voipHangUpReceived(peer_id, flags) ; } -void VOIPNotify::notifyReceivedVoipInvite(const RsPeerId& peer_id) +void VOIPNotify::notifyReceivedVoipInvite(const RsPeerId& peer_id, const uint32_t flags) { - emit voipInvitationReceived(peer_id) ; + emit voipInvitationReceived(peer_id, flags) ; } void VOIPNotify::notifyReceivedVoipAudioCall(const RsPeerId &peer_id) { diff --git a/plugins/VOIP/gui/VOIPNotify.h b/plugins/VOIP/gui/VOIPNotify.h index 4ee1e9e1f..31353f8fc 100644 --- a/plugins/VOIP/gui/VOIPNotify.h +++ b/plugins/VOIP/gui/VOIPNotify.h @@ -38,21 +38,20 @@ class VOIPNotify: public QObject Q_OBJECT public: - void notifyReceivedVoipAccept(const RsPeerId &peer_id) ; + void notifyReceivedVoipAccept(const RsPeerId &peer_id, const uint32_t flags) ; void notifyReceivedVoipBandwidth(const RsPeerId &peer_id, uint32_t bytes_per_sec) ; void notifyReceivedVoipData(const RsPeerId &peer_id) ; - void notifyReceivedVoipHangUp(const RsPeerId &peer_id) ; - void notifyReceivedVoipInvite(const RsPeerId &peer_id) ; + void notifyReceivedVoipHangUp(const RsPeerId &peer_id, const uint32_t flags) ; + void notifyReceivedVoipInvite(const RsPeerId &peer_id, const uint32_t flags) ; void notifyReceivedVoipAudioCall(const RsPeerId &peer_id) ; void notifyReceivedVoipVideoCall(const RsPeerId &peer_id) ; signals: - void voipAcceptReceived(const RsPeerId &peer_id) ; // emitted when the peer accepts the call + void voipAcceptReceived(const RsPeerId &peer_id, int flags) ; // emitted when the peer accepts the call void voipBandwidthInfoReceived(const RsPeerId &peer_id, int bytes_per_sec) ; // emitted when measured bandwidth info is received by the peer. void voipDataReceived(const RsPeerId &peer_id) ; // signal emitted when some voip data has been received - void voipHangUpReceived(const RsPeerId &peer_id) ; // emitted when the peer closes the call (i.e. hangs up) - void voipInvitationReceived(const RsPeerId &peer_id) ; // signal emitted when an invitation has been received - + void voipHangUpReceived(const RsPeerId &peer_id, int flags) ; // emitted when the peer closes the call (i.e. hangs up) + void voipInvitationReceived(const RsPeerId &peer_id, int flags) ; // signal emitted when an invitation has been received void voipAudioCallReceived(const RsPeerId &peer_id) ; // emitted when the peer is calling and own don't send audio void voipVideoCallReceived(const RsPeerId &peer_id) ; // emitted when the peer is calling and own don't send video }; diff --git a/plugins/VOIP/gui/VOIPToasterItem.cpp b/plugins/VOIP/gui/VOIPToasterItem.cpp index f848ea3e6..54659caac 100644 --- a/plugins/VOIP/gui/VOIPToasterItem.cpp +++ b/plugins/VOIP/gui/VOIPToasterItem.cpp @@ -39,18 +39,19 @@ VOIPToasterItem::VOIPToasterItem(const RsPeerId &peer_id, const QString &msg, co switch (mType){ case AudioCall: - toasterButton->setIcon(QIcon("://images/call-start.png")); - toasterButton->setText(tr("Answer")); + //acceptButton->setIcon(QIcon("://images/call-start.png")); + acceptButton->setText(tr("Answer")); break; case VideoCall: - toasterButton->setIcon(QIcon("://images/video-icon-on.png")); - toasterButton->setText(tr("Answer with video")); + acceptButton->setIcon(QIcon("://images/video-icon-on.png")); + acceptButton->setText(tr("Answer with video")); break; default: ChatDialog::chatFriend(ChatId(mPeerId)); } - connect(toasterButton, SIGNAL(clicked()), SLOT(chatButtonSlot())); + connect(acceptButton, SIGNAL(clicked()), SLOT(chatButtonSlot())); + connect(declineButton, SIGNAL(clicked()), SLOT(declineButtonSlot())); connect(closeButton, SIGNAL(clicked()), SLOT(hide())); /* set informations */ @@ -79,7 +80,23 @@ void VOIPToasterItem::chatButtonSlot() hide(); } -void VOIPToasterItem::voipAcceptReceived(const RsPeerId &) +void VOIPToasterItem::declineButtonSlot() +{ + switch (mType){ + case AudioCall: + VOIPGUIHandler::HangupAudioCall(mPeerId); + break; + case VideoCall: + VOIPGUIHandler::HangupVideoCall(mPeerId); + break; + default: + ChatDialog::chatFriend(ChatId(mPeerId)); + } + hide(); +} + +#ifdef VOIPTOASTERNOTIFY_ALL +void VOIPToasterItem::voipAcceptReceived(const RsPeerId &, int ) { } @@ -91,11 +108,11 @@ void VOIPToasterItem::voipDataReceived(const RsPeerId &) { } -void VOIPToasterItem::voipHangUpReceived(const RsPeerId &) +void VOIPToasterItem::voipHangUpReceived(const RsPeerId &, int ) { } -void VOIPToasterItem::voipInvitationReceived(const RsPeerId &) +void VOIPToasterItem::voipInvitationReceived(const RsPeerId &, int ) { } @@ -106,4 +123,4 @@ void VOIPToasterItem::voipAudioCallReceived(const RsPeerId &) void VOIPToasterItem::voipVideoCallReceived(const RsPeerId &) { } - +#endif diff --git a/plugins/VOIP/gui/VOIPToasterItem.h b/plugins/VOIP/gui/VOIPToasterItem.h index dc43bd41c..e796db4e5 100644 --- a/plugins/VOIP/gui/VOIPToasterItem.h +++ b/plugins/VOIP/gui/VOIPToasterItem.h @@ -44,14 +44,17 @@ public: private slots: void chatButtonSlot(); + void declineButtonSlot(); - void voipAcceptReceived(const RsPeerId &peer_id) ; // emitted when the peer accepts the call +#ifdef VOIPTOASTERNOTIFY_ALL + void voipAcceptReceived(const RsPeerId &peer_id, int flags) ; // emitted when the peer accepts the call void voipBandwidthInfoReceived(const RsPeerId &peer_id, int bytes_per_sec) ; // emitted when measured bandwidth info is received by the peer. void voipDataReceived(const RsPeerId &peer_id) ; // signal emitted when some voip data has been received - void voipHangUpReceived(const RsPeerId &peer_id) ; // emitted when the peer closes the call (i.e. hangs up) - void voipInvitationReceived(const RsPeerId &peer_id) ; // signal emitted when an invitation has been received + void voipHangUpReceived(const RsPeerId &peer_id, int flags) ; // emitted when the peer closes the call (i.e. hangs up) + void voipInvitationReceived(const RsPeerId &peer_id, int flags) ; // signal emitted when an invitation has been received void voipAudioCallReceived(const RsPeerId &peer_id) ; // emitted when the peer is calling and own don't send audio void voipVideoCallReceived(const RsPeerId &peer_id) ; // emitted when the peer is calling and own don't send video +#endif private: RsPeerId mPeerId; diff --git a/plugins/VOIP/gui/VOIPToasterItem.ui b/plugins/VOIP/gui/VOIPToasterItem.ui index 758c01165..ef1a3e402 100644 --- a/plugins/VOIP/gui/VOIPToasterItem.ui +++ b/plugins/VOIP/gui/VOIPToasterItem.ui @@ -6,27 +6,36 @@ 0 0 - 300 - 100 + 440 + 102 - 300 + 440 100 - 300 - 100 + 440 + 102 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -38,7 +47,16 @@ QFrame::Raised - + + 2 + + + 2 + + + 2 + + 2 @@ -124,59 +142,36 @@ - - - - - 0 - 24 - - - - - 218 - 24 - - - - - 75 - true - - - - true - - - + + 6 + - + QPushButton{ border: 1px solid #199909; -font-size: 12pt; color: white; +font-size: 12pt; color: white; min-width: 128px; min-height: 24px; border-radius: 6px; -background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, - stop: 0 #22c70d, stop: 1 #116a06); +background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(122, 230, 110, 255), stop:0.494318 rgba(36, 191, 16, 255), stop:0.505682 rgba(26, 162, 9, 255), stop:1 rgba(17, 106, 6, 255)); } QPushButton::hover{ border: 1px solid #199909; font-size: 12pt; color: white; min-width: 128px; min-height: 24px; border-radius: 6px; -background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, - stop: 0 #26df0f, stop: 1 #1db20a); +background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(153, 240, 143, 255), stop:0.494318 rgba(59, 201, 40, 255), stop:0.505682 rgba(46, 172, 29, 255), stop:1 rgba(30, 116, 20, 255)); } QPushButton::pressed{ -border: 1px solid #333333; +border: 1px solid #6a1106; font-size: 12pt; color: white; min-width: 128px; min-height: 24px; border-radius: 6px; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, stop: 0 #444444, stop: 1 #222222); -} +} +
@@ -205,6 +200,70 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, + + + + QPushButton{ +border: 1px solid #6a1106; +font-size: 12pt; color: white; +min-width: 128px; min-height: 24px; +border-radius: 6px; +background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(230, 124, 110, 255), stop:0.494318 rgba(191, 35, 16, 255), stop:0.505682 rgba(162, 26, 9, 255), stop:1 rgba(106, 17, 6, 255)); +} +QPushButton::hover{ +border: 1px solid #6a1106; +font-size: 12pt; color: white; +min-width: 128px; min-height: 24px; +border-radius: 6px; +background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(240, 154, 143, 255), stop:0.494318 rgba(201, 57, 40, 255), stop:0.505682 rgba(172, 45, 29, 255), stop:1 rgba(116, 30, 20, 255)); +} + +QPushButton::pressed{ +border: 1px solid #6a1106; +font-size: 12pt; color: white; +min-width: 128px; min-height: 24px; +border-radius: 6px; +background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, + stop: 0 #444444, stop: 1 #222222); +} + + + + Decline + + + + 22 + 22 + + + + + + + + + 0 + 24 + + + + + 218 + 24 + + + + + 75 + true + + + + true + + + diff --git a/plugins/VOIP/gui/VOIPToasterNotify.cpp b/plugins/VOIP/gui/VOIPToasterNotify.cpp index 050e30925..7d2ef37b4 100644 --- a/plugins/VOIP/gui/VOIPToasterNotify.cpp +++ b/plugins/VOIP/gui/VOIPToasterNotify.cpp @@ -36,11 +36,11 @@ VOIPToasterNotify::VOIPToasterNotify(RsVOIP *VOIP, VOIPNotify *notify, QObject * mMutex = new QMutex(); #ifdef VOIPTOASTERNOTIFY_ALL - connect(mVOIPNotify, SIGNAL(voipAcceptReceived(const RsPeerId&)), this, SLOT(voipAcceptReceived(const RsPeerId&)), Qt::QueuedConnection); + connect(mVOIPNotify, SIGNAL(voipAcceptReceived(const RsPeerId&, int)), this, SLOT(voipAcceptReceived(const RsPeerId&, int)), Qt::QueuedConnection); connect(mVOIPNotify, SIGNAL(voipBandwidthInfoReceived(const RsPeerId&, int)), this, SLOT(voipBandwidthInfoReceived(RsPeerId&, int)), Qt::QueuedConnection); connect(mVOIPNotify, SIGNAL(voipDataReceived(const RsPeerId&)), this, SLOT(voipDataReceived(const RsPeerId&)), Qt::QueuedConnection); - connect(mVOIPNotify, SIGNAL(voipHangUpReceived(const RsPeerId&)), this, SLOT(voipHangUpReceived(const RsPeerId&)), Qt::QueuedConnection); - connect(mVOIPNotify, SIGNAL(voipInvitationReceived(const RsPeerId&)), this, SLOT(voipInvitationReceived(const RsPeerId&)), Qt::QueuedConnection); + connect(mVOIPNotify, SIGNAL(voipHangUpReceived(const RsPeerId&, int)), this, SLOT(voipHangUpReceived(const RsPeerId&, int)), Qt::QueuedConnection); + connect(mVOIPNotify, SIGNAL(voipInvitationReceived(const RsPeerId&, int)), this, SLOT(voipInvitationReceived(const RsPeerId&, int)), Qt::QueuedConnection); #endif connect(mVOIPNotify, SIGNAL(voipAudioCallReceived(const RsPeerId&)), this, SLOT(voipAudioCallReceived(const RsPeerId&)), Qt::QueuedConnection); connect(mVOIPNotify, SIGNAL(voipVideoCallReceived(const RsPeerId&)), this, SLOT(voipVideoCallReceived(const RsPeerId&)), Qt::QueuedConnection); @@ -186,7 +186,7 @@ ToasterItem* VOIPToasterNotify::testToasterItem(QString tag) } #ifdef VOIPTOASTERNOTIFY_ALL -void VOIPToasterNotify::voipAcceptReceived(const RsPeerId &peer_id) +void VOIPToasterNotify::voipAcceptReceived(const RsPeerId &peer_id, int flags) { if (peer_id.isNull()) { return; @@ -258,7 +258,7 @@ void VOIPToasterNotify::voipDataReceived(const RsPeerId &peer_id) mMutex->unlock(); } -void VOIPToasterNotify::voipHangUpReceived(const RsPeerId &peer_id) +void VOIPToasterNotify::voipHangUpReceived(const RsPeerId &peer_id, int flags) { if (peer_id.isNull()) { return; @@ -282,7 +282,7 @@ void VOIPToasterNotify::voipHangUpReceived(const RsPeerId &peer_id) mMutex->unlock(); } -void VOIPToasterNotify::voipInvitationReceived(const RsPeerId &peer_id) +void VOIPToasterNotify::voipInvitationReceived(const RsPeerId &peer_id, int flags) { if (peer_id.isNull()) { return; diff --git a/plugins/VOIP/gui/VOIPToasterNotify.h b/plugins/VOIP/gui/VOIPToasterNotify.h index 7b24a28fb..035589533 100644 --- a/plugins/VOIP/gui/VOIPToasterNotify.h +++ b/plugins/VOIP/gui/VOIPToasterNotify.h @@ -60,11 +60,11 @@ public: private slots: #ifdef VOIPTOASTERNOTIFY_ALL - void voipAcceptReceived(const RsPeerId &peer_id) ; // emitted when the peer accepts the call + void voipAcceptReceived(const RsPeerId &peer_id, int flags) ; // emitted when the peer accepts the call void voipBandwidthInfoReceived(const RsPeerId &peer_id, int bytes_per_sec) ; // emitted when measured bandwidth info is received by the peer. void voipDataReceived(const RsPeerId &peer_id) ; // signal emitted when some voip data has been received - void voipHangUpReceived(const RsPeerId &peer_id) ; // emitted when the peer closes the call (i.e. hangs up) - void voipInvitationReceived(const RsPeerId &peer_id) ; // signal emitted when an invitation has been received + void voipHangUpReceived(const RsPeerId &peer_id, int flags) ; // emitted when the peer closes the call (i.e. hangs up) + void voipInvitationReceived(const RsPeerId &peer_id, int flags) ; // signal emitted when an invitation has been received #endif void voipAudioCallReceived(const RsPeerId &peer_id) ; // emitted when the peer is calling and own don't send audio void voipVideoCallReceived(const RsPeerId &peer_id) ; // emitted when the peer is calling and own don't send video diff --git a/plugins/VOIP/gui/VideoProcessor.cpp b/plugins/VOIP/gui/VideoProcessor.cpp index 20aca0410..68d0adbd6 100644 --- a/plugins/VOIP/gui/VideoProcessor.cpp +++ b/plugins/VOIP/gui/VideoProcessor.cpp @@ -12,37 +12,112 @@ #include #include -#if defined(__MINGW32__) -#define memalign _aligned_malloc -#endif //MINGW - extern "C" { #include #include -#include -#include +//#include +#include #include -#include -#include +//#include +//#include } //#define DEBUG_MPEG_VIDEO 1 +#ifndef AV_INPUT_BUFFER_PADDING_SIZE +#ifndef FF_INPUT_BUFFER_PADDING_SIZE +#define AV_INPUT_BUFFER_PADDING_SIZE 32 +#else +#define AV_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE +#endif +#endif + +#if (LIBAVUTIL_VERSION_MAJOR == 54) && (LIBAVUTIL_VERSION_MINOR == 3) && (LIBAVUTIL_VERSION_MICRO == 0) +//Ubuntu Vivid use other version of rational.h than GIT with LIBAVUTIL_VERSION_MICRO == 0 +#define VIVID_RATIONAL_H_VERSION 1 +#endif + +#if (VIVID_RATIONAL_H_VERSION) || (LIBAVUTIL_VERSION_MAJOR < 52) || ((LIBAVUTIL_VERSION_MAJOR == 52) && (LIBAVUTIL_VERSION_MINOR < 63)) +//since https://github.com/FFmpeg/FFmpeg/commit/3532dd52c51f3d4b95f31d1b195e64a04a8aea5d +static inline AVRational av_make_q(int num, int den) +{ + AVRational r = { num, den }; + return r; +} +#endif + +#if (LIBAVUTIL_VERSION_MAJOR < 55) || ((LIBAVUTIL_VERSION_MAJOR == 55) && (LIBAVUTIL_VERSION_MINOR < 52)) +//since https://github.com/FFmpeg/FFmpeg/commit/fd056029f45a9f6d213d9fce8165632042511d4f +void avcodec_free_context(AVCodecContext **pavctx) +{ + AVCodecContext *avctx = *pavctx; + + if (!avctx) + return; + + avcodec_close(avctx); + + av_freep(&avctx->extradata); + av_freep(&avctx->subtitle_header); + + av_freep(pavctx); +} +#endif + + +#if (LIBAVUTIL_VERSION_MAJOR < 57) || ((LIBAVUTIL_VERSION_MAJOR == 57) && (LIBAVUTIL_VERSION_MINOR < 52)) +//Since https://github.com/FFmpeg/FFmpeg/commit/7ecc2d403ce5c7b6ea3b1f368dccefd105209c7e +static void get_frame_defaults(AVFrame *frame) +{ + if (frame->extended_data != frame->data) + av_freep(&frame->extended_data); + return; + + frame->extended_data = NULL; + get_frame_defaults(frame); + + return; +} + +AVFrame *av_frame_alloc(void) +{ + AVFrame *frame = (AVFrame *)av_mallocz(sizeof(*frame)); + + if (!frame) + return NULL; + + get_frame_defaults(frame); + + return frame; +} + + +void av_frame_free(AVFrame **frame) +{ + if (!frame || !*frame) + return; + + av_freep(frame); +} +#endif + + VideoProcessor::VideoProcessor() :_encoded_frame_size(640,480) , vpMtx("VideoProcessor") { + //_lastTimeToShowFrame = time(NULL); _decoded_output_device = NULL ; - + //_encoding_current_codec = VIDEO_PROCESSOR_CODEC_ID_JPEG_VIDEO; _encoding_current_codec = VIDEO_PROCESSOR_CODEC_ID_MPEG_VIDEO; - + _estimated_bandwidth_in = 0 ; _estimated_bandwidth_out = 0 ; _target_bandwidth_out = 30*1024 ; // 30 KB/s - + _total_encoded_size_in = 0 ; _total_encoded_size_out = 0 ; - + _last_bw_estimate_in_TS = time(NULL) ; _last_bw_estimate_out_TS = time(NULL) ; } @@ -50,9 +125,9 @@ VideoProcessor::VideoProcessor() VideoProcessor::~VideoProcessor() { // clear encoding queue - + RS_STACK_MUTEX(vpMtx) ; - + while(!_encoded_out_queue.empty()) { _encoded_out_queue.back().clear() ; @@ -92,7 +167,7 @@ bool VideoProcessor::processImage(const QImage& img) if(now > _last_bw_estimate_out_TS) { RS_STACK_MUTEX(vpMtx) ; - + _estimated_bandwidth_out = uint32_t(0.75*_estimated_bandwidth_out + 0.25 * (_total_encoded_size_out / (float)(now - _last_bw_estimate_out_TS))) ; _total_encoded_size_out = 0 ; @@ -114,7 +189,7 @@ bool VideoProcessor::processImage(const QImage& img) bool VideoProcessor::nextEncodedPacket(RsVOIPDataChunk& chunk) { - RS_STACK_MUTEX(vpMtx) ; + RS_STACK_MUTEX(vpMtx) ; if(_encoded_out_queue.empty()) return false ; @@ -134,7 +209,7 @@ void VideoProcessor::receiveEncodedData(const RsVOIPDataChunk& chunk) static const int HEADER_SIZE = 4 ; // read frame type. Use first 4 bytes to give info about content. - // + // // Byte Meaning Values // 00 Codec CODEC_ID_JPEG_VIDEO Basic Jpeg codec // CODEC_ID_DDWT_VIDEO Differential wavelet compression @@ -164,14 +239,13 @@ void VideoProcessor::receiveEncodedData(const RsVOIPDataChunk& chunk) default: codec = NULL ; } - QImage img ; if(codec == NULL) { std::cerr << "Unknown decoding codec: " << codid << std::endl; return ; } - + { RS_STACK_MUTEX(vpMtx) ; _total_encoded_size_in += chunk.size ; @@ -188,16 +262,23 @@ void VideoProcessor::receiveEncodedData(const RsVOIPDataChunk& chunk) #ifdef DEBUG_VIDEO_OUTPUT_DEVICE std::cerr << "new bw estimate (in): " << _estimated_bandwidth_in << std::endl; #endif - } + } } - if(!codec->decodeData(chunk,img)) + + QImage img ; + if(!codec->decodeData(chunk,img)) { std::cerr << "No image decoded. Probably in the middle of something..." << std::endl; return ; } if(_decoded_output_device) - _decoded_output_device->showFrame(img) ; +// if (time(NULL) > _lastTimeToShowFrame) +// { + _decoded_output_device->showFrame(img) ; +// _lastTimeToShowFrame = time(NULL) ;//+ 1000/25; +#warning "\plugins\VOIP\gui\VideoProcessor.cpp:210 TODO: Get CPU usage to pass image." +// } } void VideoProcessor::setMaximumBandwidth(uint32_t bytes_per_sec) @@ -211,7 +292,7 @@ void VideoProcessor::setMaximumBandwidth(uint32_t bytes_per_sec) ////////////////////////////////////////////////////////////////////////////////////////////////////////////// JPEGVideo::JPEGVideo() - : _encoded_ref_frame_max_distance(10),_encoded_ref_frame_count(10) + : _encoded_ref_frame_max_distance(10),_encoded_ref_frame_count(10) { } @@ -221,9 +302,9 @@ bool JPEGVideo::decodeData(const RsVOIPDataChunk& chunk,QImage& image) uint16_t codec = ((unsigned char *)chunk.data)[0] + (((unsigned char *)chunk.data)[1] << 8) ; uint16_t flags = ((unsigned char *)chunk.data)[2] + (((unsigned char *)chunk.data)[3] << 8) ; - + assert(codec == VideoProcessor::VIDEO_PROCESSOR_CODEC_ID_JPEG_VIDEO) ; - + // un-compress image data QByteArray qb((char*)&((uint8_t*)chunk.data)[HEADER_SIZE],(int)chunk.size - HEADER_SIZE) ; @@ -233,7 +314,7 @@ bool JPEGVideo::decodeData(const RsVOIPDataChunk& chunk,QImage& image) std::cerr << "image.loadFromData(): returned an error.: " << std::endl; return false ; } - + if(flags & JPEG_VIDEO_FLAGS_DIFFERENTIAL_FRAME) { if(_decoded_reference_frame.size() != image.size()) @@ -255,7 +336,7 @@ bool JPEGVideo::decodeData(const RsVOIPDataChunk& chunk,QImage& image) } else _decoded_reference_frame = image ; - + return true ; } @@ -266,8 +347,10 @@ bool JPEGVideo::encodeData(const QImage& image,uint32_t /* size_hint */,RsVOIPDa QImage encoded_frame ; bool differential_frame ; - if(_encoded_ref_frame_count++ < _encoded_ref_frame_max_distance && image.size() == _encoded_reference_frame.size()) - { + if (_encoded_ref_frame_count++ < _encoded_ref_frame_max_distance + && image.size() == _encoded_reference_frame.size() + && image.byteCount() == _encoded_reference_frame.byteCount()) + { // compute difference with reference frame. encoded_frame = image ; @@ -285,7 +368,7 @@ bool JPEGVideo::encodeData(const QImage& image,uint32_t /* size_hint */,RsVOIPDa else { _encoded_ref_frame_count = 0 ; - _encoded_reference_frame = image ; + _encoded_reference_frame = image.copy() ; encoded_frame = image ; differential_frame = false ; @@ -317,31 +400,36 @@ bool JPEGVideo::encodeData(const QImage& image,uint32_t /* size_hint */,RsVOIPDa FFmpegVideo::FFmpegVideo() { - // Encoding - + avcodec_register_all(); + // Encoding + encoding_codec = NULL ; encoding_frame_buffer = NULL ; encoding_context = NULL ; - - //AVCodecID codec_id = AV_CODEC_ID_H264 ; - //AVCodecID codec_id = AV_CODEC_ID_MPEG2VIDEO; - AVCodecID codec_id = AV_CODEC_ID_MPEG4; - - uint8_t endcode[] = { 0, 0, 1, 0xb7 }; - /* find the mpeg1 video encoder */ + //AVCodecID codec_id = AV_CODEC_ID_H264 ; + //AVCodecID codec_id = AV_CODEC_ID_MPEG2VIDEO; +#if LIBAVCODEC_VERSION_MAJOR < 54 + CodecID codec_id = CODEC_ID_MPEG4; +#else + AVCodecID codec_id = AV_CODEC_ID_MPEG4; +#endif + + /* find the video encoder */ encoding_codec = avcodec_find_encoder(codec_id); - - if (!encoding_codec) throw("AV codec not found for codec id ") ; + + if (!encoding_codec) std::cerr << "AV codec not found for codec id " << std::endl; + if (!encoding_codec) throw std::runtime_error("AV codec not found for codec id ") ; encoding_context = avcodec_alloc_context3(encoding_codec); - - if (!encoding_context) throw std::runtime_error("AV: Could not allocate video codec encoding context"); + + if (!encoding_context) std::cerr << "AV: Could not allocate video codec encoding context" << std::endl; + if (!encoding_context) throw std::runtime_error("AV: Could not allocate video codec encoding context"); /* put sample parameters */ encoding_context->bit_rate = 10*1024 ; // default bitrate is 30KB/s encoding_context->bit_rate_tolerance = encoding_context->bit_rate ; - + #ifdef USE_VARIABLE_BITRATE encoding_context->rc_min_rate = 0; encoding_context->rc_max_rate = 10*1024;//encoding_context->bit_rate; @@ -354,8 +442,9 @@ FFmpegVideo::FFmpegVideo() encoding_context->rc_max_rate = 0; encoding_context->rc_buffer_size = 0; #endif - encoding_context->flags |= CODEC_FLAG_PSNR; - encoding_context->flags |= CODEC_FLAG_TRUNCATED; + if (encoding_codec->capabilities & CODEC_CAP_TRUNCATED) + encoding_context->flags |= CODEC_FLAG_TRUNCATED; + encoding_context->flags |= CODEC_FLAG_PSNR;//Peak signal-to-noise ratio encoding_context->flags |= CODEC_CAP_PARAM_CHANGE; encoding_context->i_quant_factor = 0.769f; encoding_context->b_quant_factor = 1.4f; @@ -364,19 +453,19 @@ FFmpegVideo::FFmpegVideo() encoding_context->qmin = 1; encoding_context->qmax = 51; encoding_context->max_qdiff = 4; - + //encoding_context->me_method = ME_HEX; - //encoding_context->max_b_frames = 4; + //encoding_context->max_b_frames = 4; //encoding_context->flags |= CODEC_FLAG_LOW_DELAY; // MPEG2 only //encoding_context->partitions = X264_PART_I4X4 | X264_PART_I8X8 | X264_PART_P8X8 | X264_PART_P4X4 | X264_PART_B8X8; //encoding_context->crf = 0.0f; //encoding_context->cqp = 26; - + /* resolution must be a multiple of two */ encoding_context->width = 640;//176; encoding_context->height = 480;//144; /* frames per second */ - encoding_context->time_base = (AVRational){1,25}; + encoding_context->time_base = av_make_q(1, 25); /* emit one intra frame every ten frames * check frame pict_type before passing frame * to encoder, if frame->pict_type is AV_PICTURE_TYPE_I @@ -385,101 +474,123 @@ FFmpegVideo::FFmpegVideo() */ encoding_context->gop_size = 100; //encoding_context->max_b_frames = 1; +#if LIBAVCODEC_VERSION_MAJOR < 54 + encoding_context->pix_fmt = PIX_FMT_YUV420P; //context->pix_fmt = PIX_FMT_RGB24; + if (codec_id == CODEC_ID_H264) { +#else encoding_context->pix_fmt = AV_PIX_FMT_YUV420P; //context->pix_fmt = AV_PIX_FMT_RGB24; - - if (codec_id == AV_CODEC_ID_H264) + if (codec_id == AV_CODEC_ID_H264) { +#endif av_opt_set(encoding_context->priv_data, "preset", "slow", 0); + } /* open it */ - if (avcodec_open2(encoding_context, encoding_codec, NULL) < 0) + if (avcodec_open2(encoding_context, encoding_codec, NULL) < 0) + { + std::cerr << "AV: Could not open codec context. Something's wrong." << std::endl; throw std::runtime_error( "AV: Could not open codec context. Something's wrong."); + } +#if (LIBAVCODEC_VERSION_MAJOR < 57) | (LIBAVCODEC_VERSION_MAJOR == 57 && LIBAVCODEC_VERSION_MINOR <3 ) encoding_frame_buffer = avcodec_alloc_frame() ;//(AVFrame*)malloc(sizeof(AVFrame)) ; - +#else + encoding_frame_buffer = av_frame_alloc() ; +#endif + + if(!encoding_frame_buffer) std::cerr << "AV: could not allocate frame buffer." << std::endl; if(!encoding_frame_buffer) throw std::runtime_error("AV: could not allocate frame buffer.") ; - + encoding_frame_buffer->format = encoding_context->pix_fmt; encoding_frame_buffer->width = encoding_context->width; encoding_frame_buffer->height = encoding_context->height; /* the image can be allocated by any means and av_image_alloc() is * just the most convenient way if av_malloc() is to be used */ - + int ret = av_image_alloc(encoding_frame_buffer->data, encoding_frame_buffer->linesize, encoding_context->width, encoding_context->height, encoding_context->pix_fmt, 32); - - if (ret < 0) - throw std::runtime_error("AV: Could not allocate raw picture buffer"); - + + if (ret < 0) std::cerr << "AV: Could not allocate raw picture buffer" << std::endl; + if (ret < 0) + throw std::runtime_error("AV: Could not allocate raw picture buffer"); + encoding_frame_count = 0 ; - + // Decoding - decoding_codec = avcodec_find_decoder(codec_id); - - if (!decoding_codec) + + if (!decoding_codec) std::cerr << "AV codec not found for codec id " << std::endl; + if (!decoding_codec) throw("AV codec not found for codec id ") ; - + decoding_context = avcodec_alloc_context3(decoding_codec); - - if(!decoding_context) + + if(!decoding_context) std::cerr << "AV: Could not allocate video codec decoding context" << std::endl; + if(!decoding_context) throw std::runtime_error("AV: Could not allocate video codec decoding context"); - + decoding_context->width = encoding_context->width; decoding_context->height = encoding_context->height; +#if LIBAVCODEC_VERSION_MAJOR < 54 + decoding_context->pix_fmt = PIX_FMT_YUV420P; +#else decoding_context->pix_fmt = AV_PIX_FMT_YUV420P; - +#endif + if(decoding_codec->capabilities & CODEC_CAP_TRUNCATED) - decoding_context->flags |= CODEC_FLAG_TRUNCATED; // we do not send complete frames - - if(avcodec_open2(decoding_context,decoding_codec,NULL) < 0) + decoding_context->flags |= CODEC_FLAG_TRUNCATED; // we do not send complete frames + //we can receive truncated frames + decoding_context->flags2 |= CODEC_FLAG2_CHUNKS; + + AVDictionary* dictionary = NULL; + if(avcodec_open2(decoding_context, decoding_codec, &dictionary) < 0) + { + std::cerr << "AV codec open action failed! " << std::endl; throw("AV codec open action failed! ") ; - - decoding_frame_buffer = avcodec_alloc_frame() ;//(AVFrame*)malloc(sizeof(AVFrame)) ; - + } + + //decoding_frame_buffer = avcodec_alloc_frame() ;//(AVFrame*)malloc(sizeof(AVFrame)) ; + decoding_frame_buffer = av_frame_alloc() ; + av_init_packet(&decoding_buffer); decoding_buffer.data = NULL ; decoding_buffer.size = 0 ; //ret = av_image_alloc(decoding_frame_buffer->data, decoding_frame_buffer->linesize, decoding_context->width, decoding_context->height, decoding_context->pix_fmt, 32); - - //if (ret < 0) - //throw std::runtime_error("AV: Could not allocate raw picture buffer"); - + + //if (ret < 0) + //throw std::runtime_error("AV: Could not allocate raw picture buffer"); + // debug -#ifdef DEBUG_MPEG_VIDEO +#ifdef DEBUG_MPEG_VIDEO std::cerr << "Dumping captured data to file tmpvideo.mpg" << std::endl; encoding_debug_file = fopen("tmpvideo.mpg","w") ; #endif } - + FFmpegVideo::~FFmpegVideo() { - avcodec_close(encoding_context); - avcodec_close(decoding_context); - av_free(encoding_context); - av_free(decoding_context); - av_freep(&encoding_frame_buffer->data[0]); - av_freep(&decoding_frame_buffer->data[0]); - free(encoding_frame_buffer); - free(decoding_frame_buffer); + avcodec_free_context(&encoding_context); + avcodec_free_context(&decoding_context); + av_frame_free(&encoding_frame_buffer); + av_frame_free(&decoding_frame_buffer); } #define MAX_FFMPEG_ENCODING_BITRATE 81920 bool FFmpegVideo::encodeData(const QImage& image, uint32_t target_encoding_bitrate, RsVOIPDataChunk& voip_chunk) { -#ifdef DEBUG_MPEG_VIDEO - std::cerr << "Encoding frame of size " << image.width() << "x" << image.height() << ", resized to " << encoding_frame_buffer->width << "x" << encoding_frame_buffer->height << " : "; +#ifdef DEBUG_MPEG_VIDEO + std::cerr << "Encoding frame of size " << image.width() << "x" << image.height() << ", resized to " << encoding_frame_buffer->width << "x" << encoding_frame_buffer->height << " : "; #endif QImage input ; - - if(target_encoding_bitrate > MAX_FFMPEG_ENCODING_BITRATE) - { - std::cerr << "Max encodign bitrate eexceeded. Capping to " << MAX_FFMPEG_ENCODING_BITRATE << std::endl; - target_encoding_bitrate = MAX_FFMPEG_ENCODING_BITRATE ; - } + + if(target_encoding_bitrate > MAX_FFMPEG_ENCODING_BITRATE) + { + std::cerr << "Max encodign bitrate eexceeded. Capping to " << MAX_FFMPEG_ENCODING_BITRATE << std::endl; + target_encoding_bitrate = MAX_FFMPEG_ENCODING_BITRATE ; + } //encoding_context->bit_rate = target_encoding_bitrate; encoding_context->rc_max_rate = target_encoding_bitrate; //encoding_context->bit_rate_tolerance = target_encoding_bitrate; @@ -491,8 +602,8 @@ bool FFmpegVideo::encodeData(const QImage& image, uint32_t target_encoding_bitra /* prepare a dummy image */ /* Y */ - for (int y = 0; y < encoding_context->height/2; y++) - for (int x = 0; x < encoding_context->width/2; x++) + for (int y = 0; y < encoding_context->height/2; y++) + for (int x = 0; x < encoding_context->width/2; x++) { QRgb pix00 = input.pixel(QPoint(2*x+0,2*y+0)) ; QRgb pix01 = input.pixel(QPoint(2*x+0,2*y+1)) ; @@ -508,11 +619,11 @@ bool FFmpegVideo::encodeData(const QImage& image, uint32_t target_encoding_bitra int Y01 = (0.257 * R01) + (0.504 * G01) + (0.098 * B01) + 16 ; int Y10 = (0.257 * R10) + (0.504 * G10) + (0.098 * B10) + 16 ; int Y11 = (0.257 * R11) + (0.504 * G11) + (0.098 * B11) + 16 ; - - float R = 0.25*(R00+R01+R10+R11) ; - float G = 0.25*(G00+G01+G10+G11) ; - float B = 0.25*(B00+B01+B10+B11) ; - + + float R = 0.25*(R00+R01+R10+R11) ; + float G = 0.25*(G00+G01+G10+G11) ; + float B = 0.25*(B00+B01+B10+B11) ; + int U = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128 ; int V = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128 ; @@ -520,7 +631,7 @@ bool FFmpegVideo::encodeData(const QImage& image, uint32_t target_encoding_bitra encoding_frame_buffer->data[0][(2*y+0) * encoding_frame_buffer->linesize[0] + 2*x+1] = std::min(255,std::max(0,Y01)); // Y encoding_frame_buffer->data[0][(2*y+1) * encoding_frame_buffer->linesize[0] + 2*x+0] = std::min(255,std::max(0,Y10)); // Y encoding_frame_buffer->data[0][(2*y+1) * encoding_frame_buffer->linesize[0] + 2*x+1] = std::min(255,std::max(0,Y11)); // Y - + encoding_frame_buffer->data[1][y * encoding_frame_buffer->linesize[1] + x] = std::min(255,std::max(0,U));// Cr encoding_frame_buffer->data[2][y * encoding_frame_buffer->linesize[2] + x] = std::min(255,std::max(0,V));// Cb } @@ -532,18 +643,28 @@ bool FFmpegVideo::encodeData(const QImage& image, uint32_t target_encoding_bitra int got_output = 0; - AVFrame *frame = encoding_frame_buffer ; - AVPacket pkt ; av_init_packet(&pkt); +#if LIBAVCODEC_VERSION_MAJOR < 54 + pkt.size = avpicture_get_size(encoding_context->pix_fmt, encoding_context->width, encoding_context->height); + pkt.data = (uint8_t*)av_malloc(pkt.size); + + // do + // { + int ret = avcodec_encode_video(encoding_context, pkt.data, pkt.size, encoding_frame_buffer) ; + if (ret > 0) { + got_output = ret; + } +#else pkt.data = NULL; // packet data will be allocated by the encoder pkt.size = 0; // do // { - int ret = avcodec_encode_video2(encoding_context, &pkt, frame, &got_output) ; + int ret = avcodec_encode_video2(encoding_context, &pkt, encoding_frame_buffer, &got_output) ; +#endif - if (ret < 0) + if (ret < 0) { std::cerr << "Error encoding frame!" << std::endl; return false ; @@ -567,14 +688,14 @@ bool FFmpegVideo::encodeData(const QImage& image, uint32_t target_encoding_bitra voip_chunk.size = pkt.size + HEADER_SIZE; voip_chunk.type = RsVOIPDataChunk::RS_VOIP_DATA_TYPE_VIDEO ; -#ifdef DEBUG_MPEG_VIDEO +#ifdef DEBUG_MPEG_VIDEO std::cerr << "Output : " << pkt.size << " bytes." << std::endl; fwrite(pkt.data,1,pkt.size,encoding_debug_file) ; fflush(encoding_debug_file) ; #endif av_free_packet(&pkt); - - return true ; + + return true ; } else { @@ -583,7 +704,7 @@ bool FFmpegVideo::encodeData(const QImage& image, uint32_t target_encoding_bitra voip_chunk.type = RsVOIPDataChunk::RS_VOIP_DATA_TYPE_VIDEO ; std::cerr << "No output produced." << std::endl; - return false ; + return false ; } } @@ -592,94 +713,68 @@ bool FFmpegVideo::decodeData(const RsVOIPDataChunk& chunk,QImage& image) { #ifdef DEBUG_MPEG_VIDEO std::cerr << "Decoding data of size " << chunk.size << std::endl; -#endif - unsigned char *buff ; - - if(decoding_buffer.data != NULL) - { -#ifdef DEBUG_MPEG_VIDEO - std::cerr << "Completing buffer with size " << chunk.size - HEADER_SIZE + decoding_buffer.size << ": copying existing " - << decoding_buffer.size << " bytes. Adding new " << chunk.size - HEADER_SIZE<< " bytes " << std::endl; + std::cerr << "Allocating new buffer of size " << chunk.size - HEADER_SIZE << std::endl; #endif - uint32_t s = chunk.size - HEADER_SIZE + decoding_buffer.size ; - unsigned char *tmp = (unsigned char*)memalign(16,s + FF_INPUT_BUFFER_PADDING_SIZE) ; - memset(tmp,0,s+FF_INPUT_BUFFER_PADDING_SIZE) ; - - memcpy(tmp,decoding_buffer.data,decoding_buffer.size) ; - - free(decoding_buffer.data) ; - - buff = &tmp[decoding_buffer.size] ; - decoding_buffer.size = s ; - decoding_buffer.data = tmp ; + uint32_t s = chunk.size - HEADER_SIZE ; +#if defined(__MINGW32__) + unsigned char *tmp = (unsigned char*)_aligned_malloc(s + AV_INPUT_BUFFER_PADDING_SIZE, 16) ; +#else + unsigned char *tmp = (unsigned char*)memalign(16, s + AV_INPUT_BUFFER_PADDING_SIZE) ; +#endif //MINGW + if (tmp == NULL) { + std::cerr << "FFmpegVideo::decodeData() Unable to allocate new buffer of size " << s << std::endl; + return false; } - else - { -#ifdef DEBUG_MPEG_VIDEO - std::cerr << "Allocating new buffer of size " << chunk.size - HEADER_SIZE << std::endl; -#endif + /* copy chunk data without header to new buffer */ + memcpy(tmp, &((unsigned char*)chunk.data)[HEADER_SIZE], s); - decoding_buffer.data = (unsigned char *)memalign(16,chunk.size - HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE) ; - decoding_buffer.size = chunk.size - HEADER_SIZE ; - memset(decoding_buffer.data,0,decoding_buffer.size + FF_INPUT_BUFFER_PADDING_SIZE) ; + /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */ + memset(&tmp[s], 0, AV_INPUT_BUFFER_PADDING_SIZE) ; - buff = decoding_buffer.data ; - } + decoding_buffer.size = s ; + decoding_buffer.data = tmp; + int got_frame = 1 ; - memcpy(buff,&((unsigned char*)chunk.data)[HEADER_SIZE],chunk.size - HEADER_SIZE) ; + while (decoding_buffer.size > 0 || (!decoding_buffer.data && got_frame)) { + int len = avcodec_decode_video2(decoding_context,decoding_frame_buffer,&got_frame,&decoding_buffer) ; - int got_frame = 0 ; - int len = avcodec_decode_video2(decoding_context,decoding_frame_buffer,&got_frame,&decoding_buffer) ; + if (len < 0) + { + std::cerr << "Error decoding frame! Return=" << len << std::endl; + return false ; + } - if(len < 0) - { - std::cerr << "Error decodign frame!" << std::endl; - return false ; - } -#ifdef DEBUG_MPEG_VIDEO - std::cerr << "Used " << len << " bytes out of " << decoding_buffer.size << ". got_frame = " << got_frame << std::endl; -#endif + decoding_buffer.data += len; + decoding_buffer.size -= len; - if(got_frame) - { - image = QImage(QSize(decoding_frame_buffer->width,decoding_frame_buffer->height),QImage::Format_ARGB32) ; + if(got_frame) + { + image = QImage(QSize(decoding_frame_buffer->width,decoding_frame_buffer->height),QImage::Format_ARGB32) ; #ifdef DEBUG_MPEG_VIDEO - std::cerr << "Decoded frame. Size=" << image.width() << "x" << image.height() << std::endl; + std::cerr << "Decoded frame. Size=" << image.width() << "x" << image.height() << std::endl; #endif - for (int y = 0; y < decoding_frame_buffer->height; y++) - for (int x = 0; x < decoding_frame_buffer->width; x++) - { - int Y = decoding_frame_buffer->data[0][y * decoding_frame_buffer->linesize[0] + x] ; - int U = decoding_frame_buffer->data[1][(y/2) * decoding_frame_buffer->linesize[1] + x/2] ; - int V = decoding_frame_buffer->data[2][(y/2) * decoding_frame_buffer->linesize[2] + x/2] ; + for (int y = 0; y < decoding_frame_buffer->height; y++) + for (int x = 0; x < decoding_frame_buffer->width; x++) + { + int Y = decoding_frame_buffer->data[0][y * decoding_frame_buffer->linesize[0] + x] ; + int U = decoding_frame_buffer->data[1][(y/2) * decoding_frame_buffer->linesize[1] + x/2] ; + int V = decoding_frame_buffer->data[2][(y/2) * decoding_frame_buffer->linesize[2] + x/2] ; - int B = std::min(255,std::max(0,(int)(1.164*(Y - 16) + 1.596*(V - 128)))) ; - int G = std::min(255,std::max(0,(int)(1.164*(Y - 16) - 0.813*(V - 128) - 0.391*(U - 128)))) ; - int R = std::min(255,std::max(0,(int)(1.164*(Y - 16) + 2.018*(U - 128)))) ; + int B = std::min(255,std::max(0,(int)(1.164*(Y - 16) + 1.596*(V - 128)))) ; + int G = std::min(255,std::max(0,(int)(1.164*(Y - 16) - 0.813*(V - 128) - 0.391*(U - 128)))) ; + int R = std::min(255,std::max(0,(int)(1.164*(Y - 16) + 2.018*(U - 128)))) ; - image.setPixel(QPoint(x,y),QRgb( 0xff000000 + (R << 16) + (G << 8) + B)) ; - } - } - - if(len == decoding_buffer.size) - { - free(decoding_buffer.data) ; - decoding_buffer.data = NULL; - decoding_buffer.size = 0; - } - else if(len != 0) - { -#ifdef DEBUG_MPEG_VIDEO - std::cerr << "Moving remaining data (" << decoding_buffer.size - len << " bytes) back to 0" << std::endl; -#endif - - memmove(decoding_buffer.data,decoding_buffer.data+len,decoding_buffer.size - len) ; - decoding_buffer.size -= len ; + image.setPixel(QPoint(x,y),QRgb( 0xff000000 + (R << 16) + (G << 8) + B)) ; + } + } } + /* flush the decoder */ + decoding_buffer.data = NULL; + decoding_buffer.size = 0; + //avcodec_decode_video2(decoding_context,decoding_frame_buffer,&got_frame,&decoding_buffer) ; return true ; } - diff --git a/plugins/VOIP/gui/VideoProcessor.h b/plugins/VOIP/gui/VideoProcessor.h index a3869dc5e..4e47b2c29 100644 --- a/plugins/VOIP/gui/VideoProcessor.h +++ b/plugins/VOIP/gui/VideoProcessor.h @@ -102,6 +102,7 @@ class VideoProcessor private: QVideoOutputDevice *_decoded_output_device ; std::list _decoded_image_queue ; + //time_t _lastTimeToShowFrame ; // ===================================================================================== // =------------------------------------ ENCODING -------------------------------------= diff --git a/plugins/VOIP/gui/images/video-icon-off.png b/plugins/VOIP/gui/images/video-icon-off.png index 88aa2066e..1a4c04840 100644 Binary files a/plugins/VOIP/gui/images/video-icon-off.png and b/plugins/VOIP/gui/images/video-icon-off.png differ diff --git a/plugins/VOIP/gui/images/video-icon-on.png b/plugins/VOIP/gui/images/video-icon-on.png index 5b5497777..6c4618293 100644 Binary files a/plugins/VOIP/gui/images/video-icon-on.png and b/plugins/VOIP/gui/images/video-icon-on.png differ diff --git a/plugins/VOIP/interface/rsVOIP.h b/plugins/VOIP/interface/rsVOIP.h index 25fd0cfbd..8b7fd3d7b 100644 --- a/plugins/VOIP/interface/rsVOIP.h +++ b/plugins/VOIP/interface/rsVOIP.h @@ -51,23 +51,23 @@ class RsVOIPPongResult struct RsVOIPDataChunk { - typedef enum { RS_VOIP_DATA_TYPE_UNKNOWN = 0x00, - RS_VOIP_DATA_TYPE_AUDIO = 0x01, - RS_VOIP_DATA_TYPE_VIDEO = 0x02 } RsVOIPDataType ; + typedef enum { RS_VOIP_DATA_TYPE_UNKNOWN = 0x00, + RS_VOIP_DATA_TYPE_AUDIO = 0x01, + RS_VOIP_DATA_TYPE_VIDEO = 0x02 } RsVOIPDataType ; void *data ; // create/delete using malloc/free. uint32_t size ; RsVOIPDataType type ; // video or audio - - void clear() ; + + void clear() ; }; class RsVOIP { public: - virtual int sendVoipHangUpCall(const RsPeerId& peer_id) = 0; - virtual int sendVoipRinging(const RsPeerId& peer_id) = 0; - virtual int sendVoipAcceptCall(const RsPeerId& peer_id) = 0; + virtual int sendVoipHangUpCall(const RsPeerId& peer_id, uint32_t flags) = 0; + virtual int sendVoipRinging(const RsPeerId& peer_id, uint32_t flags) = 0; + virtual int sendVoipAcceptCall(const RsPeerId& peer_id, uint32_t flags) = 0; // Sending data. The client keeps the memory ownership and must delete it after calling this. virtual int sendVoipData(const RsPeerId& peer_id,const RsVOIPDataChunk& chunk) = 0; diff --git a/plugins/VOIP/services/p3VOIP.cc b/plugins/VOIP/services/p3VOIP.cc index fb164bd7c..c0867299d 100644 --- a/plugins/VOIP/services/p3VOIP.cc +++ b/plugins/VOIP/services/p3VOIP.cc @@ -219,36 +219,36 @@ void p3VOIP::sendBandwidthInfo() } } -int p3VOIP::sendVoipHangUpCall(const RsPeerId &peer_id) +int p3VOIP::sendVoipHangUpCall(const RsPeerId &peer_id, uint32_t flags) { RsVOIPProtocolItem *item = new RsVOIPProtocolItem ; item->protocol = RsVOIPProtocolItem::VoipProtocol_Close; - item->flags = 0 ; + item->flags = flags ; item->PeerId(peer_id) ; sendItem(item) ; return true ; } -int p3VOIP::sendVoipAcceptCall(const RsPeerId& peer_id) +int p3VOIP::sendVoipAcceptCall(const RsPeerId& peer_id, uint32_t flags) { RsVOIPProtocolItem *item = new RsVOIPProtocolItem ; item->protocol = RsVOIPProtocolItem::VoipProtocol_Ackn ; - item->flags = 0 ; + item->flags = flags ; item->PeerId(peer_id) ; sendItem(item) ; return true ; } -int p3VOIP::sendVoipRinging(const RsPeerId &peer_id) +int p3VOIP::sendVoipRinging(const RsPeerId &peer_id, uint32_t flags) { RsVOIPProtocolItem *item = new RsVOIPProtocolItem ; item->protocol = RsVOIPProtocolItem::VoipProtocol_Ring ; - item->flags = 0 ; + item->flags = flags ; item->PeerId(peer_id) ; sendItem(item) ; @@ -362,33 +362,31 @@ void p3VOIP::handleProtocol(RsVOIPProtocolItem *item) switch(item->protocol) { - case RsVOIPProtocolItem::VoipProtocol_Ring: mNotify->notifyReceivedVoipInvite(item->PeerId()); + case RsVOIPProtocolItem::VoipProtocol_Ring: mNotify->notifyReceivedVoipInvite(item->PeerId(), (uint32_t)item->flags); #ifdef DEBUG_VOIP - std::cerr << "p3VOIP::handleProtocol(): Received protocol ring item." << std::endl; + std::cerr << "p3VOIP::handleProtocol(): Received protocol ring item." << std::endl; #endif - break ; + break ; - case RsVOIPProtocolItem::VoipProtocol_Ackn: mNotify->notifyReceivedVoipAccept(item->PeerId()); + case RsVOIPProtocolItem::VoipProtocol_Ackn: mNotify->notifyReceivedVoipAccept(item->PeerId(), (uint32_t)item->flags); #ifdef DEBUG_VOIP - std::cerr << "p3VOIP::handleProtocol(): Received protocol accept call" << std::endl; + std::cerr << "p3VOIP::handleProtocol(): Received protocol accept call" << std::endl; #endif - break ; + break ; - case RsVOIPProtocolItem::VoipProtocol_Close: mNotify->notifyReceivedVoipHangUp(item->PeerId()); + case RsVOIPProtocolItem::VoipProtocol_Close: mNotify->notifyReceivedVoipHangUp(item->PeerId(), (uint32_t)item->flags); #ifdef DEBUG_VOIP - std::cerr << "p3VOIP::handleProtocol(): Received protocol Close call." << std::endl; + std::cerr << "p3VOIP::handleProtocol(): Received protocol Close call." << std::endl; #endif - break ; + break ; case RsVOIPProtocolItem::VoipProtocol_Bandwidth: mNotify->notifyReceivedVoipBandwidth(item->PeerId(),(uint32_t)item->flags); #ifdef DEBUG_VOIP - std::cerr << "p3VOIP::handleProtocol(): Received protocol bandwidth. Value=" << item->flags << std::endl; + std::cerr << "p3VOIP::handleProtocol(): Received protocol bandwidth. Value=" << item->flags << std::endl; #endif - break ; + break ; default: -#ifdef DEBUG_VOIP - std::cerr << "p3VOIP::handleProtocol(): Received protocol item # " << item->protocol << ": not handled yet ! Sorry" << std::endl; -#endif - break ; + std::cerr << "p3VOIP::handleProtocol(): Received protocol item # " << item->protocol << ": not handled yet ! Sorry" << std::endl; + break ; } } diff --git a/plugins/VOIP/services/p3VOIP.h b/plugins/VOIP/services/p3VOIP.h index 03cbf795a..961496019 100644 --- a/plugins/VOIP/services/p3VOIP.h +++ b/plugins/VOIP/services/p3VOIP.h @@ -83,9 +83,9 @@ class p3VOIP: public RsPQIService, public RsVOIP // virtual bool getIncomingData(const RsPeerId& peer_id,std::vector& chunks) ; - virtual int sendVoipHangUpCall(const RsPeerId& peer_id) ; - virtual int sendVoipRinging(const RsPeerId& peer_id) ; - virtual int sendVoipAcceptCall(const RsPeerId &peer_id) ; + virtual int sendVoipHangUpCall(const RsPeerId& peer_id, uint32_t flags) ; + virtual int sendVoipRinging(const RsPeerId& peer_id, uint32_t flags) ; + virtual int sendVoipAcceptCall(const RsPeerId &peer_id, uint32_t flags) ; /***** overloaded from p3Service *****/ /*! diff --git a/plugins/VOIP/services/rsVOIPItems.cc b/plugins/VOIP/services/rsVOIPItems.cc index a75fa4c16..afc76b505 100644 --- a/plugins/VOIP/services/rsVOIPItems.cc +++ b/plugins/VOIP/services/rsVOIPItems.cc @@ -71,7 +71,7 @@ std::ostream& RsVOIPProtocolItem::print(std::ostream &out, uint16_t indent) out << "flags: " << flags << std::endl; printIndent(out, int_Indent); - out << "protocol: " << std::hex << protocol << std::dec << std::endl; + out << "protocol: " << std::hex << (uint32_t)protocol << std::dec << std::endl; printRsItemEnd(out, "RsVOIPProtocolItem", indent); return out; @@ -160,7 +160,7 @@ bool RsVOIPProtocolItem::serialise(void *data, uint32_t& pktsize) offset += 8; /* add mandatory parts first */ - ok &= setRawUInt32(data, tlvsize, &offset, protocol); + ok &= setRawUInt32(data, tlvsize, &offset, (uint32_t)protocol); ok &= setRawUInt32(data, tlvsize, &offset, flags); if (offset != tlvsize) @@ -300,7 +300,9 @@ RsVOIPProtocolItem::RsVOIPProtocolItem(void *data, uint32_t pktsize) offset += 8; /* get mandatory parts first */ - ok &= getRawUInt32(data, rssize, &offset, &protocol); + uint32_t uint_Protocol; + ok &= getRawUInt32(data, rssize, &offset, &uint_Protocol); + protocol = static_cast(uint_Protocol); ok &= getRawUInt32(data, rssize, &offset, &flags); if (offset != rssize) diff --git a/plugins/VOIP/services/rsVOIPItems.h b/plugins/VOIP/services/rsVOIPItems.h index 7658ea4cc..7d083fde5 100644 --- a/plugins/VOIP/services/rsVOIPItems.h +++ b/plugins/VOIP/services/rsVOIPItems.h @@ -76,8 +76,8 @@ class RsVOIPItem: public RsItem setPriorityLevel(QOS_PRIORITY_RS_VOIP) ; } - virtual ~RsVOIPItem() {}; - virtual void clear() {}; + virtual ~RsVOIPItem() {} + 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 serialise themselves ? @@ -138,14 +138,13 @@ class RsVOIPBandwidthItem: public RsVOIPItem uint32_t bytes_per_sec ; // bandwidth in bytes per sec. }; - class RsVOIPProtocolItem: public RsVOIPItem { public: RsVOIPProtocolItem() :RsVOIPItem(RS_PKT_SUBTYPE_VOIP_PROTOCOL) {} RsVOIPProtocolItem(void *data,uint32_t size) ; - enum { VoipProtocol_Ring = 1, VoipProtocol_Ackn = 2, VoipProtocol_Close = 3, VoipProtocol_Bandwidth = 4 } ; + typedef enum { VoipProtocol_Ring = 1, VoipProtocol_Ackn = 2, VoipProtocol_Close = 3, VoipProtocol_Bandwidth = 4 } en_Protocol; virtual bool serialise(void *data,uint32_t& size) ; virtual uint32_t serial_size() const ; @@ -153,7 +152,7 @@ class RsVOIPProtocolItem: public RsVOIPItem virtual ~RsVOIPProtocolItem() {} virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - uint32_t protocol ; + en_Protocol protocol ; uint32_t flags ; }; diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.cpp b/retroshare-gui/src/gui/ChatLobbyWidget.cpp index 298e172b6..5111f6734 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.cpp +++ b/retroshare-gui/src/gui/ChatLobbyWidget.cpp @@ -376,7 +376,7 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby +QObject::tr("Id:")+" "+QString::number(id,16) ; if(lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED) - tooltipstr += QObject::tr("\nSecurity: no anonymous ids") ; + tooltipstr += QObject::tr("\nSecurity: no anonymous IDs") ; item->setToolTip(0,tooltipstr) ; } @@ -795,7 +795,7 @@ void ChatLobbyWidget::subscribeChatLobbyAtItem(QTreeWidgetItem *item) if(!rsIdentity->getIdDetails(gxs_id,idd)) return ; - if(flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED) + if( (flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED) && !idd.mPgpLinked) { QMessageBox::warning(NULL,tr("Default identity is anonymous"),tr("You cannot join this lobby with your default identity, since it is anonymous and the lobby forbids it.")) ; return ; @@ -839,7 +839,7 @@ void ChatLobbyWidget::showBlankPage(ChatLobbyId id) ui.lobbyid_lineEdit->setText( QString::number((*it).lobby_id,16) ); ui.lobbytopic_lineEdit->setText( RsHtml::plainText(it->lobby_topic) ); ui.lobbytype_lineEdit->setText( (( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC)?tr("Public"):tr("Private")) ); - ui.lobbysec_lineEdit->setText( (( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)?tr("No anonymous IDs"):tr("Anonymous ids accepted")) ); + ui.lobbysec_lineEdit->setText( (( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)?tr("No anonymous IDs"):tr("Anonymous IDs accepted")) ); ui.lobbypeers_lineEdit->setText( QString::number((*it).total_number_of_peers) ); QString text = tr("You're not subscribed to this lobby; Double click-it to enter and chat.") ; diff --git a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp index a90b66660..98b26a637 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp @@ -717,9 +717,9 @@ void TransfersDialog::downloadListCustomPopupMenu( QPoint /*point*/ ) }// for (int i = 0; i < lst.count(); ++i) }// if (!items.empty()) - if (atLeastOne_Downloading) { + if (atLeastOne_Waiting || atLeastOne_Downloading || atLeastOne_Queued || atLeastOne_Paused) { contextMnu.addMenu( &prioritySpeedMenu) ; - }//if (atLeastOne_Downloading) + } if (atLeastOne_Queued) { contextMnu.addMenu( &priorityQueueMenu) ; }//if (atLeastOne_Queued) @@ -1076,6 +1076,7 @@ int TransfersDialog::addItem(int row, const FileInfo &fileInfo) } return row; + } int TransfersDialog::addPeerToItem(QStandardItem *dlItem, const QString& name, const QString& coreID, double dlspeed, uint32_t status, const FileProgressInfo& peerInfo) @@ -1401,6 +1402,13 @@ void TransfersDialog::insertTransfers() } ui.uploadsList->setSortingEnabled(true); + + downloads = tr("Downloads") + " (" + QString::number(DLListModel->rowCount()) + ")"; + uploads = tr("Uploads") + " (" + QString::number(ULListModel->rowCount()) + ")" ; + + ui.tabWidget->setTabText(0, downloads); + ui.tabWidget_2->setTabText(0, uploads); + } QString TransfersDialog::getPeerName(const RsPeerId& id) const diff --git a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h index b0a67a8c4..617974fa4 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h +++ b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h @@ -239,6 +239,9 @@ private: /** Adds a new action to the toolbar. */ void addAction(QAction *action, const char *slot = 0); + + QString downloads; + QString uploads; /** Qt Designer generated object */ Ui::TransfersDialog ui; diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index 9bebf4b2f..ba6282dc4 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -165,7 +165,7 @@ GenCertDialog::GenCertDialog(bool onlyGenerateIdentity, QWidget *parent) #if QT_VERSION >= 0x040700 ui.email_input->setPlaceholderText(tr("[Optional] Visible to your friends, and friends of friends.")) ; ui.node_input->setPlaceholderText(tr("[Required] Examples: Home, Laptop,...")) ; - ui.hiddenaddr_input->setPlaceholderText(tr("[Required] Examples: xa76giaf6ifda7ri63i263.onion (obtained by you from Tor)")) ; + ui.hiddenaddr_input->setPlaceholderText(tr("[Required] Tor/I2P address - Examples: xa76giaf6ifda7ri63i263.onion (obtained by you from Tor)")) ; ui.name_input->setPlaceholderText(tr("[Required] Visible to your friends, and friends of friends.")); ui.password_input->setPlaceholderText(tr("[Required] This password protects your private PGP key.")); ui.password_input_2->setPlaceholderText(tr("[Required] Type the same password again here.")); @@ -458,7 +458,7 @@ void GenCertDialog::genPerson() /* Message Dialog */ QMessageBox::warning(this, tr("Invalid hidden node"), - tr("Please enter a valid address of the form: 31769173498.onion:7800"), + tr("Please enter a valid address of the form: 31769173498.onion:7800 or [52 characters].b32.i2p"), QMessageBox::Ok); return; } diff --git a/retroshare-gui/src/gui/GenCertDialog.ui b/retroshare-gui/src/gui/GenCertDialog.ui index 4fe4f46ac..3dfd19786 100644 --- a/retroshare-gui/src/gui/GenCertDialog.ui +++ b/retroshare-gui/src/gui/GenCertDialog.ui @@ -7,7 +7,7 @@ 0 0 853 - 592 + 711 @@ -111,7 +111,7 @@ You can create a new profile with this form. -Alternatively you can use an existing profile. Just uncheck "Create a new profile" +Alternatively you can use an existing profile. Just uncheck "Create a new profile" true @@ -431,7 +431,7 @@ Alternatively you can use an existing profile. Just uncheck "Create a new profil - Tor address + hidden address @@ -593,7 +593,7 @@ anonymous, you can use a fake email. - <html><head/><body><p>This is a Tor Onion address of the form: xa76giaf6ifda7ri63i263.onion </p><p>In order to get one, you must configure Tor to create a new hidden service. If you do not yet have one, you can still go on, and make it right later in Retroshare's Options-&gt;Server-&gt;Tor configuration panel.</p></body></html> + <html><head/><body><p>This can be a Tor Onion address of the form: xa76giaf6ifda7ri63i263.onion <br/>or an I2P address in the form: [52 characters].b32.i2p </p><p>In order to get one, you must configure either Tor or I2P to create a new hidden service / server tunnel. If you do not yet have one, you can still go on, and make it right later in Retroshare's Options-&gt;Server-&gt;Hidden Service configuration panel.</p></body></html> true @@ -761,6 +761,7 @@ anonymous, you can use a fake email. + no_node_label genButton2 header_label genprofileinfo_label @@ -772,17 +773,17 @@ anonymous, you can use a fake email. label_hiddenaddr2 + + StyledLabel + QLabel +
gui/common/StyledLabel.h
+
HeaderFrame QFrame
gui/common/HeaderFrame.h
1
- - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
diff --git a/retroshare-gui/src/gui/GetStartedDialog.ui b/retroshare-gui/src/gui/GetStartedDialog.ui index 2f6a5f00e..4aacf28c5 100644 --- a/retroshare-gui/src/gui/GetStartedDialog.ui +++ b/retroshare-gui/src/gui/GetStartedDialog.ui @@ -198,9 +198,9 @@ p, li { white-space: pre-wrap; } <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">When your friends send you a their invitations, Click to open the Add Friends window.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">When your friends send you their invitations, click to open the Add Friends window.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Cut and Paste your Friend's &quot;ID Certificates&quot; into the window and add them as friends.</span></p></body></html> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Paste your Friend's &quot;ID Certificates&quot; into the window and add them as friends.</span></p></body></html>
@@ -283,7 +283,7 @@ p, li { white-space: pre-wrap; } <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Be Online at the same time, and RetroShare will automatically connect you!</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Be Online at the same time as your friends, and RetroShare will automatically connect you!</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Your client needs to find the RetroShare Network before it can make connections.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">This takes 5-30 minutes the first time you start up RetroShare</span></p> @@ -368,12 +368,12 @@ p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">You can improve your Retroshare performance by opening an External Port. </span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">This will speed up connections and allow more people to connect with you </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">This will speed up connections and allow more people to connect with you. </span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">The easiest way to do this is by enabling UPnP on your Wireless Box or Router.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">As each router is different, you need to find out your Router Model and Google for instructions.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">As each router is different, you will need to find out your Router Model and search the Internet for instructions.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">If none of this makes sense, don't worry about it Retroshare will still work.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">If none of this makes sense to you, don't worry about it Retroshare will still work.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></p></body></html> @@ -417,11 +417,11 @@ p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Having trouble getting started with RetroShare?</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">1) look at the FAQ Wiki. This is a bit old, we trying to bring it up to date.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">1) Look at the FAQ Wiki. This is a bit old, we are trying to bring it up to date.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">2) check out the Online Forums. Ask questions and discuss features.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">2) Check out the Online Forums. Ask questions and discuss features.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">3) try the Internal RetroShare Forums </span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">3) Try the Internal RetroShare Forums </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;"> - These come online once you are connected to friends.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">4) If you are still stuck. Email us.</span></p> diff --git a/retroshare-gui/src/gui/Identity/IdDetailsDialog.cpp b/retroshare-gui/src/gui/Identity/IdDetailsDialog.cpp index 89f64cf43..57e83c1b4 100644 --- a/retroshare-gui/src/gui/Identity/IdDetailsDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDetailsDialog.cpp @@ -26,9 +26,11 @@ #include "gui/common/UIStateHelper.h" #include +#include +// Data Requests. #define IDDETAILSDIALOG_IDDETAILS 1 - +#define IDDETAILSDIALOG_REPLIST 2 /****** * #define ID_DEBUG 1 *****/ @@ -51,39 +53,27 @@ IdDetailsDialog::IdDetailsDialog(const RsGxsGroupId& id, QWidget *parent) : mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgId); mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgName); mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_Type); - mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->toolButton_Reputation); - mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingOverall); - mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingImplicit); - mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingOwn); - mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingPeers); - mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->repModButton); - mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->repMod_Accept); - mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->repMod_Ban); - mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->repMod_Negative); - mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->repMod_Positive); - mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->repMod_Custom); - mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->repMod_spinBox); + mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_LastUsed); + mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->ownOpinion_CB); + mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->overallOpinion_TF); + mStateHelper->addWidget(IDDETAILSDIALOG_IDDETAILS, ui->neighborNodesOpinion_TF); mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_Nickname); mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgName); mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_KeyId); mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgId); mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_Type); + mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_LastUsed); mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgName); - mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingOverall); - mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingImplicit); - mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingOwn); - mStateHelper->addLoadPlaceholder(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingPeers); mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_Nickname); mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_KeyId); mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgId); mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_Type); + mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_LastUsed); mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->lineEdit_GpgName); - mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingOverall); - mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingImplicit); - mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingOwn); - mStateHelper->addClear(IDDETAILSDIALOG_IDDETAILS, ui->line_RatingPeers); + + mStateHelper->setActive(IDDETAILSDIALOG_REPLIST, false); /* Create token queue */ mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this); @@ -95,9 +85,7 @@ IdDetailsDialog::IdDetailsDialog(const RsGxsGroupId& id, QWidget *parent) : //connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(changeGroup())); connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - // Hiding Rep Btn until that part is finished. - ui->toolButton_Reputation->setVisible(false); + connect(ui->ownOpinion_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(modifyReputation())); requestIdDetails(); } @@ -111,6 +99,24 @@ IdDetailsDialog::~IdDetailsDialog() delete(mIdQueue); } +static QString getHumanReadableDuration(uint32_t seconds) +{ + if(seconds < 60) + return QString(QObject::tr("%1 seconds ago")).arg(seconds) ; + else if(seconds < 120) + return QString(QObject::tr("%1 minute ago")).arg(seconds/60) ; + else if(seconds < 3600) + return QString(QObject::tr("%1 minutes ago")).arg(seconds/60) ; + else if(seconds < 7200) + return QString(QObject::tr("%1 hour ago")).arg(seconds/3600) ; + else if(seconds < 24*3600) + return QString(QObject::tr("%1 hours ago")).arg(seconds/3600) ; + else if(seconds < 2*24*3600) + return QString(QObject::tr("%1 day ago")).arg(seconds/86400) ; + else + return QString(QObject::tr("%1 days ago")).arg(seconds/86400) ; +} + void IdDetailsDialog::insertIdDetails(uint32_t token) { mStateHelper->setLoading(IDDETAILSDIALOG_IDDETAILS, false); @@ -120,7 +126,7 @@ void IdDetailsDialog::insertIdDetails(uint32_t token) if (!rsIdentity->getGroupData(token, datavector)) { mStateHelper->setActive(IDDETAILSDIALOG_IDDETAILS, false); - mStateHelper->clear(IDDETAILSDIALOG_IDDETAILS); + mStateHelper->clear(IDDETAILSDIALOG_REPLIST); ui->lineEdit_KeyId->setText("ERROR GETTING KEY!"); @@ -153,6 +159,9 @@ void IdDetailsDialog::insertIdDetails(uint32_t token) //ui->lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash.toStdString())); ui->lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId.toStdString())); + time_t now = time(NULL) ; + ui->lineEdit_LastUsed->setText(getHumanReadableDuration(now - data.mLastUsageTS)) ; + QPixmap pixmap; if(data.mImage.mSize > 0 && pixmap.loadFromData(data.mImage.mData, data.mImage.mSize, "PNG")) @@ -217,82 +226,111 @@ void IdDetailsDialog::insertIdDetails(uint32_t token) } else ui->lineEdit_Type->setText(tr("Anonymous identity")) ; - -// if (isOwnId) -// { -// ui->radioButton_IdYourself->setChecked(true); -// } -// else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) -// { -// if (data.mPgpKnown) -// { -// if (rsPeers->isGPGAccepted(data.mPgpId)) -// { -// ui->radioButton_IdFriend->setChecked(true); -// } -// else -// { -// ui->radioButton_IdFOF->setChecked(true); -// } -// } -// else -// { -// ui->radioButton_IdOther->setChecked(true); -// } -// } -// else -// { -// ui->radioButton_IdPseudo->setChecked(true); -// } - + + if (isOwnId) { - //mStateHelper->setWidgetEnabled(ui->toolButton_Reputation, false); + mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, false); } else { // No Reputation yet! - //mStateHelper->setWidgetEnabled(ui->toolButton_Reputation, /*true*/ false); + mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, true); } - /* now fill in the reputation information */ - ui->line_RatingOverall->setText("Overall Rating TODO"); - ui->line_RatingOwn->setText("Own Rating TODO"); +/* now fill in the reputation information */ +#ifdef SUSPENDED if (data.mPgpKnown) { - ui->line_RatingImplicit->setText("+50 Known PGP"); + ui->line_RatingImplicit->setText(tr("+50 Known PGP")); } else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) { - ui->line_RatingImplicit->setText("+10 UnKnown PGP"); + ui->line_RatingImplicit->setText(tr("+10 UnKnown PGP")); } else { - ui->line_RatingImplicit->setText("+5 Anon Id"); + ui->line_RatingImplicit->setText(tr("+5 Anon Id")); } - - { - QString rating = QString::number(data.mReputation.mOverallScore); - ui->line_RatingOverall->setText(rating); - } - { QString rating = QString::number(data.mReputation.mIdScore); ui->line_RatingImplicit->setText(rating); } - { - QString rating = QString::number(data.mReputation.mOwnOpinion); - ui->line_RatingOwn->setText(rating); - } +#endif + RsReputations::ReputationInfo info ; + rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),info) ; + + ui->neighborNodesOpinion_TF->setText(QString::number(info.mOverallReputationScore-1.0f)); + + ui->overallOpinion_TF->setText(QString::number(info.mOverallReputationScore-1.0f) +" ("+ + ((info.mAssessment == RsReputations::ASSESSMENT_OK)? tr("OK") : tr("Banned")) +")" ) ; + + switch(info.mOwnOpinion) { - QString rating = QString::number(data.mReputation.mPeerOpinion); - ui->line_RatingPeers->setText(rating); + case RsReputations::OPINION_NEGATIVE: ui->ownOpinion_CB->setCurrentIndex(0); break ; + case RsReputations::OPINION_NEUTRAL : ui->ownOpinion_CB->setCurrentIndex(1); break ; + case RsReputations::OPINION_POSITIVE: ui->ownOpinion_CB->setCurrentIndex(2); break ; + default: + std::cerr << "Unexpected value in own opinion: " << info.mOwnOpinion << std::endl; } } +void IdDetailsDialog::modifyReputation() +{ +#ifdef ID_DEBUG + std::cerr << "IdDialog::modifyReputation()"; + std::cerr << std::endl; +#endif + + RsGxsId id(ui->lineEdit_KeyId->text().toStdString()); + + RsReputations::Opinion op ; + + switch(ui->ownOpinion_CB->currentIndex()) + { + case 0: op = RsReputations::OPINION_NEGATIVE ; break ; + case 1: op = RsReputations::OPINION_NEUTRAL ; break ; + case 2: op = RsReputations::OPINION_POSITIVE ; break ; + default: + std::cerr << "Wrong value from opinion combobox. Bug??" << std::endl; + + } + rsReputations->setOwnOpinion(id,op) ; + +#ifdef ID_DEBUG + std::cerr << "IdDialog::modifyReputation() ID: " << id << " Mod: " << mod; + std::cerr << std::endl; +#endif + +#ifdef SUSPENDED + // Cyril: apparently the old reputation system was in used here. It's based on GXS data exchange, and probably not + // very efficient because of this. + + uint32_t token; + if (!rsIdentity->submitOpinion(token, id, false, op)) + { +#ifdef ID_DEBUG + std::cerr << "IdDialog::modifyReputation() Error submitting Opinion"; + std::cerr << std::endl; +#endif + } +#endif + +#ifdef ID_DEBUG + std::cerr << "IdDialog::modifyReputation() queuingRequest(), token: " << token; + std::cerr << std::endl; +#endif + + // trigger refresh when finished. + // basic / anstype are not needed. + requestIdDetails(); + + return; +} + void IdDetailsDialog::requestIdDetails() { mIdQueue->cancelActiveRequestTokens(IDDETAILSDIALOG_IDDETAILS); @@ -318,6 +356,32 @@ void IdDetailsDialog::requestIdDetails() mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDDETAILSDIALOG_IDDETAILS); } +void IdDetailsDialog::requestRepList() +{ + // Removing this for the moment. + return; + + mStateHelper->setLoading(IDDETAILSDIALOG_REPLIST, true); + + mIdQueue->cancelActiveRequestTokens(IDDETAILSDIALOG_REPLIST); + + std::list groupIds; + groupIds.push_back(mId); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + + uint32_t token; + mIdQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDDETAILSDIALOG_REPLIST); +} + +void IdDetailsDialog::insertRepList(uint32_t token) +{ + Q_UNUSED(token) + mStateHelper->setLoading(IDDETAILSDIALOG_REPLIST, false); + mStateHelper->setActive(IDDETAILSDIALOG_REPLIST, true); +} + void IdDetailsDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) { if (queue != mIdQueue) { @@ -334,7 +398,11 @@ void IdDetailsDialog::loadRequest(const TokenQueue *queue, const TokenRequest &r case IDDETAILSDIALOG_IDDETAILS: insertIdDetails(req.mToken); break; - + + case IDDETAILSDIALOG_REPLIST: + insertRepList(req.mToken); + break; + default: std::cerr << "IdDetailsDialog::loadRequest() ERROR"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/Identity/IdDetailsDialog.h b/retroshare-gui/src/gui/Identity/IdDetailsDialog.h index 9ff7330bf..4992297ad 100644 --- a/retroshare-gui/src/gui/Identity/IdDetailsDialog.h +++ b/retroshare-gui/src/gui/Identity/IdDetailsDialog.h @@ -46,9 +46,15 @@ public: /* TokenResponse */ void loadRequest(const TokenQueue *queue, const TokenRequest &req); -private: +private slots: + void modifyReputation(); + +private : void requestIdDetails(); void insertIdDetails(uint32_t token); + + void requestRepList(); + void insertRepList(uint32_t token); private: RsGxsGroupId mId; diff --git a/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui b/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui index 79d520c78..e9e57478d 100644 --- a/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui @@ -7,7 +7,7 @@ 0 0 698 - 446 + 472 @@ -134,7 +134,7 @@ - + Qt::Vertical @@ -147,6 +147,23 @@ + + + + true + + + true + + + + + + + Last used: + + + @@ -183,206 +200,131 @@ + + + + + + + 0 + 0 + + + + Reputation + + + + + + + + <html><head/><body><p>Average opinion of neighbor nodes about this identity. Negative is bad,</p><p>positive is good. Zero is neutral.</p></body></html> + + + true + + + + + + + Your opinion: + + + + + + + Neighbor nodes: + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Your own opinion about an identity rules the visibility of that identity for yourself,</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">and is shared among friends. A final score is calculated according to a formula that accounts your own opinion and your friends' opinions about someone:</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> S = own_opinion * a + friends_opinion * (1-a)</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The factor 'a' depends on the type of ID. </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- anonymous IDs: </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- PGP-signed IDs by unknown PGP keys: a=</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The overall score is used in chat lobbies, forums and channels to decide on the actions to take for each specific identity:</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; -0.5: Posts are not stored, nor forwarded </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; 0.2: Posts are hidden, but still transmitted</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; 0.0: </p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The overall rating is computed in such a way that it is not possible for a single person to deterministically change someone's status at neighbor nodes.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + 0 + + + + Negative + + + + ../icons/yellow_biohazard64.png../icons/yellow_biohazard64.png + + + + + Neutral + + + + + Positive + + + + + + + + <html><head/><body><p>Overall reputation score, accounting for yours and your friends'.</p><p>Negative is bad, positive is good. Zero is neutral. If the score is too low,</p><p>the identity is flagged as bad, and will be filtered out in forums, chat lobbies,</p><p>channels, etc.</p></body></html> + + + true + + + + + + + + 75 + true + + + + Overall: + + + + + + + + + + - - - 9 - - - 0 - - - 9 - - - 9 - - - - - - 0 - 0 - - - - Reputation - - - - - - - - - 75 - true - - - - Overall - - - - - - - true - - - - - - - Implicit - - - - - - - true - - - - - - - Opinion - - - - - - - true - - - - - - - Peers - - - - - - - true - - - - - - - - - Qt::NoFocus - - - Edit Reputation - - - - :/images/edit_24.png:/images/edit_24.png - - - - 24 - 24 - - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - - - - - 0 - 0 - - - - Tweak Opinion - - - - - - Accept (+100) - - - - - - - Positive (+10) - - - - - - - Negative (-10) - - - - - - - Ban (-100) - - - - - - - - - Custom - - - - - - - -100 - - - 100 - - - - - - - - - Modify - - - - - - - - - Qt::Vertical @@ -395,7 +337,7 @@ - + 9 diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index b3535338c..ec9eaf1da 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -32,8 +32,10 @@ #include "gui/chat/ChatDialog.h" #include "gui/settings/rsharesettings.h" #include "gui/msgs/MessageComposer.h" +#include "util/QtVersion.h" #include +#include #include "retroshare/rsgxsflags.h" #include "retroshare/rsmsgs.h" #include @@ -55,6 +57,7 @@ #define RSID_COL_NICKNAME 0 #define RSID_COL_KEYID 1 #define RSID_COL_IDTYPE 2 +#define RSID_COL_VOTES 3 #define RSIDREP_COL_NAME 0 #define RSIDREP_COL_OPINION 1 @@ -91,19 +94,10 @@ IdDialog::IdDialog(QWidget *parent) : mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId); mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName); mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_Type); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->toolButton_Reputation); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingOverall); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingImplicit); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingOwn); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingPeers); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repModButton); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Accept); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Ban); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Negative); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Positive); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Custom); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_spinBox); + mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); + mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->ownOpinion_CB); + mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->overallOpinion_TF); + mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->neighborNodesOpinion_TF); mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname); mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName); @@ -112,23 +106,16 @@ IdDialog::IdDialog(QWidget *parent) : mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId); mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Type); mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName); - mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); - mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingOverall); - mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingImplicit); - mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingOwn); - mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingPeers); + mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); + //mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingOverall); mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname); mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId); // mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgHash); mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId); mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Type); - mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName); - mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); - mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingOverall); - mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingImplicit); - mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingOwn); - mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingPeers); + mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName); + mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); //mStateHelper->addWidget(IDDIALOG_REPLIST, ui->treeWidget_RepList); //mStateHelper->addLoadPlaceholder(IDDIALOG_REPLIST, ui->treeWidget_RepList); @@ -147,7 +134,7 @@ IdDialog::IdDialog(QWidget *parent) : connect(ui->filterComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterComboBoxChanged())); connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); - connect(ui->repModButton, SIGNAL(clicked()), this, SLOT(modifyReputation())); + connect(ui->ownOpinion_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(modifyReputation())); connect(ui->messageButton, SIGNAL(clicked()), this, SLOT(sendMsg())); @@ -183,12 +170,15 @@ IdDialog::IdDialog(QWidget *parent) : ui->idTreeWidget->enableColumnCustomize(true); ui->idTreeWidget->setColumnCustomizable(RSID_COL_NICKNAME, false); - + ui->idTreeWidget->setColumnHidden(RSID_COL_IDTYPE, true); /* Set initial column width */ int fontWidth = QFontMetricsF(ui->idTreeWidget->font()).width("W"); - ui->idTreeWidget->setColumnWidth(RSID_COL_NICKNAME, 18 * fontWidth); - ui->idTreeWidget->setColumnWidth(RSID_COL_KEYID, 25 * fontWidth); + ui->idTreeWidget->setColumnWidth(RSID_COL_NICKNAME, 14 * fontWidth); + ui->idTreeWidget->setColumnWidth(RSID_COL_KEYID, 20 * fontWidth); ui->idTreeWidget->setColumnWidth(RSID_COL_IDTYPE, 18 * fontWidth); + ui->idTreeWidget->setColumnWidth(RSID_COL_VOTES, 7 * fontWidth); + + //QHeaderView_setSectionResizeMode(ui->idTreeWidget->header(), QHeaderView::ResizeToContents); mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this); @@ -197,7 +187,7 @@ IdDialog::IdDialog(QWidget *parent) : // Hiding RepList until that part is finished. //ui->treeWidget_RepList->setVisible(false); - ui->toolButton_Reputation->setVisible(false); + #ifndef UNFINISHED ui->todoPushButton->hide() ; #endif @@ -225,8 +215,8 @@ IdDialog::IdDialog(QWidget *parent) : processSettings(true); // hide reputation sice it's currently unused - ui->reputationGroupBox->hide(); - ui->tweakGroupBox->hide(); + //ui->reputationGroupBox->hide(); + //ui->tweakGroupBox->hide(); } IdDialog::~IdDialog() @@ -300,6 +290,24 @@ void IdDialog::updateSelection() } } +static QString getHumanReadableDuration(uint32_t seconds) +{ + if(seconds < 60) + return QString(QObject::tr("%1 seconds ago")).arg(seconds) ; + else if(seconds < 120) + return QString(QObject::tr("%1 minute ago")).arg(seconds/60) ; + else if(seconds < 3600) + return QString(QObject::tr("%1 minutes ago")).arg(seconds/60) ; + else if(seconds < 7200) + return QString(QObject::tr("%1 hour ago")).arg(seconds/3600) ; + else if(seconds < 24*3600) + return QString(QObject::tr("%1 hours ago")).arg(seconds/3600) ; + else if(seconds < 2*24*3600) + return QString(QObject::tr("%1 day ago")).arg(seconds/86400) ; + else + return QString(QObject::tr("%1 days ago")).arg(seconds/86400) ; +} + void IdDialog::requestIdList() { //Disable by default, will be enable by insertIdDetails() @@ -366,11 +374,17 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item, if (!item) item = new QTreeWidgetItem(); + + RsReputations::ReputationInfo info ; + rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),info) ; item->setText(RSID_COL_NICKNAME, QString::fromUtf8(data.mMeta.mGroupName.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE)); item->setText(RSID_COL_KEYID, QString::fromStdString(data.mMeta.mGroupId.toStdString())); item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ; + + item->setTextAlignment(RSID_COL_VOTES, Qt::AlignRight); + item->setData(RSID_COL_VOTES,Qt::DisplayRole, QString::number(info.mOverallReputationScore - 1.0f,'f',3)); if(isOwnId) { @@ -491,6 +505,9 @@ void IdDialog::insertIdList(uint32_t token) ui->idTreeWidget->addTopLevelItem(item); } } + + /* count items */ + ui->label_count->setText( "(" + QString::number(ui->idTreeWidget->topLevelItemCount()) + ")" ); filterIds(); @@ -522,23 +539,6 @@ void IdDialog::requestIdDetails() mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDDIALOG_IDDETAILS); } -static QString getHumanReadableDuration(uint32_t seconds) -{ - if(seconds < 60) - return QString(QObject::tr("%1 seconds ago")).arg(seconds) ; - else if(seconds < 120) - return QString(QObject::tr("%1 minute ago")).arg(seconds/60) ; - else if(seconds < 3600) - return QString(QObject::tr("%1 minutes ago")).arg(seconds/60) ; - else if(seconds < 7200) - return QString(QObject::tr("%1 hour ago")).arg(seconds/3600) ; - else if(seconds < 24*3600) - return QString(QObject::tr("%1 hours ago")).arg(seconds/3600) ; - else if(seconds < 2*24*3600) - return QString(QObject::tr("%1 day ago")).arg(seconds/86400) ; - else - return QString(QObject::tr("%1 days ago")).arg(seconds/86400) ; -} void IdDialog::insertIdDetails(uint32_t token) { @@ -652,36 +652,9 @@ void IdDialog::insertIdDetails(uint32_t token) else ui->lineEdit_Type->setText(tr("Anonymous identity")) ; - // if (isOwnId) -// { -// ui->radioButton_IdYourself->setChecked(true); -// } -// else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) -// { -// if (data.mPgpKnown) -// { -// if (rsPeers->isGPGAccepted(data.mPgpId)) -// { -// ui->radioButton_IdFriend->setChecked(true); -// } -// else -// { -// ui->radioButton_IdFOF->setChecked(true); -// } -// } -// else -// { -// ui->radioButton_IdOther->setChecked(true); -// } -// } -// else -// { -// ui->radioButton_IdPseudo->setChecked(true); -// } - if (isOwnId) { - mStateHelper->setWidgetEnabled(ui->toolButton_Reputation, false); + mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, false); ui->editIdentity->setEnabled(true); ui->removeIdentity->setEnabled(true); ui->chatIdentity->setEnabled(false); @@ -690,7 +663,7 @@ void IdDialog::insertIdDetails(uint32_t token) else { // No Reputation yet! - mStateHelper->setWidgetEnabled(ui->toolButton_Reputation, /*true*/ false); + mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, true); ui->editIdentity->setEnabled(false); ui->removeIdentity->setEnabled(false); ui->chatIdentity->setEnabled(true); @@ -698,9 +671,8 @@ void IdDialog::insertIdDetails(uint32_t token) } /* now fill in the reputation information */ - ui->line_RatingOverall->setText("Overall Rating TODO"); - ui->line_RatingOwn->setText("Own Rating TODO"); +#ifdef SUSPENDED if (data.mPgpKnown) { ui->line_RatingImplicit->setText(tr("+50 Known PGP")); @@ -713,25 +685,28 @@ void IdDialog::insertIdDetails(uint32_t token) { ui->line_RatingImplicit->setText(tr("+5 Anon Id")); } - - { - QString rating = QString::number(data.mReputation.mOverallScore); - ui->line_RatingOverall->setText(rating); - } - { QString rating = QString::number(data.mReputation.mIdScore); ui->line_RatingImplicit->setText(rating); } - { - QString rating = QString::number(data.mReputation.mOwnOpinion); - ui->line_RatingOwn->setText(rating); - } +#endif + RsReputations::ReputationInfo info ; + rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),info) ; + + ui->neighborNodesOpinion_TF->setText(QString::number(info.mFriendAverage - 1.0f)); + + ui->overallOpinion_TF->setText(QString::number(info.mOverallReputationScore - 1.0f) +" ("+ + ((info.mAssessment == RsReputations::ASSESSMENT_OK)? tr("OK") : tr("Banned")) +")" ) ; + + switch(info.mOwnOpinion) { - QString rating = QString::number(data.mReputation.mPeerOpinion); - ui->line_RatingPeers->setText(rating); + case RsReputations::OPINION_NEGATIVE: ui->ownOpinion_CB->setCurrentIndex(0); break ; + case RsReputations::OPINION_NEUTRAL : ui->ownOpinion_CB->setCurrentIndex(1); break ; + case RsReputations::OPINION_POSITIVE: ui->ownOpinion_CB->setCurrentIndex(2); break ; + default: + std::cerr << "Unexpected value in own opinion: " << info.mOwnOpinion << std::endl; } } @@ -743,47 +718,38 @@ void IdDialog::modifyReputation() #endif RsGxsId id(ui->lineEdit_KeyId->text().toStdString()); + + RsReputations::Opinion op ; - int mod = 0; - if (ui->repMod_Accept->isChecked()) - { - mod += 100; - } - else if (ui->repMod_Positive->isChecked()) - { - mod += 10; - } - else if (ui->repMod_Negative->isChecked()) - { - mod += -10; - } - else if (ui->repMod_Ban->isChecked()) - { - mod += -100; - } - else if (ui->repMod_Custom->isChecked()) - { - mod += ui->repMod_spinBox->value(); - } - else - { - // invalid - return; - } + switch(ui->ownOpinion_CB->currentIndex()) + { + case 0: op = RsReputations::OPINION_NEGATIVE ; break ; + case 1: op = RsReputations::OPINION_NEUTRAL ; break ; + case 2: op = RsReputations::OPINION_POSITIVE ; break ; + default: + std::cerr << "Wrong value from opinion combobox. Bug??" << std::endl; + + } + rsReputations->setOwnOpinion(id,op) ; #ifdef ID_DEBUG std::cerr << "IdDialog::modifyReputation() ID: " << id << " Mod: " << mod; std::cerr << std::endl; #endif +#ifdef SUSPENDED + // Cyril: apparently the old reputation system was in used here. It's based on GXS data exchange, and probably not + // very efficient because of this. + uint32_t token; - if (!rsIdentity->submitOpinion(token, id, false, mod)) + if (!rsIdentity->submitOpinion(token, id, false, op)) { #ifdef ID_DEBUG std::cerr << "IdDialog::modifyReputation() Error submitting Opinion"; std::cerr << std::endl; #endif } +#endif #ifdef ID_DEBUG std::cerr << "IdDialog::modifyReputation() queuingRequest(), token: " << token; @@ -792,7 +758,8 @@ void IdDialog::modifyReputation() // trigger refresh when finished. // basic / anstype are not needed. - mIdQueue->queueRequest(token, 0, 0, IDDIALOG_REFRESH); + requestIdDetails(); + requestIdList(); return; } @@ -983,6 +950,29 @@ void IdDialog::IdListCustomPopupMenu( QPoint ) } contextMnu.addAction(QIcon(":/images/mail_new.png"), tr("Send message to this person"), this, SLOT(sendMsg())); + + contextMnu.addSeparator(); + + RsReputations::ReputationInfo info ; + std::string Id = item->text(RSID_COL_KEYID).toStdString(); + rsReputations->getReputationInfo(RsGxsId(Id),info) ; + + + QAction *banaction = contextMnu.addAction(QIcon(":/images/denied16.png"), tr("Ban this person"), this, SLOT(banPerson())); + QAction *unbanaction = contextMnu.addAction(QIcon(), tr("Unban this person"), this, SLOT(unbanPerson())); + + + if(info.mAssessment == RsReputations::ASSESSMENT_BAD) + { + banaction->setVisible(false); + unbanaction->setVisible(true); + } + else + { + banaction->setVisible(true); + unbanaction->setVisible(false); + } + } } @@ -1042,3 +1032,35 @@ void IdDialog::sendMsg() /* window will destroy itself! */ } + +void IdDialog::banPerson() +{ + QTreeWidgetItem *item = ui->idTreeWidget->currentItem(); + if (!item) + { + return; + } + + std::string Id = item->text(RSID_COL_KEYID).toStdString(); + + rsReputations->setOwnOpinion(RsGxsId(Id),RsReputations::OPINION_NEGATIVE) ; + + requestIdDetails(); + requestIdList(); +} + +void IdDialog::unbanPerson() +{ + QTreeWidgetItem *item = ui->idTreeWidget->currentItem(); + if (!item) + { + return; + } + + std::string Id = item->text(RSID_COL_KEYID).toStdString(); + + rsReputations->setOwnOpinion(RsGxsId(Id),RsReputations::OPINION_POSITIVE) ; + + requestIdDetails(); + requestIdList(); +} diff --git a/retroshare-gui/src/gui/Identity/IdDialog.h b/retroshare-gui/src/gui/Identity/IdDialog.h index a46a6ce73..8eb2b748f 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.h +++ b/retroshare-gui/src/gui/Identity/IdDialog.h @@ -75,6 +75,9 @@ private slots: /** Create the context popup menu and it's submenus */ void IdListCustomPopupMenu( QPoint point ); + void banPerson(); + void unbanPerson(); + private: void processSettings(bool load); diff --git a/retroshare-gui/src/gui/Identity/IdDialog.ui b/retroshare-gui/src/gui/Identity/IdDialog.ui index 4109e6bcb..778d218cb 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDialog.ui @@ -7,7 +7,7 @@ 0 0 826 - 752 + 630 @@ -20,7 +20,16 @@ - + + 0 + + + 0 + + + 0 + + 0 @@ -38,7 +47,16 @@ QFrame::Sunken - + + 2 + + + 2 + + + 2 + + 2 @@ -73,6 +91,13 @@ + + + + () + + + @@ -129,7 +154,16 @@ QFrame::Sunken - + + 2 + + + 2 + + + 2 + + 2 @@ -208,6 +242,14 @@ Owned by + + + Reputation + + + AlignLeading|AlignVCenter + + @@ -304,29 +346,21 @@ - + + 6 + + + 6 + + + 6 + + + 6 + + 6 - - - - Identity name : - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -334,6 +368,13 @@ + + + + Identity name : + + + @@ -457,7 +498,7 @@ 20 - 40 + 2 @@ -468,192 +509,140 @@ - - - - - - 0 - 0 - - - - Reputation - - - - - - - - - 75 - true - - - - Overall - - - - - - - true - - - - - - - Implicit - - - - - - - true - - - - - - - Opinion - - - - - - - true - - - - - - - Peers - - - - - - - true - - - - - - - - - Qt::NoFocus + + + + 0 + 0 + + + + Reputation + + + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + <html><head/><body><p>Average opinion of neighbor nodes about this identity. Negative is bad,</p><p>positive is good. Zero is neutral.</p></body></html> - - Edit reputation - - - - :/images/edit_24.png:/images/edit_24.png - - - - 24 - 24 - - - - Qt::ToolButtonTextBesideIcon - - + true - - - - - - - - 0 - 0 - - - - Tweak Opinion - - - - + + - Accept (+100) + Your opinion: - - + + - Positive (+10) + Neighbor nodes: - - - - Negative (-10) + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Your own opinion about an identity rules the visibility of that identity for yourself,</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">and is shared among friends. A final score is calculated according to a formula that accounts your own opinion and your friends' opinions about someone:</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> S = own_opinion * a + friends_opinion * (1-a)</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The factor 'a' depends on the type of ID. </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- anonymous IDs: </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- PGP-signed IDs by unknown PGP keys: a=</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The overall score is used in chat lobbies, forums and channels to decide on the actions to take for each specific identity:</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; -0.5: Posts are not stored, nor forwarded </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; 0.2: Posts are hidden, but still transmitted</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; 0.0: </p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The overall rating is computed in such a way that it is not possible for a single person to deterministically change someone's status at neighbor nodes.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> - - - - - - Ban (-100) + + 0 - - - - - - - Custom - - + + Negative + + + + ../icons/yellow_biohazard64.png../icons/yellow_biohazard64.png + - - - -100 - - - 100 - - + + Neutral + - + + + Positive + + + - - + + + + <html><head/><body><p>Overall reputation score, accounting for yours and your friends'.</p><p>Negative is bad, positive is good. Zero is neutral. If the score is too low,</p><p>the identity is flagged as bad, and will be filtered out in forums, chat lobbies,</p><p>channels, etc.</p></body></html> + + + true + + + + + + + + 75 + true + + - Modify + Overall: - - - + + + Qt::Vertical + + QSizePolicy::Expanding + 20 @@ -730,9 +719,6 @@ lineEdit_KeyId lineEdit_GpgId lineEdit_GpgName - line_RatingOverall - line_RatingImplicit - line_RatingOwn diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index e4bbc7662..9cd8c60e9 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -113,10 +113,16 @@ void IdEditDialog::changeAvatar() } } -void IdEditDialog::setupNewId(bool pseudo) +void IdEditDialog::setupNewId(bool pseudo,bool enable_anon) { setWindowTitle(tr("New identity")); + if(pseudo && !enable_anon) + { + std::cerr << "IdEditDialog::setupNewId: Error. Cannot init with pseudo-anonymous id when anon ids are disabled." << std::endl; + pseudo = false ; + } + mIsNew = true; mGroupId.clear(); @@ -139,7 +145,11 @@ void IdEditDialog::setupNewId(bool pseudo) ui->frame_Tags->setHidden(true); ui->radioButton_GpgId->setEnabled(true); - ui->radioButton_Pseudo->setEnabled(true); + + if(enable_anon) + ui->radioButton_Pseudo->setEnabled(true); + else + ui->radioButton_Pseudo->setEnabled(false); setAvatar(QPixmap()); diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.h b/retroshare-gui/src/gui/Identity/IdEditDialog.h index d46cd7de3..d97aee090 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.h +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.h @@ -45,7 +45,7 @@ public: IdEditDialog(QWidget *parent = 0); ~IdEditDialog(); - void setupNewId(bool pseudo); + void setupNewId(bool pseudo, bool enable_anon = true); void setupExistingId(const RsGxsGroupId &keyId); void enforceNoAnonIds() ; diff --git a/retroshare-gui/src/gui/MainWindow.cpp b/retroshare-gui/src/gui/MainWindow.cpp index be269db84..e3b975843 100644 --- a/retroshare-gui/src/gui/MainWindow.cpp +++ b/retroshare-gui/src/gui/MainWindow.cpp @@ -677,12 +677,20 @@ void MainWindow::updateTrayCombine() updateFriends(); } +void MainWindow::toggleStatusToolTip(bool toggle){ + if(!toggle)return; + QString tray = "RetroShare\n"; + tray += "\n" + nameAndLocation; + trayIcon->setToolTip(tray); +} + void MainWindow::updateStatus() { // This call is essential to remove locks due to QEventLoop re-entrance while asking gpg passwds. Dont' remove it! if(RsAutoUpdatePage::eventsLocked()) return; - + if(Settings->valueFromGroup("StatusBar", "DisableSysTrayToolTip", QVariant(false)).toBool()) + return; float downKb = 0; float upKb = 0; rsConfig->GetCurrentDataRates(downKb, upKb); diff --git a/retroshare-gui/src/gui/MainWindow.h b/retroshare-gui/src/gui/MainWindow.h index fae0dacbd..897740123 100644 --- a/retroshare-gui/src/gui/MainWindow.h +++ b/retroshare-gui/src/gui/MainWindow.h @@ -184,6 +184,7 @@ public slots: void setNewPage(int page); void setCompactStatusMode(bool compact); + void toggleStatusToolTip(bool toggle); protected: /** Default Constructor */ MainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0); diff --git a/retroshare-gui/src/gui/MessagesDialog.cpp b/retroshare-gui/src/gui/MessagesDialog.cpp index e09174f41..49fc7a9f5 100644 --- a/retroshare-gui/src/gui/MessagesDialog.cpp +++ b/retroshare-gui/src/gui/MessagesDialog.cpp @@ -1237,8 +1237,16 @@ void MessagesDialog::insertMessages() else if(it->msgflags & RS_MSG_DISTANT) { item->setIcon(COLUMN_SIGNATURE, QIcon(":/images/blue_lock_open.png")) ; - item->setToolTip(COLUMN_SIGNATURE, tr("This message comes from a distant person.")) ; item->setIcon(COLUMN_SUBJECT, QIcon(":/images/message-mail-read.png")) ; + + if (msgbox == RS_MSG_INBOX ) + { + item->setToolTip(COLUMN_SIGNATURE, tr("This message comes from a distant person.")) ; + } + else if (msgbox == RS_MSG_OUTBOX) + { + item->setToolTip(COLUMN_SIGNATURE, tr("This message goes to a distant person.")) ; + } if(it->msgflags & RS_MSG_SIGNED) { diff --git a/retroshare-gui/src/gui/NetworkDialog.cpp b/retroshare-gui/src/gui/NetworkDialog.cpp index 16ee66b0d..416045d15 100644 --- a/retroshare-gui/src/gui/NetworkDialog.cpp +++ b/retroshare-gui/src/gui/NetworkDialog.cpp @@ -393,6 +393,8 @@ void NetworkDialog::insertConnect() /* get a link to the table */ QTreeWidget *connectWidget = ui.connectTreeWidget; + /* disable sorting while editing the table */ + connectWidget->setSortingEnabled(false); //remove items int index = 0; @@ -560,7 +562,10 @@ void NetworkDialog::insertConnect() } connectWidget->addTopLevelItem(self_item); - connectWidget->update(); /* update display */ + /* enable sorting */ + connectWidget->setSortingEnabled(true); + /* update display */ + connectWidget->update(); if (ui.filterLineEdit->text().isEmpty() == false) { filterItems(ui.filterLineEdit->text()); diff --git a/retroshare-gui/src/gui/QuickStartWizard.cpp b/retroshare-gui/src/gui/QuickStartWizard.cpp index bc684b7bf..08f314959 100644 --- a/retroshare-gui/src/gui/QuickStartWizard.cpp +++ b/retroshare-gui/src/gui/QuickStartWizard.cpp @@ -183,11 +183,26 @@ void QuickStartWizard::on_pushButtonSharesExit_clicked() close(); } -void QuickStartWizard::on_pushButtonSystemBack_clicked() +void QuickStartWizard::on_pushButtonStyleBack_clicked() { ui.pagesWizard->setCurrentIndex(2); } +void QuickStartWizard::on_pushButtonStyleNext_clicked() +{ + ui.pagesWizard->setCurrentIndex(4); +} + +void QuickStartWizard::on_pushButtonStyleExit_clicked() +{ + close(); +} + +void QuickStartWizard::on_pushButtonSystemBack_clicked() +{ + ui.pagesWizard->setCurrentIndex(3); +} + void QuickStartWizard::on_pushButtonSystemFinish_clicked() { Settings->setStartMinimized(ui.checkBoxStartMinimized->isChecked()); @@ -390,6 +405,9 @@ QuickStartWizard::loadGeneral() ui.checkBoxStartMinimized->setChecked(Settings->getStartMinimized()); ui.checkBoxQuit->setChecked(Settings->value("doQuit", false).toBool()); + ui.rbtPageOnToolBar->setChecked(Settings->getPageButtonLoc()); + ui.rbtPageOnListItem->setChecked(!Settings->getPageButtonLoc()); + //ui.checkBoxQuickWizard->setChecked(settings.value(QString::fromUtf8("FirstRun"), false).toBool()); } @@ -419,6 +437,12 @@ void QuickStartWizard::loadNetwork() case RS_NETMODE_UDP: netIndex = 1; break; + case RS_NETMODE_HIDDEN: + ui.netModeLabel->hide(); + ui.netModeComboBox->hide(); + ui.discoveryLabel->hide(); + ui.discoveryComboBox->hide(); + break; default: case RS_NETMODE_UPNP: netIndex = 0; @@ -472,6 +496,8 @@ void QuickStartWizard::saveChanges() //bool saveAddr = false; + Settings->setPageButtonLoc(ui.rbtPageOnToolBar->isChecked()); + RsPeerDetails detail; RsPeerId ownId = rsPeers->getOwnId(); diff --git a/retroshare-gui/src/gui/QuickStartWizard.h b/retroshare-gui/src/gui/QuickStartWizard.h index fc88fd530..756dcd592 100644 --- a/retroshare-gui/src/gui/QuickStartWizard.h +++ b/retroshare-gui/src/gui/QuickStartWizard.h @@ -60,6 +60,9 @@ private Q_SLOTS: void on_pushButtonSharesExit_clicked(); void on_pushButtonSharesNext_clicked(); void on_pushButtonSharesBack_clicked(); + void on_pushButtonStyleExit_clicked(); + void on_pushButtonStyleNext_clicked(); + void on_pushButtonStyleBack_clicked(); void on_pushButtonWelcomeExit_clicked(); void on_pushButtonWelcomeNext_clicked(); void on_pushButtonConnectionExit_clicked(); diff --git a/retroshare-gui/src/gui/QuickStartWizard.ui b/retroshare-gui/src/gui/QuickStartWizard.ui index 2bd83d2a1..ede111c52 100644 --- a/retroshare-gui/src/gui/QuickStartWizard.ui +++ b/retroshare-gui/src/gui/QuickStartWizard.ui @@ -9,7 +9,7 @@ 0 0 - 445 + 457 370 @@ -36,7 +36,16 @@ true - + + 0 + + + 0 + + + 0 + + 0 @@ -48,11 +57,20 @@ - 0 + 1 - + + 0 + + + 0 + + + 0 + + 0 @@ -73,7 +91,16 @@ QFrame::Sunken - + + 4 + + + 4 + + + 4 + + 4 @@ -188,7 +215,16 @@ p, li { white-space: pre-wrap; } - + + 0 + + + 0 + + + 0 + + 0 @@ -291,7 +327,7 @@ p, li { white-space: pre-wrap; } QFormLayout::AllNonFixedFieldsGrow - + Connection : @@ -317,7 +353,7 @@ p, li { white-space: pre-wrap; } - + Discovery : @@ -443,7 +479,16 @@ p, li { white-space: pre-wrap; } - + + 0 + + + 0 + + + 0 + + 0 @@ -674,9 +719,137 @@ p, li { white-space: pre-wrap; } + + + + + + + 0 + 228 + + + + Qt::NoContextMenu + + + RetroShare Page Display Style + + + + + + Where do you want to have the buttons for the page? + + + + + + + ToolBar View + + + + + + + List View + + + + + + + Qt::Vertical + + + + 20 + 204 + + + + + + + + + + + 4 + + + 4 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + < Back + + + + + + + Next > + + + true + + + + + + + Exit + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + - + + 0 + + + 0 + + + 0 + + 0 @@ -697,8 +870,17 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - - 4 + + 6 + + + 6 + + + 6 + + + 6 4 diff --git a/retroshare-gui/src/gui/RemoteDirModel.cpp b/retroshare-gui/src/gui/RemoteDirModel.cpp index df3cf0c14..6c64a7b89 100644 --- a/retroshare-gui/src/gui/RemoteDirModel.cpp +++ b/retroshare-gui/src/gui/RemoteDirModel.cpp @@ -590,7 +590,7 @@ QVariant RetroshareDirModel::data(const QModelIndex &index, int role) const QVariant TreeStyle_RDM::headerData(int section, Qt::Orientation orientation, int role) const { - if (role == Qt::SizeHintRole) + /*if (role == Qt::SizeHintRole) { int defw = QFontMetricsF(QWidget().font()).width(headerData(section,Qt::Horizontal,Qt::DisplayRole).toString()) ; int defh = QFontMetricsF(QWidget().font()).height(); @@ -600,7 +600,7 @@ QVariant TreeStyle_RDM::headerData(int section, Qt::Orientation orientation, int defw = 200/16.0*defh; } return QSize(defw, defh); - } + }*/ if (role != Qt::DisplayRole) return QVariant(); @@ -636,7 +636,7 @@ QVariant TreeStyle_RDM::headerData(int section, Qt::Orientation orientation, int } QVariant FlatStyle_RDM::headerData(int section, Qt::Orientation orientation, int role) const { - if (role == Qt::SizeHintRole) + /*if (role == Qt::SizeHintRole) { int defw = QFontMetricsF(QWidget().font()).width(headerData(section,Qt::Horizontal,Qt::DisplayRole).toString()) ; int defh = QFontMetricsF(QWidget().font()).height(); @@ -646,7 +646,7 @@ QVariant FlatStyle_RDM::headerData(int section, Qt::Orientation orientation, int defw = defh*200/16.0; } return QSize(defw, defh); - } + }*/ if (role != Qt::DisplayRole) return QVariant(); diff --git a/retroshare-gui/src/gui/RetroShareLink.cpp b/retroshare-gui/src/gui/RetroShareLink.cpp index 702b73369..5754d5831 100644 --- a/retroshare-gui/src/gui/RetroShareLink.cpp +++ b/retroshare-gui/src/gui/RetroShareLink.cpp @@ -195,7 +195,9 @@ void RetroShareLink::fromUrl(const QUrl& url) if (url.scheme() != RSLINK_SCHEME) { /* No RetroShare-Link */ +#ifdef DEBUG_RSLINK std::cerr << "Not a RS link: scheme=" << url.scheme().toStdString() << std::endl; +#endif return; } diff --git a/retroshare-gui/src/gui/SearchDialog.cpp b/retroshare-gui/src/gui/SearchDialog.cpp index ea2a7d933..553912f99 100644 --- a/retroshare-gui/src/gui/SearchDialog.cpp +++ b/retroshare-gui/src/gui/SearchDialog.cpp @@ -244,6 +244,9 @@ void SearchDialog::processSettings(bool bLoad) // state of splitter ui.splitter->restoreState(Settings->value("Splitter").toByteArray()); + + ui._max_results_SB->setValue(Settings->value("MaxResults").toInt()); + } else { // save settings @@ -252,6 +255,8 @@ void SearchDialog::processSettings(bool bLoad) // state of splitter Settings->setValue("Splitter", ui.splitter->saveState()); + + Settings->setValue("MaxResults", ui._max_results_SB->value()); } Settings->endGroup(); diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp index b4a26dddb..a4be2189f 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp @@ -79,7 +79,7 @@ /** Constructor */ WikiDialog::WikiDialog(QWidget *parent) -: MainPage(parent) +: RsGxsUpdateBroadcastPage(rsWiki, parent) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); @@ -103,11 +103,6 @@ WikiDialog::WikiDialog(QWidget *parent) connect(ui.groupTreeWidget, SIGNAL(treeCustomContextMenuRequested(QPoint)), this, SLOT(groupListCustomPopupMenu(QPoint))); connect(ui.groupTreeWidget, SIGNAL(treeItemActivated(QString)), this, SLOT(wikiGroupChanged(QString))); - - QTimer *timer = new QTimer(this); - timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); - timer->start(1000); - /* setup TokenQueue */ mWikiQueue = new TokenQueue(rsWiki->getTokenService(), this); @@ -118,8 +113,6 @@ WikiDialog::WikiDialog(QWidget *parent) mPopularGroups = ui.groupTreeWidget->addCategoryItem(tr("Popular Groups"), QIcon(IMAGE_FOLDERGREEN), false); mOtherGroups = ui.groupTreeWidget->addCategoryItem(tr("Other Groups"), QIcon(IMAGE_FOLDERYELLOW), false); - //Auto refresh seems not to work, temporary solution at start - insertWikiGroups(); } WikiDialog::~WikiDialog() @@ -127,20 +120,6 @@ WikiDialog::~WikiDialog() delete(mWikiQueue); } -void WikiDialog::checkUpdate() -{ - /* update */ - if (!rsWiki) - return; - - if (rsWiki->updated()) - { - insertWikiGroups(); - } - - return; -} - void WikiDialog::OpenOrShowAddPageDialog() { RsGxsGroupId groupId = getSelectedGroup(); @@ -362,11 +341,6 @@ const RsGxsGroupId& WikiDialog::getSelectedGroup() /************************** Request / Response *************************/ /*** Loading Main Index ***/ -void WikiDialog::insertWikiGroups() -{ - requestGroupMeta(); -} - void WikiDialog::requestGroupMeta() { std::cerr << "WikiDialog::requestGroupMeta()"; @@ -528,7 +502,7 @@ void WikiDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) #define GXSGROUP_NEWGROUPID 1 case GXSGROUP_NEWGROUPID: - insertWikiGroups(); + requestGroupMeta(); break; default: std::cerr << "WikiDialog::loadRequest() ERROR: INVALID TYPE"; @@ -716,3 +690,20 @@ void WikiDialog::todo() "
  • Auto update Group trees" ""); } + +void WikiDialog::updateDisplay(bool complete) +{ + if (complete || !getGrpIds().empty() || !getGrpIdsMeta().empty()) { + /* Update group list */ + requestGroupMeta(); + } else { + /* Update all groups of changed messages */ + std::map > msgIds; + getAllMsgIds(msgIds); + + std::map >::iterator msgIt; + for (msgIt = msgIds.begin(); msgIt != msgIds.end(); ++msgIt) { + wikiGroupChanged(QString::fromStdString(msgIt->first.toStdString())); + } + } +} diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.h b/retroshare-gui/src/gui/WikiPoos/WikiDialog.h index f0dbd8c64..bf6a609ee 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.h +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.h @@ -26,7 +26,7 @@ #include -#include "retroshare-gui/mainpage.h" +#include "gui/gxs/RsGxsUpdateBroadcastPage.h" #include "ui_WikiDialog.h" #include @@ -40,7 +40,7 @@ class WikiAddDialog; class WikiEditDialog; -class WikiDialog : public MainPage, public TokenResponse +class WikiDialog : public RsGxsUpdateBroadcastPage, public TokenResponse { Q_OBJECT @@ -52,12 +52,13 @@ public: virtual QString pageName() const { return tr("Wiki Pages") ; } //MainPage virtual QString helpText() const { return ""; } //MainPage + void loadRequest(const TokenQueue *queue, const TokenRequest &req); -void loadRequest(const TokenQueue *queue, const TokenRequest &req); +public: + virtual void updateDisplay(bool complete); private slots: - void checkUpdate(); void OpenOrShowAddPageDialog(); void OpenOrShowAddGroupDialog(); void OpenOrShowEditDialog(); @@ -69,8 +70,6 @@ private slots: void showGroupDetails(); void editGroupDetails(); - void insertWikiGroups(); - // GroupTreeWidget stuff. void groupListCustomPopupMenu(QPoint point); void subscribeToGroup(); diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp index be5bc0721..709d0262c 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp @@ -733,7 +733,7 @@ void WikiEditDialog::loadBaseHistory(const uint32_t &token) modItem->setText(WET_COL_DATE, text); modItem->setData(WET_COL_DATE, WET_ROLE_SORT, sort); } - modItem->setId(page.mMeta.mAuthorId, WET_COL_AUTHORID); + modItem->setId(page.mMeta.mAuthorId, WET_COL_AUTHORID, false); modItem->setText(WET_COL_PAGEID, QString::fromStdString(page.mMeta.mMsgId.toStdString())); ui.treeWidget_History->addTopLevelItem(modItem); @@ -847,7 +847,7 @@ void WikiEditDialog::loadEditTreeData(const uint32_t &token) modItem->setText(WET_COL_DATE, text); modItem->setData(WET_COL_DATE, WET_ROLE_SORT, sort); } - modItem->setId(snapshot.mMeta.mAuthorId, WET_COL_AUTHORID); + modItem->setId(snapshot.mMeta.mAuthorId, WET_COL_AUTHORID, false); modItem->setText(WET_COL_PAGEID, QString::fromStdString(snapshot.mMeta.mMsgId.toStdString())); /* find the parent */ diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp b/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp index c4ea3c1cc..e87120c4a 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp @@ -34,6 +34,7 @@ #include "gui/settings/RsharePeerSettings.h" #include "gui/MainWindow.h" #include "gui/FriendsDialog.h" +#include "gui/msgs/MessageComposer.h" #include #include "gui/common/RSTreeWidgetItem.h" #include "gui/common/FriendSelectionDialog.h" @@ -52,6 +53,8 @@ #define COLUMN_ID 3 #define COLUMN_COUNT 4 +const static uint32_t timeToInactivity = 60 * 10; // in seconds + /** Default constructor */ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WindowFlags flags) : ChatDialog(parent, flags), lobbyId(lid) @@ -66,18 +69,20 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi connect(ui.participantsList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(participantsTreeWidgetDoubleClicked(QTreeWidgetItem*,int))); int S = QFontMetricsF(font()).height() ; - ui.participantsList->setIconSize(QSize(S,S)); + ui.participantsList->setIconSize(QSize(1.3*S,1.3*S)); ui.participantsList->setColumnCount(COLUMN_COUNT); - ui.participantsList->setColumnWidth(COLUMN_ICON, 1.25*S); + ui.participantsList->setColumnWidth(COLUMN_ICON, 1.4*S); ui.participantsList->setColumnHidden(COLUMN_ACTIVITY,true); ui.participantsList->setColumnHidden(COLUMN_ID,true); - muteAct = new QAction(QIcon(), tr("Mute participant"), this); - distantChatAct = new QAction(QIcon(), tr("Start private chat"), this); + muteAct = new QAction(QIcon(), tr("Mute participant"), this); + distantChatAct = new QAction(QIcon(":/images/chat_24.png"), tr("Start private chat"), this); + sendMessageAct = new QAction(QIcon(":/images/mail_new.png"), tr("Send Message"), this); connect(muteAct, SIGNAL(triggered()), this, SLOT(changePartipationState())); connect(distantChatAct, SIGNAL(triggered()), this, SLOT(distantChatParticipant())); + connect(sendMessageAct, SIGNAL(triggered()), this, SLOT(sendMessage())); // Add a button to invite friends. // @@ -170,12 +175,15 @@ void ChatLobbyDialog::participantsTreeWidgetCustomPopupMenu(QPoint) QMenu contextMnu(this); - contextMnu.addAction(muteAct); contextMnu.addAction(distantChatAct); + contextMnu.addAction(sendMessageAct); + contextMnu.addSeparator(); + contextMnu.addAction(muteAct); + muteAct->setCheckable(true); muteAct->setEnabled(false); - muteAct->setChecked(false); + muteAct->setChecked(false); if (selectedItems.size()) { @@ -362,7 +370,7 @@ void ChatLobbyDialog::addChatMsg(const ChatMessage& msg) else name = QString::fromUtf8(msg.peer_alternate_nickname.c_str()) + " (" + QString::fromStdString(gxs_id.toStdString()) + ")" ; - ui.chatWidget->addChatMsg(msg.incoming, name, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL); + ui.chatWidget->addChatMsg(msg.incoming, name, gxs_id, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL); emit messageReceived(msg.incoming, id(), sendTime, name, message) ; // This is a trick to translate HTML into text. @@ -425,7 +433,8 @@ void ChatLobbyDialog::updateParticipantsList() widgetitem = new GxsIdRSTreeWidgetItem(mParticipantCompareRole,GxsIdDetails::ICON_TYPE_AVATAR); widgetitem->setId(it2->first,COLUMN_NAME, true) ; //widgetitem->setText(COLUMN_NAME, participant); - widgetitem->setText(COLUMN_ACTIVITY,QString::number(time(NULL))); + // set activity time to the oast so that the peer is marked as inactive + widgetitem->setText(COLUMN_ACTIVITY,QString::number(time(NULL) - timeToInactivity)); widgetitem->setText(COLUMN_ID,QString::fromStdString(it2->first.toStdString())); ui.participantsList->addTopLevelItem(widgetitem); @@ -443,16 +452,16 @@ void ChatLobbyDialog::updateParticipantsList() time_t now = time(NULL); if(isParticipantMuted(it2->first)) - widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_red_64.png")); - else if (tLastActsetIcon(COLUMN_ICON, QIcon(":/icons/bullet_grey_64.png")); - else - widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_green_64.png")); + widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_red_128.png")); + else if (tLastAct + timeToInactivity < now) + widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_grey_128.png")); + else + widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_green_128.png")); RsGxsId gxs_id; rsMsgs->getIdentityForChatLobby(lobbyId, gxs_id); - if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_yellow_64.png")); + if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_yellow_128.png")); QTime qtLastAct=QTime(0,0,0).addSecs(now-tLastAct); widgetitem->setToolTip(COLUMN_ICON,tr("Right click to mute/unmute participants
    Double click to address this person
    ") @@ -572,6 +581,36 @@ void ChatLobbyDialog::distantChatParticipant() } } +void ChatLobbyDialog::sendMessage() +{ + + QList selectedItems = ui.participantsList->selectedItems(); + + if (selectedItems.isEmpty()) + return; + + QList::iterator item; + for (item = selectedItems.begin(); item != selectedItems.end(); ++item) { + + RsGxsId gxs_id ; + dynamic_cast(*item)->getId(gxs_id) ; + + + MessageComposer *nMsgDialog = MessageComposer::newMsg(); + if (nMsgDialog == NULL) { + return; + } + + nMsgDialog->addRecipient(MessageComposer::TO, RsGxsId(gxs_id)); + nMsgDialog->show(); + nMsgDialog->activateWindow(); + + /* window will destroy itself! */ + + } + +} + void ChatLobbyDialog::muteParticipant(const RsGxsId& nickname) { diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.h b/retroshare-gui/src/gui/chat/ChatLobbyDialog.h index 7729abba8..a11a1d73b 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.h +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.h @@ -77,6 +77,7 @@ protected slots: void changePartipationState(); void distantChatParticipant(); void participantsTreeWidgetDoubleClicked(QTreeWidgetItem *item, int column); + void sendMessage(); private: void updateParticipantsList(); @@ -101,9 +102,10 @@ private: /** Ignored Users in Chatlobby by nickname until we had implemented Peer Ids in ver 0.6 */ std::set mutedParticipants; - QAction *muteAct; + QAction *muteAct; QAction *distantChatAct; QWidgetAction *checkableAction; + QAction *sendMessageAct; GxsIdChooser *ownIdChooser ; }; diff --git a/retroshare-gui/src/gui/chat/ChatStyle.cpp b/retroshare-gui/src/gui/chat/ChatStyle.cpp index 7bc382dbd..b6a27b90c 100644 --- a/retroshare-gui/src/gui/chat/ChatStyle.cpp +++ b/retroshare-gui/src/gui/chat/ChatStyle.cpp @@ -351,11 +351,14 @@ QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, co Q_UNUSED(flag); #endif - QString formatMsg = style.replace("%name%", RsHtml::plainText(name)) - .replace("%date%", DateTime::formatDate(timestamp.date())) - .replace("%time%", DateTime::formatTime(timestamp.time())) + QString strName = RsHtml::plainText(name).prepend(QString("")).append(QString("")); + QString strDate = DateTime::formatDate(timestamp.date()).prepend(QString("")).append(QString("")); + QString strTime = DateTime::formatTime(timestamp.time()).prepend(QString("")).append(QString("")); + QString formatMsg = style.replace("%name%", strName) + .replace("%date%", strDate) + .replace("%time%", strTime) #ifdef COLORED_NICKNAMES - .replace("%color%", color.name()) + .replace("%color%", color.name()) #endif .replace("%message%", messageBody ) ; if ( !styleOptimized.isEmpty() ) { diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index 12667f03e..5bf42f035 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -214,7 +214,7 @@ void ChatWidget::setDefaultExtraFileFlags(TransferRequestFlags fl) void ChatWidget::addChatHorizontalWidget(QWidget *w) { - ui->verticalLayout_2->addWidget(w) ; + ui->vl_Plugins->addWidget(w) ; update() ; } @@ -223,9 +223,15 @@ void ChatWidget::addChatBarWidget(QWidget *w) ui->pluginButtonFrame->layout()->addWidget(w) ; } -void ChatWidget::addVOIPBarWidget(QWidget *w) +void ChatWidget::addTitleBarWidget(QWidget *w) { - ui->titleBarFrame->layout()->addWidget(w) ; + ui->pluginTitleFrame->layout()->addWidget(w) ; +} + +void ChatWidget::hideChatText(bool hidden) +{ + ui->frame_ChatText->setHidden(hidden); ; + ui->searchframe->setVisible(ui->actionSearch_History->isChecked() && !hidden); ; } RSButtonOnText* ChatWidget::getNewButtonOnTextBrowser() @@ -489,10 +495,10 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event) QKeyEvent *keyEvent = static_cast(event); if (keyEvent) { - if (notify && keyEvent->key() == Qt::Key_Delete) { + if (keyEvent->key() == Qt::Key_Delete) { // Delete key pressed if (ui->textBrowser->textCursor().selectedText().length() > 0) { - if (chatType() == CHATTYPE_LOBBY) { + if (notify && chatType() == CHATTYPE_LOBBY) { QRegExp rx("textBrowser->textCursor().selection().toHtml(); @@ -840,6 +846,13 @@ void ChatWidget::setWelcomeMessage(QString &text) } void ChatWidget::addChatMsg(bool incoming, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message, MsgType chatType) +{ + addChatMsg(incoming, name, RsGxsId(), sendTime, recvTime, message, chatType); +} + +void ChatWidget::addChatMsg(bool incoming, const QString &name, const RsGxsId gxsId + , const QDateTime &sendTime, const QDateTime &recvTime + , const QString &message, MsgType chatType) { #ifdef CHAT_DEBUG std::cout << "ChatWidget::addChatMsg message : " << message.toStdString() << std::endl; @@ -871,6 +884,7 @@ void ChatWidget::addChatMsg(bool incoming, const QString &name, const QDateTime if (!Settings->valueFromGroup("Chat", "EnableCustomFontSize", true).toBool()) { formatTextFlag |= RSHTML_FORMATTEXT_REMOVE_FONT_SIZE; } + int desiredMinimumFontSize = Settings->valueFromGroup("Chat", "MinimumFontSize", 10).toInt(); if (!Settings->valueFromGroup("Chat", "EnableBold", true).toBool()) { formatTextFlag |= RSHTML_FORMATTEXT_REMOVE_FONT_WEIGHT; } @@ -894,13 +908,20 @@ void ChatWidget::addChatMsg(bool incoming, const QString &name, const QDateTime formatFlag |= CHAT_FORMATMSG_SYSTEM; } - QString formattedMessage = RsHtml().formatText(ui->textBrowser->document(), message, formatTextFlag, backgroundColor, desiredContrast); + QString formattedMessage = RsHtml().formatText(ui->textBrowser->document(), message, formatTextFlag, backgroundColor, desiredContrast, desiredMinimumFontSize); QDateTime dtTimestamp=incoming ? sendTime : recvTime; QString formatMsg = chatStyle.formatMessage(type, name, dtTimestamp, formattedMessage, formatFlag); QString timeStamp = dtTimestamp.toString(Qt::ISODate); - formatMsg.prepend(QString("").arg(timeStamp)); - //To call this anchor do: ui->textBrowser->scrollToAnchor(QString("%1_%2").arg(timeStamp).arg(name)); + //replace Date and Time anchors + formatMsg.replace(QString(""),QString("").arg(timeStamp)); + formatMsg.replace(QString(""),QString("").arg(timeStamp)); + //replace Name anchors with GXS Id + QString strGxsId = ""; + if (!gxsId.isNull()) + strGxsId = QString::fromStdString(gxsId.toStdString()); + formatMsg.replace(QString(""),QString("").arg(strGxsId)); + QTextCursor textCursor = QTextCursor(ui->textBrowser->textCursor()); textCursor.movePosition(QTextCursor::End); textCursor.setBlockFormat(QTextBlockFormat ()); diff --git a/retroshare-gui/src/gui/chat/ChatWidget.h b/retroshare-gui/src/gui/chat/ChatWidget.h index 312f9d879..d93df9496 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.h +++ b/retroshare-gui/src/gui/chat/ChatWidget.h @@ -94,6 +94,7 @@ public: void setWelcomeMessage(QString &text); void addChatMsg(bool incoming, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message, MsgType chatType); + void addChatMsg(bool incoming, const QString &name, const RsGxsId gxsId, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message, MsgType chatType); void updateStatusString(const QString &statusMask, const QString &statusString, bool permanent = false); void addToolsAction(QAction *action); @@ -108,9 +109,8 @@ public: // Adds one widget in the chat bar. Used to add e.g. new buttons. The widget should be // small enough in size. void addChatBarWidget(QWidget *w) ; - - - void addVOIPBarWidget(QWidget *w); + void addTitleBarWidget(QWidget *w); + void hideChatText(bool hidden); RSButtonOnText* getNewButtonOnTextBrowser(); RSButtonOnText* getNewButtonOnTextBrowser(QString text); diff --git a/retroshare-gui/src/gui/chat/ChatWidget.ui b/retroshare-gui/src/gui/chat/ChatWidget.ui index 02b3f9afc..5d3fb6ba9 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.ui +++ b/retroshare-gui/src/gui/chat/ChatWidget.ui @@ -17,13 +17,538 @@ 0 - - + + + + 2 + + + + + + 20 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 178 + + + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 178 + + + + + + + + + 255 + 255 + 178 + + + + + + + 255 + 255 + 178 + + + + + + + + true + + + QFrame::Box + + + + 6 + + + + + + 16 + 16 + + + + + + + :/images/info16.png + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + TextLabel + + + + + + + + 16 + 16 + + + + Qt::NoFocus + + + Close + + + QToolButton +{ + border-image: url(:/images/closenormal.png) +} + +QToolButton:hover +{ +border-image: url(:/images/closehover.png) +} + +QToolButton:pressed { +border-image: url(:/images/closepressed.png) +} + + + true + + + + + + + + + + Qt::Vertical + + + 2 + + + false + + + + + 0 + 0 + + + + + 0 + 30 + + + + Qt::CustomContextMenu + + + + + + 0 + + + + + + + + 18 + 18 + + + + + 18 + 18 + + + + T + + + Qt::AlignCenter + + + + + + + + 400 + 18 + + + + 0 + + + 3 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 0 + + + + + 0 + 30 + + + + Type a message here + + + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 2 + + + + + + 0 + 0 + + + + + 28 + 28 + + + + + 28 + 28 + + + + Qt::NoFocus + + + + :/images/emoticons/kopete/kopete020.png:/images/emoticons/kopete/kopete020.png + + + + 24 + 24 + + + + true + + + + + + + + 32 + 28 + + + + + 32 + 28 + + + + Qt::TabFocus + + + Set text font & color + + + + :/images/textedit/format-text-color.png:/images/textedit/format-text-color.png + + + + 24 + 24 + + + + QToolButton::InstantPopup + + + true + + + + + + + + 28 + 28 + + + + + 28 + 28 + + + + Qt::NoFocus + + + Attach a Picture + + + + :/images/add_image24.png:/images/add_image24.png + + + + 24 + 24 + + + + true + + + + + + + + 28 + 28 + + + + Qt::NoFocus + + + Attach a File + + + + :/images/attach.png:/images/attach.png + + + + 24 + 24 + + + + true + + + + + + + + 28 + 28 + + + + + 28 + 28 + + + + Qt::NoFocus + + + + :/images/configure.png:/images/configure.png + + + + 24 + 24 + + + + QToolButton::InstantPopup + + + true + + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + + 2 + + + + + + + + Qt::Horizontal + + + + 190 + 25 + + + + + + + + Send + + + + + + + + + + true + + + + + + + + + + + + QLayout::SetMaximumSize + + + + 0 + 0 + + + + + 16777215 + 64 + + QFrame::Box @@ -103,6 +628,21 @@ + + + + QFrame::NoFrame + + + QFrame::Plain + + + + 2 + + + + @@ -295,478 +835,6 @@ - - - - true - - - - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 178 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 178 - - - - - - - - - 255 - 255 - 178 - - - - - - - 255 - 255 - 178 - - - - - - - - true - - - QFrame::Box - - - - 6 - - - - - - 16 - 16 - - - - - - - :/images/info16.png - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - TextLabel - - - - - - - - 16 - 16 - - - - Qt::NoFocus - - - Close - - - QToolButton -{ - border-image: url(:/images/closenormal.png) -} - -QToolButton:hover -{ -border-image: url(:/images/closehover.png) -} - -QToolButton:pressed { -border-image: url(:/images/closepressed.png) -} - - - true - - - - - - - - - - Qt::Vertical - - - 2 - - - false - - - - - 0 - 0 - - - - - 0 - 30 - - - - Qt::CustomContextMenu - - - - - - 0 - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - 18 - 18 - - - - - 18 - 18 - - - - T - - - Qt::AlignCenter - - - - - - - 0 - - - 3 - - - - 400 - 18 - - - - - - - - - - - 0 - 0 - - - - - 0 - 30 - - - - Type a message here - - - - - - - - - - - QFrame::Box - - - QFrame::Sunken - - - - 2 - - - - - - 0 - 0 - - - - - 28 - 28 - - - - - 28 - 28 - - - - Qt::NoFocus - - - - :/images/emoticons/kopete/kopete020.png:/images/emoticons/kopete/kopete020.png - - - - 24 - 24 - - - - true - - - - - - - - 32 - 28 - - - - - 32 - 28 - - - - Qt::TabFocus - - - Set text font & color - - - - :/images/textedit/format-text-color.png:/images/textedit/format-text-color.png - - - - 24 - 24 - - - - QToolButton::InstantPopup - - - true - - - - - - - - 28 - 28 - - - - - 28 - 28 - - - - Qt::NoFocus - - - Attach a Picture - - - - :/images/add_image24.png:/images/add_image24.png - - - - 24 - 24 - - - - true - - - - - - - - 28 - 28 - - - - Qt::NoFocus - - - Attach a File - - - - :/images/attach.png:/images/attach.png - - - - 24 - 24 - - - - true - - - - - - - - 28 - 28 - - - - - 28 - 28 - - - - Qt::NoFocus - - - - :/images/configure.png:/images/configure.png - - - - 24 - 24 - - - - QToolButton::InstantPopup - - - true - - - - - - - QFrame::NoFrame - - - QFrame::Plain - - - - 2 - - - - - - - - Qt::Horizontal - - - - 190 - 25 - - - - - - - - Send - - - - - - diff --git a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp index f8be00f33..12911efc9 100644 --- a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp +++ b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp @@ -48,8 +48,11 @@ PopupDistantChatDialog::PopupDistantChatDialog(const DistantChatPeerId& tunnel_i { _tunnel_id = tunnel_id ; - _status_label = new QLabel ; + _status_label = new QToolButton ; _update_timer = new QTimer ; + + _status_label->setAutoRaise(true); + _status_label->setIconSize(QSize(24,24)); _update_timer->setInterval(1000) ; QObject::connect(_update_timer,SIGNAL(timeout()),this,SLOT(updateDisplay())) ; @@ -100,10 +103,11 @@ void PopupDistantChatDialog::updateDisplay() ui.avatarWidget->setId(ChatId(_tunnel_id)); QString msg; + switch(tinfo.status) { case RS_DISTANT_CHAT_STATUS_UNKNOWN: //std::cerr << "Unknown hash. Error!" << std::endl; - _status_label->setPixmap(QPixmap(IMAGE_GRY_LED)) ; + _status_label->setIcon(QIcon(IMAGE_GRY_LED)) ; msg = tr("Chat remotely closed. Please close this window."); _status_label->setToolTip(msg) ; getChatWidget()->updateStatusString("%1", msg, true); @@ -111,7 +115,7 @@ void PopupDistantChatDialog::updateDisplay() setPeerStatus(RS_STATUS_OFFLINE) ; break ; case RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED: std::cerr << "Chat remotely closed. " << std::endl; - _status_label->setPixmap(QPixmap(IMAGE_RED_LED)) ; + _status_label->setIcon(QIcon(IMAGE_RED_LED)) ; _status_label->setToolTip(QObject::tr("Distant peer has closed the chat")) ; getChatWidget()->updateStatusString("%1", tr("The person you're talking to has deleted the secured chat tunnel. You may remove the chat window now."), true); @@ -120,7 +124,7 @@ void PopupDistantChatDialog::updateDisplay() break ; case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: //std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl; - _status_label->setPixmap(QPixmap(IMAGE_RED_LED)) ; + _status_label->setIcon(QIcon(IMAGE_RED_LED)) ; msg = QObject::tr("Tunnel is pending..."); _status_label->setToolTip(msg) ; getChatWidget()->updateStatusString("%1", msg, true); @@ -128,7 +132,7 @@ void PopupDistantChatDialog::updateDisplay() setPeerStatus(RS_STATUS_OFFLINE) ; break ; case RS_DISTANT_CHAT_STATUS_CAN_TALK: //std::cerr << "Tunnel is ok and data is transmitted." << std::endl; - _status_label->setPixmap(QPixmap(IMAGE_GRN_LED)) ; + _status_label->setIcon(QIcon(IMAGE_GRN_LED)) ; msg = QObject::tr("Secured tunnel is working. You can talk!"); _status_label->setToolTip(msg) ; getChatWidget()->unblockSending(); diff --git a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h index e0d00b7f3..dfe75b9de 100644 --- a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h +++ b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h @@ -50,7 +50,7 @@ class PopupDistantChatDialog: public PopupChatDialog private: QTimer *_update_timer ; DistantChatPeerId _tunnel_id ; - QLabel *_status_label ; + QToolButton *_status_label ; friend class ChatDialog; }; diff --git a/retroshare-gui/src/gui/common/ElidedLabel.cpp b/retroshare-gui/src/gui/common/ElidedLabel.cpp index a18aaf299..934756dc4 100644 --- a/retroshare-gui/src/gui/common/ElidedLabel.cpp +++ b/retroshare-gui/src/gui/common/ElidedLabel.cpp @@ -221,5 +221,7 @@ void ElidedLabel::mousePressEvent(QMouseEvent *ev) { if (mElided && (ev->buttons()==Qt::LeftButton) && (mRectElision.contains(ev->pos()))){ QToolTip::showText(mapToGlobal(QPoint(0, 0)),QString("") + mContent + QString("")); + return; // eat event } + QLabel::mousePressEvent(ev); } diff --git a/retroshare-gui/src/gui/common/GroupTreeWidget.cpp b/retroshare-gui/src/gui/common/GroupTreeWidget.cpp index c9eb59302..2f70e7987 100644 --- a/retroshare-gui/src/gui/common/GroupTreeWidget.cpp +++ b/retroshare-gui/src/gui/common/GroupTreeWidget.cpp @@ -96,7 +96,7 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) : QHeaderView_setSectionResizeModeColumn(header, COLUMN_NAME, QHeaderView::Stretch); header->resizeSection(COLUMN_NAME, 10*S); QHeaderView_setSectionResizeModeColumn(header, COLUMN_POPULARITY, QHeaderView::Fixed); - header->resizeSection(COLUMN_POPULARITY, 1.5*S); + header->resizeSection(COLUMN_POPULARITY, 2*S); /* add filter actions */ ui->filterLineEdit->addFilter(QIcon(), tr("Title"), FILTER_NAME_INDEX , tr("Search Title")); @@ -106,7 +106,7 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) : /* Initialize display button */ initDisplayMenu(ui->displayButton); - ui->treeWidget->setIconSize(QSize(S*1.2,S*1.2)) ; + ui->treeWidget->setIconSize(QSize(S*1.6,S*1.6)) ; } GroupTreeWidget::~GroupTreeWidget() diff --git a/retroshare-gui/src/gui/common/StatusDefs.cpp b/retroshare-gui/src/gui/common/StatusDefs.cpp index b0756c88f..486312c61 100644 --- a/retroshare-gui/src/gui/common/StatusDefs.cpp +++ b/retroshare-gui/src/gui/common/StatusDefs.cpp @@ -182,6 +182,10 @@ QString StatusDefs::connectStateString(RsPeerDetails &details) stateString = qApp->translate("StatusDefs", "Connected: Tor"); isConnected = true; break; + case RS_PEER_CONNECTSTATE_CONNECTED_I2P: + stateString = qApp->translate("StatusDefs", "Connected: I2P"); + isConnected = true; + break; case RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN: stateString = qApp->translate("StatusDefs", "Connected: Unknown"); isConnected = true; @@ -231,6 +235,7 @@ QString StatusDefs::connectStateWithoutTransportTypeString(RsPeerDetails &detail case RS_PEER_CONNECTSTATE_CONNECTED_TCP: case RS_PEER_CONNECTSTATE_CONNECTED_UDP: case RS_PEER_CONNECTSTATE_CONNECTED_TOR: + case RS_PEER_CONNECTSTATE_CONNECTED_I2P: case RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN: stateString = qApp->translate("StatusDefs", "Connected"); break; @@ -258,6 +263,9 @@ QString StatusDefs::connectStateIpString(RsPeerDetails &details) case RS_PEER_CONNECTSTATE_CONNECTED_TOR: stateString += QString(details.actAsServer ? qApp->translate("StatusDefs", "Tor-in") : qApp->translate("StatusDefs", "Tor-out")); break; + case RS_PEER_CONNECTSTATE_CONNECTED_I2P: + stateString += QString(details.actAsServer ? qApp->translate("StatusDefs", "I2P-in") : qApp->translate("StatusDefs", "I2P-out")); + break; case RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN: stateString += qApp->translate("StatusDefs", "unkown"); break; diff --git a/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp b/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp index 80aaf7698..7990b92c4 100755 --- a/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp +++ b/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp @@ -103,7 +103,21 @@ ConnectFriendWizard::ConnectFriendWizard(QWidget *parent) : ui->requestinfolabel->hide(); connect(ui->acceptNoSignGPGCheckBox,SIGNAL(toggled(bool)), ui->_options_GB,SLOT(setEnabled(bool))) ; - connect(ui->addKeyToKeyring_CB,SIGNAL(toggled(bool)), ui->acceptNoSignGPGCheckBox,SLOT(setChecked(bool))) ; + connect(ui->addKeyToKeyring_CB,SIGNAL(toggled(bool)), ui->acceptNoSignGPGCheckBox,SLOT(setChecked(bool))) ; + + connect(ui->gmailButton, SIGNAL(clicked()), this, SLOT(inviteGmail())); + connect(ui->yahooButton, SIGNAL(clicked()), this, SLOT(inviteYahoo())); + connect(ui->outlookButton, SIGNAL(clicked()), this, SLOT(inviteOutlook())); + connect(ui->aolButton, SIGNAL(clicked()), this, SLOT(inviteAol())); + connect(ui->yandexButton, SIGNAL(clicked()), this, SLOT(inviteYandex())); + connect(ui->emailButton, SIGNAL(clicked()), this, SLOT(runEmailClient2())); + + + subject = tr("RetroShare Invitation"); + body = GetStartedDialog::GetInviteText(); + + body += "\n" + GetStartedDialog::GetCutBelowText(); + body += "\n\n" + QString::fromUtf8(rsPeers->GetRetroshareInvite(false).c_str()); updateStylesheet(); } @@ -351,13 +365,23 @@ void ConnectFriendWizard::initializePage(int id) case Page_Rsid: ui->RsidPage->registerField("friendRSID*", ui->friendRsidEdit); break; + case Page_WebMail: + case Page_Email: + { ui->EmailPage->registerField("addressEdit*", ui->addressEdit); ui->EmailPage->registerField("subjectEdit*", ui->subjectEdit); ui->subjectEdit->setText(tr("RetroShare Invitation")); ui->inviteTextEdit->setPlainText(GetStartedDialog::GetInviteText()); + + QString body = ui->inviteTextEdit->toPlainText(); + body += "\n" + GetStartedDialog::GetCutBelowText(); + body += "\n\n" + QString::fromUtf8(rsPeers->GetRetroshareInvite(false).c_str()); + + ui->inviteTextEdit->setPlainText(body); + } break; case Page_ErrorMessage: break; @@ -488,6 +512,7 @@ void ConnectFriendWizard::initializePage(int id) } ui->nodeEdit->setText(loc); + ui->ipEdit->setText(QString::fromStdString(peerDetails.isHiddenNode ? peerDetails.hiddenNodeAddress : peerDetails.extAddr)); ui->signersEdit->setPlainText(ts); fillGroups(this, ui->groupComboBox, groupId); @@ -730,6 +755,7 @@ int ConnectFriendWizard::nextId() const if (ui->certRadioButton->isChecked()) return Page_Cert; if (ui->foffRadioButton->isChecked()) return Page_Foff; if (ui->rsidRadioButton->isChecked()) return Page_Rsid; + if (ui->webmailRadioButton->isChecked()) return Page_WebMail; if (ui->emailRadioButton->isChecked()) return Page_Email; if (ui->friendRecommendationsRadioButton->isChecked()) return Page_FriendRecommendations; return ConnectFriendWizard::Page_Foff; @@ -738,6 +764,7 @@ int ConnectFriendWizard::nextId() const case Page_Rsid: return error ? ConnectFriendWizard::Page_Conclusion : ConnectFriendWizard::Page_ErrorMessage; case Page_Foff: + case Page_WebMail: case Page_Email: case Page_ErrorMessage: case Page_Conclusion: @@ -1205,4 +1232,34 @@ void ConnectFriendWizard::groupCurrentIndexChanged(int index) } } +//========================== WebMailPage ================================== +void ConnectFriendWizard::inviteGmail() +{ + QDesktopServices::openUrl(QUrl("https://mail.google.com/mail/?view=cm&fs=1&su=" + subject + "&body=" + body , QUrl::TolerantMode)); +} + +void ConnectFriendWizard::inviteYahoo() +{ + QDesktopServices::openUrl(QUrl("http://compose.mail.yahoo.com/?&subject=" + subject + "&body=" + body, QUrl::TolerantMode)); +} + +void ConnectFriendWizard::inviteOutlook() +{ + QDesktopServices::openUrl(QUrl("http://mail.live.com/mail/EditMessageLight.aspx?n=&subject=" + subject + "&body=" + body, QUrl::TolerantMode)); +} + +void ConnectFriendWizard::inviteAol() +{ + QDesktopServices::openUrl(QUrl("http://webmail.aol.com/Mail/ComposeMessage.aspx?&subject=" + subject + "&body=" + body, QUrl::TolerantMode)); +} + +void ConnectFriendWizard::inviteYandex() +{ + QDesktopServices::openUrl(QUrl("https://mail.yandex.com/neo2/#compose/subject=" + subject + "&body=" + body, QUrl::TolerantMode)); +} + +void ConnectFriendWizard::runEmailClient2() +{ + sendMail("", subject, body ); +} diff --git a/retroshare-gui/src/gui/connect/ConnectFriendWizard.h b/retroshare-gui/src/gui/connect/ConnectFriendWizard.h index edb08b99f..54eb71062 100755 --- a/retroshare-gui/src/gui/connect/ConnectFriendWizard.h +++ b/retroshare-gui/src/gui/connect/ConnectFriendWizard.h @@ -30,7 +30,7 @@ class ConnectFriendWizard : public QWizard Q_PROPERTY(QString titleColor READ titleColor WRITE setTitleColor) public: - enum Page { Page_Intro, Page_Text, Page_Cert, Page_ErrorMessage, Page_Conclusion, Page_Foff, Page_Rsid, Page_Email, Page_FriendRequest, Page_FriendRecommendations }; + enum Page { Page_Intro, Page_Text, Page_Cert, Page_ErrorMessage, Page_Conclusion, Page_Foff, Page_Rsid, Page_WebMail, Page_Email, Page_FriendRequest, Page_FriendRecommendations }; ConnectFriendWizard(QWidget *parent = 0); ~ConnectFriendWizard(); @@ -62,6 +62,7 @@ private slots: void toggleSignatureState(bool doUpdate = true); void toggleFormatState(bool doUpdate = true); void runEmailClient(); + void runEmailClient2(); void showHelpUserCert(); void copyCert(); void pasteCert(); @@ -81,6 +82,14 @@ private slots: /* ConclusionPage */ void groupCurrentIndexChanged(int index); + + /* WebMailPage */ + void inviteGmail(); + void inviteYahoo(); + void inviteOutlook(); + void inviteAol(); + void inviteYandex(); + private: // returns the translated error string for the error code (to be found in rspeers.h) @@ -109,6 +118,10 @@ private: /* ConclusionPage */ QString groupId; + + /* WebMailPage */ + QString subject; + QString body; Ui::ConnectFriendWizard *ui; }; diff --git a/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui b/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui index f5f6ce6bf..df15425a5 100644 --- a/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui +++ b/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui @@ -7,7 +7,7 @@ 0 0 691 - 650 + 644 @@ -22,7 +22,7 @@ Add a new Friend - This wizard will help you to connect to your friend(s) to RetroShare network.<br>These ways are possible to do this: + This wizard will help you to connect to your friend(s) to RetroShare network.<br>Select how you would like to add a friend: ConnectFriendWizard::Page_Intro @@ -31,7 +31,7 @@ - &Enter the certificate manually + Enter the certificate manually @@ -52,7 +52,14 @@ - &Enter RetroShare ID manually + Enter RetroShare ID manually + + + + + + + &Send an Invitation by Web Mail Providers @@ -60,14 +67,14 @@ &Send an Invitation by Email - (She/He receives an email with instructions how to to download RetroShare) + (Your friend will receive an email with instructions how to to download RetroShare) - Recommend many friends to each others + Recommend many friends to each other @@ -271,7 +278,7 @@ - Please, paste your friends PGP certificate into the box below + Please, paste your friend's PGP certificate into the box below @@ -504,6 +511,227 @@ + + + RetroShare is better with Friends + + + Invite your Friends from other Networks to RetroShare. + + + ConnectFriendWizard::Page_WebMail + + + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 40 + 20 + + + + + + + + GMail + + + + :/icons/gmail.png:/icons/gmail.png + + + + 32 + 32 + + + + false + + + + + + + Yahoo + + + + :/icons/yahoo.png:/icons/yahoo.png + + + + 32 + 32 + + + + false + + + + + + + Outlook + + + + :/icons/outlook.png:/icons/outlook.png + + + + 32 + 32 + + + + false + + + + + + + AOL + + + + :/icons/aol.png:/icons/aol.png + + + + 32 + 32 + + + + false + + + + + + + Yandex + + + + :/icons/yandex.png:/icons/yandex.png + + + + 32 + 32 + + + + false + + + + + + + Email + + + + :/icons/mail_128.png:/icons/mail_128.png + + + + 32 + 32 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 444 + + + + + + Invite Friends by Email @@ -883,7 +1111,8 @@ QFrame::Box - Please note that RetroShare will require excessive amounts of bandwidth, memory and CPU if you add to many friends. You can add as many friends as you like, but more than 40 will probably require too much resources. + Please note that RetroShare will require excessive amounts of bandwidth, memory and CPU if you add too many friends. You can add as many friends as you like, but more than 40 will probably require too much +resources. true @@ -1038,21 +1267,21 @@ - + Signers - + true - + This peer is already on your friend list. Adding it might just set it's ip address. @@ -1062,6 +1291,20 @@ + + + + IP-Addr: + + + + + + + IP-Address + + + @@ -1338,6 +1581,7 @@ + diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index 19b315164..353f509c0 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -37,18 +37,24 @@ #include // Control of Publish Signatures. -#define RSGXS_GROUP_SIGN_PUBLISH_MASK 0x000000ff -#define RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED 0x00000001 -#define RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED 0x00000002 -#define RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD 0x00000004 -#define RSGXS_GROUP_SIGN_PUBLISH_NONEREQ 0x00000008 +// +// These are now defined in rsgxsflags.h +// +// #define FLAG_GROUP_SIGN_PUBLISH_MASK 0x000000ff +// #define FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED 0x00000001 +// #define FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED 0x00000002 +// #define FLAG_GROUP_SIGN_PUBLISH_THREADHEAD 0x00000004 +// #define FLAG_GROUP_SIGN_PUBLISH_NONEREQ 0x00000008 -// Author Signature. -#define RSGXS_GROUP_SIGN_AUTHOR_MASK 0x0000ff00 -#define RSGXS_GROUP_SIGN_AUTHOR_GPG 0x00000100 -#define RSGXS_GROUP_SIGN_AUTHOR_REQUIRED 0x00000200 -#define RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN 0x00000400 -#define RSGXS_GROUP_SIGN_AUTHOR_NONE 0x00000800 +// // Author Signature. +// +// These are now defined in rsgxsflags.h +// +// #define FLAG_AUTHOR_AUTHENTICATION_MASK 0x0000ff00 +// #define FLAG_AUTHOR_AUTHENTICATION_NONE 0x00000000 +// #define FLAG_AUTHOR_AUTHENTICATION_GPG 0x00000100 +// #define FLAG_AUTHOR_AUTHENTICATION_REQUIRED 0x00000200 +// #define FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN 0x00000400 #define GXSGROUP_NEWGROUPID 1 #define GXSGROUP_LOADGROUP 2 @@ -123,6 +129,10 @@ void GxsGroupDialog::init() ui.groupDesc->setPlaceholderText(tr("Set a descriptive description here")); + ui.personal_ifnopub->hide() ; + ui.personal_required->hide() ; + ui.personal_required->setChecked(true) ; // this is always true + initMode(); } @@ -288,7 +298,12 @@ void GxsGroupDialog::setupDefaults() ui.comments_no->setChecked(true); ui.comments_no_3->setChecked(true); } - } + } + ui.antiSpam_trackMessages->setChecked((bool)(mDefaultsFlags & GXS_GROUP_DEFAULTS_ANTISPAM_TRACK)); + ui.antiSpam_signedIds->setChecked((bool)(mDefaultsFlags & GXS_GROUP_DEFAULTS_ANTISPAM_FAVOR_PGP)); + ui.antiSpam_trackMessages_2->setChecked((bool)(mDefaultsFlags & GXS_GROUP_DEFAULTS_ANTISPAM_TRACK)); + ui.antiSpam_signedIds_2->setChecked((bool)(mDefaultsFlags & GXS_GROUP_DEFAULTS_ANTISPAM_FAVOR_PGP)); + #ifndef RS_USE_CIRCLES ui.typeGroup->setEnabled(false); ui.typeLocal->setEnabled(false); @@ -308,6 +323,9 @@ void GxsGroupDialog::setupVisibility() ui.distribGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DISTRIBUTION); ui.distribGroupBox_2->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DISTRIBUTION); + + ui.spamProtection_GB->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ANTI_SPAM); + ui.spamProtection_GB_2->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ANTI_SPAM); ui.publishGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PUBLISHSIGN); @@ -347,6 +365,8 @@ void GxsGroupDialog::setupReadonly() ui.distribGroupBox_2->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_DISTRIBUTION)); ui.commentGroupBox_2->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_COMMENTS)); + ui.spamProtection_GB->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_ANTI_SPAM)); + ui.spamProtection_GB_2->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_ANTI_SPAM)); ui.extraFrame->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_EXTRA)); #ifndef UNFINISHED @@ -376,6 +396,7 @@ void GxsGroupDialog::updateFromExistingMeta(const QString &description) setupVisibility(); setupReadonly(); clearForm(); + setGroupSignFlags(mGrpMeta.mSignFlags) ; /* setup name */ ui.groupName->setText(QString::fromUtf8(mGrpMeta.mGroupName.c_str())); @@ -576,54 +597,59 @@ uint32_t GxsGroupDialog::getGroupSignFlags() /* grab from the ui options -> */ uint32_t signFlags = 0; if (ui.publish_encrypt->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED; + signFlags |= GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED; } else if (ui.publish_required->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED; + signFlags |= GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED; } else if (ui.publish_threads->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD; + signFlags |= GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_THREADHEAD; } else { // publish_open (default). - signFlags |= RSGXS_GROUP_SIGN_PUBLISH_NONEREQ; + signFlags |= GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_NONEREQ; } + if (ui.personal_required->isChecked()) + signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED; + + if (ui.personal_ifnopub->isChecked()) + signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN; + // Author Signature. - if (ui.personal_pgp->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_AUTHOR_GPG; - } else if (ui.personal_required->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_AUTHOR_REQUIRED; - } else if (ui.personal_ifnopub->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN; - } else { // shouldn't allow this one. - signFlags |= RSGXS_GROUP_SIGN_AUTHOR_NONE; - } + if (ui.antiSpam_signedIds->isChecked()) + signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG; + + if (ui.antiSpam_trackMessages->isChecked()) + signFlags |= GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES; + return signFlags; } void GxsGroupDialog::setGroupSignFlags(uint32_t signFlags) { - if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED) { + if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED) { ui.publish_encrypt->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED) { + } else if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED) { ui.publish_required->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD) { + } else if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_THREADHEAD) { ui.publish_threads->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_NONEREQ) { + } else if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_NONEREQ) { ui.publish_open->setChecked(true); } - if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_GPG) { - ui.personal_pgp->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_REQUIRED) { + if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED) ui.personal_required->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN) { + + if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN) ui.personal_ifnopub->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_NONE) { - // Its the same... but not quite. - //ui.personal_noifpub->setChecked(); - } - + + ui.antiSpam_trackMessages ->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) ); + ui.antiSpam_signedIds ->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) ); + ui.antiSpam_trackMessages_2->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) ); + ui.antiSpam_signedIds_2 ->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) ); + //ui.SignEdIds->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) ); + //ui.trackmessagesradioButton->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) ); + /* guess at comments */ - if ((signFlags & RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD) && - (signFlags & RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN)) + if ((signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_THREADHEAD) && + (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN)) { ui.comments_allowed->setChecked(true); ui.comments_allowed_3->setChecked(true); diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index ab93a2038..7f94c32db 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -63,14 +63,14 @@ public: #define GXS_GROUP_FLAGS_SHAREKEYS 0x00000020 #define GXS_GROUP_FLAGS_PERSONALSIGN 0x00000040 #define GXS_GROUP_FLAGS_COMMENTS 0x00000080 - #define GXS_GROUP_FLAGS_EXTRA 0x00000100 +#define GXS_GROUP_FLAGS_ANTI_SPAM 0x00000200 /*** Default flags are used to determine privacy of group, signatures required *** *** whether publish or id and whether comments are allowed or not ***/ -#define GXS_GROUP_DEFAULTS_DISTRIB_MASK 0x0000000f -#define GXS_GROUP_DEFAULTS_PUBLISH_MASK 0x000000f0 +#define GXS_GROUP_DEFAULTS_DISTRIB_MASK 0x0000000f +#define GXS_GROUP_DEFAULTS_PUBLISH_MASK 0x000000f0 #define GXS_GROUP_DEFAULTS_PERSONAL_MASK 0x00000f00 #define GXS_GROUP_DEFAULTS_COMMENTS_MASK 0x0000f000 @@ -78,18 +78,21 @@ public: #define GXS_GROUP_DEFAULTS_DISTRIB_GROUP 0x00000002 #define GXS_GROUP_DEFAULTS_DISTRIB_LOCAL 0x00000004 -#define GXS_GROUP_DEFAULTS_PUBLISH_OPEN 0x00000010 +#define GXS_GROUP_DEFAULTS_PUBLISH_OPEN 0x00000010 #define GXS_GROUP_DEFAULTS_PUBLISH_THREADS 0x00000020 #define GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED 0x00000040 #define GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED 0x00000080 -#define GXS_GROUP_DEFAULTS_PERSONAL_PGP 0x00000100 +#define GXS_GROUP_DEFAULTS_PERSONAL_PGP 0x00000100 #define GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED 0x00000200 #define GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB 0x00000400 -#define GXS_GROUP_DEFAULTS_COMMENTS_YES 0x00001000 +#define GXS_GROUP_DEFAULTS_COMMENTS_YES 0x00001000 #define GXS_GROUP_DEFAULTS_COMMENTS_NO 0x00002000 +#define GXS_GROUP_DEFAULTS_ANTISPAM_FAVOR_PGP 0x00100000 +#define GXS_GROUP_DEFAULTS_ANTISPAM_TRACK 0x00200000 + /*! * The aim of this dialog is to be convenient to encapsulate group * creation code for several GXS services such forums, channels diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui index c8fdc33d9..4e2cb03bd 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui @@ -6,8 +6,8 @@ 0 0 - 685 - 517 + 928 + 400 @@ -44,19 +44,10 @@ QFrame::Raised - 1 + 0 - - 9 - - - 6 - - - 0 - @@ -205,190 +196,114 @@ - - - - Publish Signatures + + + + true - - - 6 - - - 9 - - - 4 - - - 9 - - - 4 - - - - - Open - - - - - - - New Thread - - - - - - - Required - - - - - - - Encrypted Msgs - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + 0 + 0 + + + + + 300 + 524287 + + + + + 220 + 0 + + + + + 0 + 0 + + + + check peers you would like to share private publish key with + + + false + + + QDockWidget::NoDockWidgetFeatures + + + Share Key With + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 4 + + + + + 20 + 0 + + + + + 300 + 16777215 + + + + + 220 + 0 + + + + + 200 + 0 + + + + + + - - + + - Personal Signatures + Description - - - 6 - - - 9 - - - 4 - - - 9 - - - 4 - + - - - PGP Required - - - - - - - Signature Required - - - - - - - If No Publish Signature - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - + - - - - Comments - - - - 6 - - - 9 - - - 4 - - - 9 - - - 4 - - - - - Allow Comments - - - - - - - No Comments - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - @@ -490,125 +405,259 @@ - - + + - Description + Publish Signatures - + + + 6 + + + 9 + + + 4 + + + 9 + + + 4 + - + + + Open + + + + + + + New Thread + + + + + + + Required + + + + + + + Encrypted Msgs + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + - - - - true + + + + Personal Signatures - - - 0 - 0 - + + + + + PGP Required + + + + + + + Signature Required + + + + + + + If No Publish Signature + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Comments - - - 300 - 524287 - + + + 6 + + + 9 + + + 4 + + + 9 + + + 4 + + + + + Allow Comments + + + + + + + No Comments + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Spam-protection - - - 220 - 0 - + + + 6 + + + 9 + + + 4 + + + 9 + + + 4 + + + + + <html><head/><body><p>This makes the media increase the reputation threshold to 0.4 for anonymous ids, while keeping it to 0.0 for PGP-linked ids. Therefore, anonymous ids can still post, if their local reputation score is above that threshold.</p></body></html> + + + Favor PGP-signed ids + + + + + + + <html><head/><body><p align="justify">This feature allows Retroshare to locally keep a record of who forwarded each message to you, for the last 10 days. Although useless if alone (and already available whatsoever) this information can be used by a group of collaborative friends to easily locate the source of spams. To be used with care, since it significantly decreases the anonymity of message posts.</p></body></html> + + + Keep track of posts + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + QFrame::StyledPanel - - - 0 - 0 - + + QFrame::Raised - - check peers you would like to share private publish key with - - - false - - - QDockWidget::NoDockWidgetFeatures - - - Share Key With - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 4 - - - - - 20 - 0 - - - - - 300 - 16777215 - - - - - 220 - 0 - - - - - 200 - 0 - - - - - - + + + + Description + + + + + + true + + + + + + Info - + @@ -717,7 +766,7 @@ - + @@ -775,28 +824,28 @@ - + true - + true - + true - + true @@ -824,7 +873,7 @@ - + @@ -865,29 +914,68 @@ - + GxsIdLabel - - - - - - - Description - - - - - - true + + + + Anti spam + + + + + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + PGP-signed ids + + + + + + + Track of Posts + + + + + + + Qt::Horizontal + + + + 718 + 20 + + + + + + + diff --git a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp index 7fb83f131..522f927ec 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp @@ -27,6 +27,7 @@ #include "gui/Identity/IdEditDialog.h" #include +#include #include #include @@ -42,6 +43,8 @@ #define TYPE_UNKNOWN_ID 3 #define TYPE_CREATE_ID 4 +#define BANNED_ICON ":/icons/yellow_biohazard64.png" + #define IDCHOOSER_REFRESH 1 //#define IDCHOOSER_DEBUG @@ -138,7 +141,6 @@ static void loadPrivateIdsCallback(GxsIdDetailsType type, const RsIdentityDetail switch (type) { case GXS_ID_DETAILS_TYPE_EMPTY: case GXS_ID_DETAILS_TYPE_FAILED: -// icons = ; break; case GXS_ID_DETAILS_TYPE_LOADING: @@ -148,17 +150,49 @@ static void loadPrivateIdsCallback(GxsIdDetailsType type, const RsIdentityDetail case GXS_ID_DETAILS_TYPE_DONE: GxsIdDetails::getIcons(details, icons); break; + + case GXS_ID_DETAILS_TYPE_BANNED: + icons.push_back(QIcon(BANNED_ICON)) ; + break; } chooser->setItemData(index, QString("%1_%2").arg((type == GXS_ID_DETAILS_TYPE_DONE) ? TYPE_FOUND_ID : TYPE_UNKNOWN_ID).arg(text), ROLE_SORT); chooser->setItemData(index, (type == GXS_ID_DETAILS_TYPE_DONE) ? TYPE_FOUND_ID : TYPE_UNKNOWN_ID, ROLE_TYPE); chooser->setItemIcon(index, icons.empty() ? QIcon() : icons[0]); + std::cerr << "ID=" << details.mId << ", chooser->flags()=" << chooser->flags() << ", pgpLinked=" << details.mPgpLinked ; + + if((chooser->flags() & IDCHOOSER_NON_ANONYMOUS) && !(details.mPgpLinked)) + { + std::cerr << " - disabling ID - entry = " << index << std::endl; + chooser->setEntryEnabled(index,false) ; + } + std::cerr << std::endl; + chooser->model()->sort(0); chooser->blockSignals(false) ; } +void GxsIdChooser::setEntryEnabled(int indx,bool enabled) +{ + bool disable = !enabled ; + + QSortFilterProxyModel* model = qobject_cast(QComboBox::model()); + //QStandardItem* item = model->item(index); + + QModelIndex ii = model->index(indx,0); + + // visually disable by greying out - works only if combobox has been painted already and palette returns the wanted color + //model->setFlags(ii,disable ? (model->flags(ii) & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled)) : (Qt::ItemIsSelectable|Qt::ItemIsEnabled)); + + uint32_t v = enabled?(1|32):(0); + + // clear item data in order to use default color + //model->setData(ii,disable ? (QComboBox::palette().color(QPalette::Disabled, QPalette::Text)) : QVariant(), Qt::TextColorRole); + model->setData(ii,QVariant(v),Qt::UserRole-1) ; +} + void GxsIdChooser::loadPrivateIds() { if (mFirstLoad) { @@ -217,6 +251,8 @@ void GxsIdChooser::loadPrivateIds() addItem(QIcon(":/images/identity/identity_create_32.png"), str, id); setItemData(count() - 1, QString("%1_%2").arg(TYPE_CREATE_ID).arg(str), ROLE_SORT); setItemData(count() - 1, TYPE_CREATE_ID, ROLE_TYPE); + + } setDefaultItem(); emit idsLoaded(); @@ -299,7 +335,7 @@ void GxsIdChooser::indexActivated(int index) int type = itemData(index, ROLE_TYPE).toInt(); if (type == TYPE_CREATE_ID) { IdEditDialog dlg(this); - dlg.setupNewId(false); + dlg.setupNewId(false, !(mFlags & IDCHOOSER_NON_ANONYMOUS)); if (dlg.exec() == QDialog::Accepted) { setDefaultId(RsGxsId(dlg.groupId())); } diff --git a/retroshare-gui/src/gui/gxs/GxsIdChooser.h b/retroshare-gui/src/gui/gxs/GxsIdChooser.h index e785fb227..98c33a052 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdChooser.h +++ b/retroshare-gui/src/gui/gxs/GxsIdChooser.h @@ -37,6 +37,7 @@ class RsGxsUpdateBroadcastBase; #define IDCHOOSER_ID_REQUIRED 0x0001 #define IDCHOOSER_ANON_DEFAULT 0x0002 #define IDCHOOSER_NO_CREATE 0x0004 +#define IDCHOOSER_NON_ANONYMOUS 0x0008 class GxsIdChooser : public QComboBox { @@ -48,6 +49,7 @@ public: virtual ~GxsIdChooser(); void setFlags(uint32_t flags) ; + uint32_t flags() const { return mFlags ; } enum ChosenId_Ret {None, KnowId, UnKnowId, NoId} ; void loadIds(uint32_t chooserFlags, const RsGxsId &defId); @@ -56,6 +58,7 @@ public: bool setChosenId(const RsGxsId &gxsId); ChosenId_Ret getChosenId(RsGxsId &gxsId); + void setEntryEnabled(int index, bool enabled); signals: // emitted after first load of own ids void idsLoaded(); @@ -71,13 +74,13 @@ private slots: private: void loadPrivateIds(); - void setDefaultItem(); + void setDefaultItem(); uint32_t mFlags; RsGxsId mDefaultId; bool mFirstLoad; - RsGxsUpdateBroadcastBase *mBase; + RsGxsUpdateBroadcastBase *mBase; }; #endif diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp index aab87ddf7..400498823 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp @@ -29,6 +29,7 @@ #include #include "GxsIdDetails.h" #include "retroshare-gui/RsAutoUpdatePage.h" +#include "retroshare/rsreputations.h" #include @@ -40,6 +41,7 @@ #define IMAGE_PGPKNOWN ":/images/contact.png" #define IMAGE_PGPUNKNOWN ":/images/tags/pgp-unknown.png" #define IMAGE_ANON ":/images/tags/anon.png" +#define IMAGE_BANNED ":/icons/yellow_biohazard64.png" #define IMAGE_DEV_AMBASSADOR ":/images/tags/dev-ambassador.png" #define IMAGE_DEV_CONTRIBUTOR ":/images/tags/vote_down.png" @@ -821,6 +823,9 @@ QString GxsIdDetails::getNameForType(GxsIdDetailsType type, const RsIdentityDeta case GXS_ID_DETAILS_TYPE_DONE: return getName(details); + case GXS_ID_DETAILS_TYPE_BANNED: + return tr("[Banned]") ; + case GXS_ID_DETAILS_TYPE_FAILED: return getFailedText(details.mId); } @@ -873,7 +878,10 @@ bool GxsIdDetails::MakeIdDesc(const RsGxsId &id, bool doIcons, QString &str, QLi QString GxsIdDetails::getName(const RsIdentityDetails &details) { - QString name = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE); + if(rsReputations->isIdentityBanned(details.mId)) + return tr("[Banned]") ; + + QString name = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE); std::list::const_iterator it; for (it = details.mRecognTags.begin(); it != details.mRecognTags.end(); ++it) @@ -887,9 +895,18 @@ QString GxsIdDetails::getName(const RsIdentityDetails &details) QString GxsIdDetails::getComment(const RsIdentityDetails &details) { QString comment; +QString nickname ; -QString nickname = details.mNickname.empty()?tr("[Unknown]"):QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE) ; + bool banned = rsReputations->isIdentityBanned(details.mId) ; + + if(details.mNickname.empty()) + nickname = tr("[Unknown]") ; + else if(banned) + nickname = tr("[Banned]") ; + else + nickname = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE) ; + comment = QString("%1:%2
    %3:%4").arg(QApplication::translate("GxsIdDetails", "Identity name"), nickname, QApplication::translate("GxsIdDetails", "Identity Id"), @@ -903,7 +920,8 @@ QString nickname = details.mNickname.empty()?tr("[Unknown]"):QString::fromUtf8(d { /* look up real name */ std::string authorName = rsPeers->getGPGName(details.mPgpId); - comment += QString("%1 [%2]").arg(QString::fromUtf8(authorName.c_str()), QString::fromStdString(details.mPgpId.toStdString())); + + comment += QString("%1 [%2]").arg(QString::fromUtf8(authorName.c_str()), QString::fromStdString(details.mPgpId.toStdString())); } else comment += QApplication::translate("GxsIdDetails", "unknown Key"); @@ -918,6 +936,13 @@ void GxsIdDetails::getIcons(const RsIdentityDetails &details, QList &icon { QPixmap pix ; + if(rsReputations->isIdentityBanned(details.mId)) + { + icons.clear() ; + icons.push_back(QIcon(IMAGE_BANNED)) ; + return ; + } + if(icon_types & ICON_TYPE_AVATAR) { if(details.mAvatar.mSize == 0 || !pix.loadFromData(details.mAvatar.mData, details.mAvatar.mSize, "PNG")) diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.h b/retroshare-gui/src/gui/gxs/GxsIdDetails.h index 06747e71e..3c9259ff3 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.h +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.h @@ -39,7 +39,8 @@ enum GxsIdDetailsType GXS_ID_DETAILS_TYPE_EMPTY, GXS_ID_DETAILS_TYPE_LOADING, GXS_ID_DETAILS_TYPE_DONE, - GXS_ID_DETAILS_TYPE_FAILED + GXS_ID_DETAILS_TYPE_FAILED, + GXS_ID_DETAILS_TYPE_BANNED }; typedef void (*GxsIdDetailsCallbackFunction)(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &data); @@ -49,10 +50,11 @@ class GxsIdDetails : public QObject Q_OBJECT public: - static const int ICON_TYPE_AVATAR = 0x0001 ; - static const int ICON_TYPE_PGP = 0x0002 ; - static const int ICON_TYPE_RECOGN = 0x0004 ; - static const int ICON_TYPE_ALL = 0x0007 ; + static const int ICON_TYPE_AVATAR = 0x0001 ; + static const int ICON_TYPE_PGP = 0x0002 ; + static const int ICON_TYPE_RECOGN = 0x0004 ; + static const int ICON_TYPE_ALL = 0x0007 ; + static const int ICON_TYPE_REDACTED= 0x0008 ; GxsIdDetails(); virtual ~GxsIdDetails(); diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp index 56c225d6b..60b0849ed 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp @@ -25,6 +25,9 @@ #include "GxsIdTreeWidgetItem.h" #include "GxsIdDetails.h" #include "util/HandleRichText.h" +#include "retroshare/rsreputations.h" + +#define BANNED_IMAGE ":/icons/yellow_biohazard64.png" /** Constructor */ GxsIdRSTreeWidgetItem::GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, uint32_t icon_mask,QTreeWidget *parent) @@ -71,6 +74,10 @@ static void fillGxsIdRSTreeWidgetItemCallback(GxsIdDetailsType type, const RsIde GxsIdDetails::getIcons(details, icons, item->iconTypeMask()); item->processResult(true); break; + + case GXS_ID_DETAILS_TYPE_BANNED: + icons.push_back(QIcon("BANNED_IMAGE")) ; + break ; } int column = item->idColumn(); @@ -81,7 +88,7 @@ static void fillGxsIdRSTreeWidgetItemCallback(GxsIdDetailsType type, const RsIde QPixmap combinedPixmap; if (!icons.empty()) { - GxsIdDetails::GenerateCombinedPixmap(combinedPixmap, icons, QFontMetricsF(item->font(item->idColumn())).height()*1.1); + GxsIdDetails::GenerateCombinedPixmap(combinedPixmap, icons, QFontMetricsF(item->font(item->idColumn())).height()*1.4); } item->setData(column, Qt::DecorationRole, combinedPixmap); item->setAvatar(details.mAvatar); @@ -139,28 +146,30 @@ void GxsIdRSTreeWidgetItem::setAvatar(const RsGxsImage &avatar) QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const { - if (column == idColumn()) { - switch (role) { - case Qt::ToolTipRole: - { - QString t = RSTreeWidgetItem::data(column, role).toString(); + if (column == idColumn()) + { + if (role == Qt::ToolTipRole) + { + QString t = RSTreeWidgetItem::data(column, role).toString(); + QImage pix; - QImage pix; - if (mAvatar.mSize == 0 || !pix.loadFromData(mAvatar.mData, mAvatar.mSize, "PNG")) { - pix = GxsIdDetails::makeDefaultIcon(mId); - } + if(mId.isNull()) + return RSTreeWidgetItem::data(column, role); + else if(rsReputations->isIdentityBanned(mId)) + pix = QImage(BANNED_IMAGE) ; + else if (mAvatar.mSize == 0 || !pix.loadFromData(mAvatar.mData, mAvatar.mSize, "PNG")) + pix = GxsIdDetails::makeDefaultIcon(mId); - int S = QFontMetricsF(font(column)).height(); + int S = QFontMetricsF(font(column)).height(); - QString embeddedImage; - if (RsHtml::makeEmbeddedImage(pix.scaled(QSize(4*S,4*S), Qt::KeepAspectRatio, Qt::SmoothTransformation), embeddedImage, 8*S * 8*S)) { - t = "
    " + embeddedImage + "" + t + "
    "; - } + QString embeddedImage; + if (RsHtml::makeEmbeddedImage(pix.scaled(QSize(4*S,4*S), Qt::KeepAspectRatio, Qt::SmoothTransformation), embeddedImage, 8*S * 8*S)) { + t = "
    " + embeddedImage + "" + t + "
    "; + } - return t; - } - } - } + return t; + } + } - return RSTreeWidgetItem::data(column, role); + return RSTreeWidgetItem::data(column, role); } diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp index d9e83111a..a3af87db4 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp @@ -121,7 +121,9 @@ void CreateGxsForumMsg::newMsg() mForumMetaLoaded = false; /* fill in the available OwnIds for signing */ - ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId()); + std::cerr << "Initing ID chooser. Sign flags = " << std::hex << mForumMeta.mSignFlags << std::dec << std::endl; + + ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId()); if (mForumId.isNull()) { mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, false); @@ -203,6 +205,13 @@ void CreateGxsForumMsg::loadFormInformation() std::cerr << "CreateGxsForumMsg::loadMsgInformation() Data Available!"; std::cerr << std::endl; + std::cerr << "CreateGxsForumMsg::loadMsgInformation() using signFlags=" << std::hex << mForumMeta.mSignFlags << std::dec << std::endl; + + if(mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) + ui.idChooser->setFlags(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NON_ANONYMOUS) ; + else + ui.idChooser->setFlags(IDCHOOSER_ID_REQUIRED) ; + QString name = QString::fromUtf8(mForumMeta.mGroupName.c_str()); QString subj; if (!mParentId.isNull()) @@ -251,7 +260,7 @@ void CreateGxsForumMsg::loadFormInformation() ui.signBox->setEnabled(true); } - ui.forumMessage->setText(""); + //ui.forumMessage->setText(""); } void CreateGxsForumMsg::createMsg() @@ -497,3 +506,8 @@ void CreateGxsForumMsg::loadRequest(const TokenQueue *queue, const TokenRequest } } } + +void CreateGxsForumMsg::insertPastedText(QString msg) +{ + ui.forumMessage->append(msg); +} diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h index 2447e02ba..cde7f4d77 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h @@ -40,6 +40,7 @@ public: void newMsg(); /* cleanup */ virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); +void insertPastedText(QString msg) ; private slots: void fileHashingFinished(QList hashedFiles); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp index 41f138e20..433f354c9 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp @@ -33,6 +33,7 @@ const uint32_t ForumCreateEnabledFlags = ( GXS_GROUP_FLAGS_DISTRIBUTION | // GXS_GROUP_FLAGS_PUBLISHSIGN | GXS_GROUP_FLAGS_SHAREKEYS | + GXS_GROUP_FLAGS_ANTI_SPAM | // GXS_GROUP_FLAGS_PERSONALSIGN | // GXS_GROUP_FLAGS_COMMENTS | 0); @@ -46,7 +47,7 @@ const uint32_t ForumCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC //GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | //GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED | - //GXS_GROUP_DEFAULTS_PERSONAL_GPG | + //GXS_GROUP_DEFAULTS_PERSONAL_PGP | GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | //GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index e51527860..12c207384 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -41,6 +41,8 @@ #include "util/QtVersion.h" #include +#include +#include #include // These should be in retroshare/ folder. #include "retroshare/rsgxsflags.h" @@ -57,6 +59,7 @@ #define IMAGE_DOWNLOAD ":/images/start.png" #define IMAGE_DOWNLOADALL ":/images/startall.png" #define IMAGE_COPYLINK ":/images/copyrslink.png" +#define IMAGE_BIOHAZARD ":/icons/yellow_biohazard64.png" #define VIEW_LAST_POST 0 #define VIEW_THREADED 1 @@ -94,6 +97,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget mTokenTypeInsertThreads = nextTokenType(); mTokenTypeMessageData = nextTokenType(); mTokenTypeReplyMessage = nextTokenType(); + mTokenTypeReplyForumMessage = nextTokenType(); setUpdateWhenInvisible(true); @@ -134,7 +138,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget ui->subscribeToolButton->hide() ; connect(ui->subscribeToolButton, SIGNAL(subscribe(bool)), this, SLOT(subscribeGroup(bool))); - connect(ui->newmessageButton, SIGNAL(clicked()), this, SLOT(createmessage())); + connect(ui->newmessageButton, SIGNAL(clicked()), this, SLOT(replytoforummessage())); connect(ui->newthreadButton, SIGNAL(clicked()), this, SLOT(createthread())); connect(ui->threadTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(changedThread())); @@ -401,11 +405,15 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) QMenu contextMnu(this); QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply"), &contextMnu); - connect(replyAct, SIGNAL(triggered()), this, SLOT(createmessage())); + connect(replyAct, SIGNAL(triggered()), this, SLOT(replytoforummessage())); QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply with private message"), &contextMnu); connect(replyauthorAct, SIGNAL(triggered()), this, SLOT(replytomessage())); + QAction *flagasbadAct = new QAction(QIcon(IMAGE_BIOHAZARD), tr("Ban this author"), &contextMnu); + flagasbadAct->setToolTip(tr("This will block/hide messages from this person, and notify neighbor nodes.")) ; + connect(flagasbadAct, SIGNAL(triggered()), this, SLOT(flagpersonasbad())); + QAction *newthreadAct = new QAction(QIcon(IMAGE_MESSAGE), tr("Start New Thread"), &contextMnu); newthreadAct->setEnabled (IS_GROUP_SUBSCRIBED(mSubscribeFlags)); connect(newthreadAct , SIGNAL(triggered()), this, SLOT(createthread())); @@ -484,6 +492,8 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) contextMnu.addAction(expandAll); contextMnu.addAction(collapseAll); + contextMnu.addSeparator(); + contextMnu.addAction(flagasbadAct); contextMnu.addSeparator(); contextMnu.addAction(replyauthorAct); @@ -539,6 +549,17 @@ void GxsForumThreadWidget::changedThread() mThreadId = RsGxsMessageId(item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString()); } + // Show info about who passed on this message. + if(mForumGroup.mMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) + { + RsPeerId providerId ; + std::string msgId = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); + RsGxsMessageId mid(msgId) ; + + if(rsGRouter->getTrackingInfo(mid,providerId) && !providerId.isNull() ) + item->setToolTip(COLUMN_THREAD_TITLE,tr("This message was obtained from %1").arg(QString::fromUtf8(rsPeers->getPeerName(providerId).c_str()))); + } + if (mFillThread) { return; } @@ -725,6 +746,9 @@ void GxsForumThreadWidget::insertGroupData() case GXS_ID_DETAILS_TYPE_LOADING: author = GxsIdDetails::getLoadingText(details.mId); break; + case GXS_ID_DETAILS_TYPE_BANNED: + author = tr("[Banned]") ; + break ; case GXS_ID_DETAILS_TYPE_DONE: author = GxsIdDetails::getName(details); break; @@ -733,12 +757,26 @@ void GxsForumThreadWidget::insertGroupData() const RsGxsForumGroup& group = tw->mForumGroup; tw->mSubscribeFlags = group.mMeta.mSubscribeFlags; + tw->mSignFlags = group.mMeta.mSignFlags; tw->ui->forumName->setText(QString::fromUtf8(group.mMeta.mGroupName.c_str())); + QString anti_spam_features1 ; + if(IS_GROUP_PGP_AUTHED(tw->mSignFlags)) anti_spam_features1 = tr("Anonymous IDs reputation threshold set to 0.4"); + + QString anti_spam_features2 ; + if(IS_GROUP_MESSAGE_TRACKING(tw->mSignFlags)) anti_spam_features2 = tr("Message routing info kept for 10 days"); + tw->mForumDescription = QString("%1: \t%2
    ").arg(tr("Forum name"), QString::fromUtf8( group.mMeta.mGroupName.c_str())); tw->mForumDescription += QString("%1: \t%2
    ").arg(tr("Subscribers")).arg(group.mMeta.mPop); tw->mForumDescription += QString("%1: \t%2
    ").arg(tr("Posts (at neighbor nodes)")).arg(group.mMeta.mVisibleMsgCount); tw->mForumDescription += QString("%1: \t%2
    ").arg(tr("Author"), author); + + if(!anti_spam_features1.isNull()) + tw->mForumDescription += QString("%1: \t%2
    ").arg(tr("Anti-spam")).arg(anti_spam_features1); + + if(!anti_spam_features2.isNull()) + tw->mForumDescription += QString("%1: \t%2
    ").arg(tr("Anti-spam")).arg(anti_spam_features2); + tw->mForumDescription += QString("%1:

    %2").arg(tr("Description"), QString::fromUtf8(group.mDescription.c_str())); tw->ui->subscribeToolButton->setSubscribed(IS_GROUP_SUBSCRIBED(tw->mSubscribeFlags)); @@ -886,12 +924,21 @@ void GxsForumThreadWidget::fillThreadStatus(QString text) QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForumMsg &msg, bool useChildTS, uint32_t filterColumn) { - GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_ALL); + // Early check for a message that should be hidden because its author + // is flagged with a bad reputation + + + bool redacted = rsReputations->isIdentityBanned(msg.mMeta.mAuthorId) ; + + GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_ALL || (redacted?(GxsIdDetails::ICON_TYPE_REDACTED):0)); item->moveToThread(ui->threadTreeWidget->thread()); QString text; - item->setText(COLUMN_THREAD_TITLE, QString::fromUtf8(msg.mMeta.mMsgName.c_str())); + if(redacted) + item->setText(COLUMN_THREAD_TITLE, tr("[ ... Redacted message ... ]")); + else + item->setText(COLUMN_THREAD_TITLE, QString::fromUtf8(msg.mMeta.mMsgName.c_str())); QDateTime qtime; QString sort; @@ -916,6 +963,7 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum // Set later with GxsIdRSTreeWidgetItem::setId item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_AUTHOR, QString::fromStdString(msg.mMeta.mAuthorId.toStdString())); + //#TODO #if 0 text = QString::fromUtf8(authorName.c_str()); @@ -961,18 +1009,20 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum } #endif item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, msg.mMeta.mMsgStatus); - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, false); - + return item; } QTreeWidgetItem *GxsForumThreadWidget::generateMissingItem(const RsGxsMessageId &msgId) { GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_ALL); + item->setText(COLUMN_THREAD_TITLE, tr("[ ... Missing Message ... ]")); item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID, QString::fromStdString(msgId.toStdString())); item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, true); + + item->setId(RsGxsId(), COLUMN_THREAD_AUTHOR, false); // fixed up columnId() return item; } @@ -1301,6 +1351,8 @@ void GxsForumThreadWidget::insertMessageData(const RsGxsForumMsg &msg) return; } + bool redacted = rsReputations->isIdentityBanned(msg.mMeta.mAuthorId) ; + mStateHelper->setActive(mTokenTypeMessageData, true); QTreeWidgetItem *item = ui->threadTreeWidget->currentItem(); @@ -1334,9 +1386,20 @@ void GxsForumThreadWidget::insertMessageData(const RsGxsForumMsg &msg) ui->by_text_label->show() ; ui->by_label->show() ; - QString extraTxt = RsHtml().formatText(ui->postText->document(), QString::fromUtf8(msg.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); - + if(redacted) + { + QString extraTxt = tr("

    The author of this message (with ID %1) is banned.").arg(QString::fromStdString(msg.mMeta.mAuthorId.toStdString())) ; + extraTxt += tr("

    • Messages from this author are not forwarded.
    • ") ; + extraTxt += tr("
    • Messages from this author are replaced by this text.
    ") ; + extraTxt += tr("

    You can force the visibility and forwarding of messages by setting a different opinion for that Id in People's tab.

    ") ; + ui->postText->setHtml(extraTxt); + } + else + { + QString extraTxt = RsHtml().formatText(ui->postText->document(), QString::fromUtf8(msg.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); + ui->postText->setHtml(extraTxt); + } //ui->threadTitle->setText(QString::fromUtf8(msg.mMeta.mMsgName.c_str())); } @@ -1685,6 +1748,34 @@ static QString buildReplyHeader(const RsMsgMetaData &meta) return header; } +void GxsForumThreadWidget::flagpersonasbad() +{ + // no need to use the token system for that, since we just need to find out the author's name, which is in the item. + + if (groupId().isNull() || mThreadId.isNull()) { + QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message")); + return; + } + + // Get Message ... then complete replyMessageData(). + RsGxsGrpMsgIdPair postId = std::make_pair(groupId(), mThreadId); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumThreadWidget::requestMsgData_BanAuthor(" << postId.first << "," << postId.second << ")"; + std::cerr << std::endl; +#endif + + GxsMsgReq msgIds; + std::vector &vect = msgIds[postId.first]; + vect.push_back(postId.second); + + uint32_t token; + mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeBanAuthor); +} + void GxsForumThreadWidget::replytomessage() { if (groupId().isNull() || mThreadId.isNull()) { @@ -1697,6 +1788,18 @@ void GxsForumThreadWidget::replytomessage() requestMsgData_ReplyMessage(postId); } +void GxsForumThreadWidget::replytoforummessage() +{ + if (groupId().isNull() || mThreadId.isNull()) { + QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message")); + return; + } + + // Get Message ... then complete replyMessageData(). + RsGxsGrpMsgIdPair postId = std::make_pair(groupId(), mThreadId); + requestMsgData_ReplyForumMessage(postId); +} + void GxsForumThreadWidget::replyMessageData(const RsGxsForumMsg &msg) { if ((msg.mMeta.mGroupId != groupId()) || (msg.mMeta.mMsgId != mThreadId)) @@ -1725,6 +1828,34 @@ void GxsForumThreadWidget::replyMessageData(const RsGxsForumMsg &msg) } } +void GxsForumThreadWidget::replyForumMessageData(const RsGxsForumMsg &msg) +{ + if ((msg.mMeta.mGroupId != groupId()) || (msg.mMeta.mMsgId != mThreadId)) + { + std::cerr << "GxsForumThreadWidget::replyMessageData() ERROR Message Ids have changed!"; + std::cerr << std::endl; + return; + } + + if (!msg.mMeta.mAuthorId.isNull()) + { + CreateGxsForumMsg *cfm = new CreateGxsForumMsg(groupId(), mThreadId); + QTextDocument doc ; +// doc.setHtml(QString::fromUtf8(msg.mMsg.c_str()) ); +// std::string cited_text(doc.toPlainText().toStdString()) ; + RsHtml::makeQuotedText(ui->postText); + + cfm->insertPastedText(RsHtml::makeQuotedText(ui->postText)) ; + cfm->show(); + + /* window will destroy itself! */ + } + else + { + QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to an Anonymous Author")); + } +} + void GxsForumThreadWidget::changedViewBox() { if (mInProcessSettings) { @@ -1800,6 +1931,7 @@ bool GxsForumThreadWidget::filterItem(QTreeWidgetItem *item, const QString &text void GxsForumThreadWidget::requestGroupData() { mSubscribeFlags = 0; + mSignFlags = 0; mForumDescription.clear(); mTokenQueue->cancelActiveRequestTokens(mTokenTypeGroupData); @@ -1940,6 +2072,24 @@ void GxsForumThreadWidget::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair & mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeReplyMessage); } +void GxsForumThreadWidget::requestMsgData_ReplyForumMessage(const RsGxsGrpMsgIdPair &msgId) +{ + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumThreadWidget::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")"; + std::cerr << std::endl; +#endif + + GxsMsgReq msgIds; + std::vector &vect = msgIds[msgId.first]; + vect.push_back(msgId.second); + + uint32_t token; + mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeReplyForumMessage); +} + void GxsForumThreadWidget::loadMsgData_ReplyMessage(const uint32_t &token) { #ifdef DEBUG_FORUMS @@ -1956,7 +2106,6 @@ void GxsForumThreadWidget::loadMsgData_ReplyMessage(const uint32_t &token) std::cerr << std::endl; return; } - replyMessageData(msgs[0]); } else @@ -1966,6 +2115,63 @@ void GxsForumThreadWidget::loadMsgData_ReplyMessage(const uint32_t &token) } } +void GxsForumThreadWidget::loadMsgData_ReplyForumMessage(const uint32_t &token) +{ +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumThreadWidget::loadMsgData_ReplyMessage()"; + std::cerr << std::endl; +#endif + + std::vector msgs; + if (rsGxsForums->getMsgData(token, msgs)) + { + if (msgs.size() != 1) + { + std::cerr << "GxsForumThreadWidget::loadMsgData_ReplyMessage() ERROR Wrong number of answers"; + std::cerr << std::endl; + return; + } + + replyForumMessageData(msgs[0]); + } + else + { + std::cerr << "GxsForumThreadWidget::loadMsgData_ReplyMessage() ERROR Missing Message Data..."; + std::cerr << std::endl; + } +} + +void GxsForumThreadWidget::loadMsgData_BanAuthor(const uint32_t &token) +{ +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumThreadWidget::loadMsgData_BanAuthor()"; + std::cerr << std::endl; +#endif + + std::vector msgs; + if (rsGxsForums->getMsgData(token, msgs)) + { + if (msgs.size() != 1) + { + std::cerr << "GxsForumThreadWidget::loadMsgData_ReplyMessage() ERROR Wrong number of answers"; + std::cerr << std::endl; + return; + } + + std::cerr << " banning author id " << msgs[0].mMeta.mAuthorId << std::endl; + rsReputations->setOwnOpinion(msgs[0].mMeta.mAuthorId,RsReputations::OPINION_NEGATIVE) ; + } + else + { + std::cerr << "GxsForumThreadWidget::loadMsgData_ReplyMessage() ERROR Missing Message Data..."; + std::cerr << std::endl; + } + updateDisplay(true) ; + + // we should also update the icons so that they changed to the icon for banned peers. + + std::cerr << __PRETTY_FUNCTION__ << ": need to implement the update of GxsTreeWidgetItems icons too." << std::endl; +} /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ @@ -1993,6 +2199,16 @@ void GxsForumThreadWidget::loadRequest(const TokenQueue *queue, const TokenReque loadMsgData_ReplyMessage(req.mToken); return; } + + if (req.mUserType == mTokenTypeReplyForumMessage) { + loadMsgData_ReplyForumMessage(req.mToken); + return; + } + + if (req.mUserType == mTokenTypeBanAuthor) { + loadMsgData_BanAuthor(req.mToken); + return; + } } GxsMessageFrameWidget::loadRequest(queue, req); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h index 311024f07..4e6afbb45 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h @@ -66,7 +66,7 @@ protected: /* GxsMessageFrameWidget */ virtual void setAllMessagesReadDo(bool read, uint32_t &token); - + private slots: /** Create the context popup menu and it's submenus */ void threadListCustomPopupMenu(QPoint point); @@ -75,7 +75,13 @@ private slots: void clickedThread (QTreeWidgetItem *item, int column); void replytomessage(); + void replytoforummessage(); + void replyMessageData(const RsGxsForumMsg &msg); + void replyForumMessageData(const RsGxsForumMsg &msg); + + + //void print(); //void printpreview(); @@ -101,6 +107,7 @@ private slots: void downloadAllFiles(); void changedViewBox(); + void flagpersonasbad(); void filterColumnChanged(int column); void filterItems(const QString &text); @@ -140,6 +147,10 @@ private: void loadMessageData(const uint32_t &token); void requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId); void loadMsgData_ReplyMessage(const uint32_t &token); + + void requestMsgData_ReplyForumMessage(const RsGxsGrpMsgIdPair &msgId); + void loadMsgData_ReplyForumMessage(const uint32_t &token); + void loadMsgData_BanAuthor(const uint32_t &token); private: RsGxsGroupId mLastForumID; @@ -147,6 +158,7 @@ private: RsGxsForumGroup mForumGroup; QString mForumDescription; int mSubscribeFlags; + int mSignFlags; bool mInProcessSettings; bool mInMsgAsReadUnread; int mLastViewType; @@ -159,6 +171,8 @@ private: uint32_t mTokenTypeInsertThreads; uint32_t mTokenTypeMessageData; uint32_t mTokenTypeReplyMessage; + uint32_t mTokenTypeReplyForumMessage; + uint32_t mTokenTypeBanAuthor; /* Color definitions (for standard see qss.default) */ QColor mTextColorRead; @@ -170,7 +184,7 @@ private: RsGxsMessageId mNavigatePendingMsgId; QList mIgnoredMsgId; - Ui::GxsForumThreadWidget *ui; + Ui::GxsForumThreadWidget *ui; }; #endif // GXSFORUMTHREADWIDGET_H diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp index 6fefb0c34..880ed6ba7 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp @@ -178,8 +178,9 @@ void GxsForumsDialog::groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, groupItemInfo.description = descriptionIt.value(); } - if (IS_GROUP_ADMIN(groupInfo.mSubscribeFlags)) { - groupItemInfo.icon = QIcon(":images/konv_message2.png"); - } + if (IS_GROUP_ADMIN(groupInfo.mSubscribeFlags)) + groupItemInfo.icon = QIcon(":images/konv_message2.png"); + else if ((IS_GROUP_PGP_AUTHED(groupInfo.mSignFlags)) || (IS_GROUP_MESSAGE_TRACKING(groupInfo.mSignFlags)) ) + groupItemInfo.icon = QIcon(":images/konv_message3.png"); } diff --git a/retroshare-gui/src/gui/help/content/en/addfriends.html b/retroshare-gui/src/gui/help/content/en/addfriends.html index bb78dc4ad..8d2f749e1 100644 --- a/retroshare-gui/src/gui/help/content/en/addfriends.html +++ b/retroshare-gui/src/gui/help/content/en/addfriends.html @@ -32,7 +32,7 @@

    -When your friends send you a their invitations, Click to open the Add Friends window. +When your friends send you their invitations, click to open the Add Friends window. Cut and Paste your Friend's "ID Certificates" into the window and add them as friends.

    diff --git a/retroshare-gui/src/gui/help/content/en/peerdetails.html b/retroshare-gui/src/gui/help/content/en/peerdetails.html index 2dee340cf..6fe745bca 100644 --- a/retroshare-gui/src/gui/help/content/en/peerdetails.html +++ b/retroshare-gui/src/gui/help/content/en/peerdetails.html @@ -35,9 +35,9 @@ Trust settings and Signing

    Trust Settings

    -The trust settings refers to the gnupg web of trust mecanism.
    +The trust settings refers to the GnuPG web of trust mechanism.
    This trust means how you trust your friends when he is signing other PGP keys.
    -If you set your trust to "full", it means that when your friend sign a key, this key will be shown as validated by the web of trust in the network view.

    +If you set your trust to "full", it means that when your friend signs a key, this key will be shown as validated by the web of trust in the network view.

    @@ -45,8 +45,8 @@ If you set your trust to "full", it means that when your friend sign a key, this

    You should sign a key when you are sure that the person who claims ownership on this key is the real owner of the key.
    -When you are sure that the name of the key owner is the real name of the emmitter of this key, you may sign it to confirm it.
    -Signing the key will be public unless public discovery is not setted. This means you friends can check if you did sign someone's key. +When you are sure that the name of the key owner is the real name of the emitter of this key, you may sign it to confirm it.
    +Signing the key will be public unless public discovery is not set. This means your friends can check if you did sign someone's key.

    diff --git a/retroshare-gui/src/gui/icons.qrc b/retroshare-gui/src/gui/icons.qrc index 8840c6087..8967f1670 100644 --- a/retroshare-gui/src/gui/icons.qrc +++ b/retroshare-gui/src/gui/icons.qrc @@ -7,10 +7,10 @@ icons/blank_green_128.png icons/browsable_blue_128.png icons/browsable_green_128.png - icons/bullet_green_64.png - icons/bullet_grey_64.png - icons/bullet_red_64.png - icons/bullet_yellow_64.png + icons/bullet_green_128.png + icons/bullet_grey_128.png + icons/bullet_red_128.png + icons/bullet_yellow_128.png icons/channels_128.png icons/channels_red_128.png icons/chat_128.png @@ -60,5 +60,14 @@ icons/user-busy_64.png icons/user-offline_64.png icons/user-online_64.png + icons/yellow_biohazard64.png + icons/gmail.png + icons/yahoo.png + icons/outlook.png + icons/aol.png + icons/yandex.png + icons/tor-on.png + icons/tor-logo.png + icons/tor-off.png diff --git a/retroshare-gui/src/gui/icons/aol.png b/retroshare-gui/src/gui/icons/aol.png new file mode 100644 index 000000000..2f1422842 Binary files /dev/null and b/retroshare-gui/src/gui/icons/aol.png differ diff --git a/retroshare-gui/src/gui/icons/bullet_green_128.png b/retroshare-gui/src/gui/icons/bullet_green_128.png new file mode 100644 index 000000000..72427d3cf Binary files /dev/null and b/retroshare-gui/src/gui/icons/bullet_green_128.png differ diff --git a/retroshare-gui/src/gui/icons/bullet_green_64.png b/retroshare-gui/src/gui/icons/bullet_green_64.png deleted file mode 100644 index f5f95da4a..000000000 Binary files a/retroshare-gui/src/gui/icons/bullet_green_64.png and /dev/null differ diff --git a/retroshare-gui/src/gui/icons/bullet_grey_128.png b/retroshare-gui/src/gui/icons/bullet_grey_128.png new file mode 100644 index 000000000..a1c3dc798 Binary files /dev/null and b/retroshare-gui/src/gui/icons/bullet_grey_128.png differ diff --git a/retroshare-gui/src/gui/icons/bullet_grey_64.png b/retroshare-gui/src/gui/icons/bullet_grey_64.png deleted file mode 100644 index 3b9f2c65e..000000000 Binary files a/retroshare-gui/src/gui/icons/bullet_grey_64.png and /dev/null differ diff --git a/retroshare-gui/src/gui/icons/bullet_red_128.png b/retroshare-gui/src/gui/icons/bullet_red_128.png new file mode 100644 index 000000000..507f4851e Binary files /dev/null and b/retroshare-gui/src/gui/icons/bullet_red_128.png differ diff --git a/retroshare-gui/src/gui/icons/bullet_red_64.png b/retroshare-gui/src/gui/icons/bullet_red_64.png deleted file mode 100644 index 2b18d7ff0..000000000 Binary files a/retroshare-gui/src/gui/icons/bullet_red_64.png and /dev/null differ diff --git a/retroshare-gui/src/gui/icons/bullet_yellow_128.png b/retroshare-gui/src/gui/icons/bullet_yellow_128.png new file mode 100644 index 000000000..bc4270683 Binary files /dev/null and b/retroshare-gui/src/gui/icons/bullet_yellow_128.png differ diff --git a/retroshare-gui/src/gui/icons/bullet_yellow_64.png b/retroshare-gui/src/gui/icons/bullet_yellow_64.png deleted file mode 100644 index 52a6e41e2..000000000 Binary files a/retroshare-gui/src/gui/icons/bullet_yellow_64.png and /dev/null differ diff --git a/retroshare-gui/src/gui/icons/gmail.png b/retroshare-gui/src/gui/icons/gmail.png new file mode 100644 index 000000000..b17b672bd Binary files /dev/null and b/retroshare-gui/src/gui/icons/gmail.png differ diff --git a/retroshare-gui/src/gui/icons/outlook.png b/retroshare-gui/src/gui/icons/outlook.png new file mode 100644 index 000000000..ba8c5ad06 Binary files /dev/null and b/retroshare-gui/src/gui/icons/outlook.png differ diff --git a/retroshare-gui/src/gui/icons/tor-logo.png b/retroshare-gui/src/gui/icons/tor-logo.png new file mode 100644 index 000000000..5d52e8433 Binary files /dev/null and b/retroshare-gui/src/gui/icons/tor-logo.png differ diff --git a/retroshare-gui/src/gui/icons/tor-off.png b/retroshare-gui/src/gui/icons/tor-off.png new file mode 100644 index 000000000..93bc0529c Binary files /dev/null and b/retroshare-gui/src/gui/icons/tor-off.png differ diff --git a/retroshare-gui/src/gui/icons/tor-on.png b/retroshare-gui/src/gui/icons/tor-on.png new file mode 100644 index 000000000..cb5018dd8 Binary files /dev/null and b/retroshare-gui/src/gui/icons/tor-on.png differ diff --git a/retroshare-gui/src/gui/icons/tor-starting.png b/retroshare-gui/src/gui/icons/tor-starting.png new file mode 100644 index 000000000..f9a97fd2a Binary files /dev/null and b/retroshare-gui/src/gui/icons/tor-starting.png differ diff --git a/retroshare-gui/src/gui/icons/tor-stopping.png b/retroshare-gui/src/gui/icons/tor-stopping.png new file mode 100644 index 000000000..f7a68c2a9 Binary files /dev/null and b/retroshare-gui/src/gui/icons/tor-stopping.png differ diff --git a/retroshare-gui/src/gui/icons/yahoo.png b/retroshare-gui/src/gui/icons/yahoo.png new file mode 100644 index 000000000..37e31a893 Binary files /dev/null and b/retroshare-gui/src/gui/icons/yahoo.png differ diff --git a/retroshare-gui/src/gui/icons/yandex.png b/retroshare-gui/src/gui/icons/yandex.png new file mode 100644 index 000000000..13c6b5f72 Binary files /dev/null and b/retroshare-gui/src/gui/icons/yandex.png differ diff --git a/retroshare-gui/src/gui/icons/yellow_biohazard64.png b/retroshare-gui/src/gui/icons/yellow_biohazard64.png new file mode 100644 index 000000000..edb6fb3f2 Binary files /dev/null and b/retroshare-gui/src/gui/icons/yellow_biohazard64.png differ diff --git a/retroshare-gui/src/gui/images.qrc b/retroshare-gui/src/gui/images.qrc index de22823e7..2d26956be 100644 --- a/retroshare-gui/src/gui/images.qrc +++ b/retroshare-gui/src/gui/images.qrc @@ -316,6 +316,7 @@ images/konversation16.png images/konversation128.png images/konv_message2.png + images/konv_message3.png images/konv_message64.png images/konversation64.png images/forums_new.png diff --git a/retroshare-gui/src/gui/images/konv_message3.png b/retroshare-gui/src/gui/images/konv_message3.png new file mode 100644 index 000000000..40280bb50 Binary files /dev/null and b/retroshare-gui/src/gui/images/konv_message3.png differ diff --git a/retroshare-gui/src/gui/images/white-bubble-64.png b/retroshare-gui/src/gui/images/white-bubble-64.png index bb572da6a..f8a6ca27f 100644 Binary files a/retroshare-gui/src/gui/images/white-bubble-64.png and b/retroshare-gui/src/gui/images/white-bubble-64.png differ diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.cpp b/retroshare-gui/src/gui/msgs/MessageComposer.cpp index 16c58a20c..3b771aa3f 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.cpp +++ b/retroshare-gui/src/gui/msgs/MessageComposer.cpp @@ -136,8 +136,8 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) m_completer = NULL; ui.distantFrame->hide(); - ui.respond_to_CB->setEnabled(false) ; - ui.fromLabel->setEnabled(false) ; + ui.respond_to_CB->hide(); + ui.fromLabel->hide(); Settings->loadWidgetInformation(this); @@ -389,15 +389,15 @@ void MessageComposer::updateCells(int,int) } if(has_gxs) { - ui.respond_to_CB->setEnabled(true) ; + ui.respond_to_CB->show(); ui.distantFrame->show(); - ui.fromLabel->setEnabled(true); + ui.fromLabel->show(); } else { - ui.respond_to_CB->setEnabled(false) ; + ui.respond_to_CB->hide(); ui.distantFrame->hide() ; - ui.fromLabel->setEnabled(false); + ui.fromLabel->hide(); } } diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss index ed8272ee7..645fb9702 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss @@ -253,9 +253,9 @@ PopupChatWindow QToolBar#chattoolBar{ /* Messages */ -MessageComposer > QToolBar#toolBar { +MessageComposer QToolBar#toolBar { background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - + border: 0px; } MessagesDialog QFrame#folderFrame, MessagesDialog QFrame#quickViewFrame { diff --git a/retroshare-gui/src/gui/settings/AppearancePage.cpp b/retroshare-gui/src/gui/settings/AppearancePage.cpp index 5f16bdc45..0d431e996 100755 --- a/retroshare-gui/src/gui/settings/AppearancePage.cpp +++ b/retroshare-gui/src/gui/settings/AppearancePage.cpp @@ -45,6 +45,7 @@ AppearancePage::AppearancePage(QWidget * parent, Qt::WindowFlags flags) connect(ui.checkBoxHideSoundStatus, SIGNAL(toggled(bool)), pMainWindow->soundStatusInstance(), SLOT(setHidden(bool))); connect(ui.checkBoxHideToasterDisable, SIGNAL(toggled(bool)), pMainWindow->toasterDisableInstance(), SLOT(setHidden(bool))); connect(ui.checkBoxShowSystrayOnStatus, SIGNAL(toggled(bool)), pMainWindow->sysTrayStatusInstance(), SLOT(setVisible(bool))); + connect(ui.checkBoxDisableSysTrayToolTip, SIGNAL(toggled(bool)), pMainWindow, SLOT(toggleStatusToolTip(bool))); /* Populate combo boxes */ foreach (QString code, LanguageSupport::languageCodes()) { @@ -142,6 +143,8 @@ bool AppearancePage::save(QString &errmsg) Settings->setValueToGroup("StatusBar", "HideSound", QVariant(ui.checkBoxHideSoundStatus->isChecked())); Settings->setValueToGroup("StatusBar", "HideToaster", QVariant(ui.checkBoxHideToasterDisable->isChecked())); Settings->setValueToGroup("StatusBar", "ShowSysTrayOnStatusBar", QVariant(ui.checkBoxShowSystrayOnStatus->isChecked())); + Settings->setValueToGroup("StatusBar", "DisableSysTrayToolTip", QVariant(ui.checkBoxDisableSysTrayToolTip->isChecked())); + MainWindow::getInstance()->toggleStatusToolTip(ui.checkBoxDisableSysTrayToolTip->isChecked()); return true; } @@ -228,6 +231,7 @@ void AppearancePage::load() ui.checkBoxHideSoundStatus->setChecked(Settings->valueFromGroup("StatusBar", "HideSound", QVariant(false)).toBool()); ui.checkBoxHideToasterDisable->setChecked(Settings->valueFromGroup("StatusBar", "HideToaster", QVariant(false)).toBool()); ui.checkBoxShowSystrayOnStatus->setChecked(Settings->valueFromGroup("StatusBar", "ShowSysTrayOnStatusBar", QVariant(false)).toBool()); + ui.checkBoxDisableSysTrayToolTip->setChecked(Settings->valueFromGroup("StatusBar", "DisableSysTrayToolTip", QVariant(false)).toBool()); } diff --git a/retroshare-gui/src/gui/settings/AppearancePage.ui b/retroshare-gui/src/gui/settings/AppearancePage.ui index 027668dc2..95f3bf297 100755 --- a/retroshare-gui/src/gui/settings/AppearancePage.ui +++ b/retroshare-gui/src/gui/settings/AppearancePage.ui @@ -14,7 +14,16 @@ Qt::NoContextMenu - + + 6 + + + 6 + + + 6 + + 6 @@ -199,7 +208,16 @@ QFrame::Plain - + + 2 + + + 2 + + + 2 + + 2 @@ -212,7 +230,7 @@ - On List Item + On List Ite&m @@ -248,7 +266,16 @@ QFrame::Plain - + + 2 + + + 2 + + + 2 + + 2 @@ -461,6 +488,13 @@ + + + + Disable SysTray ToolTip + + + diff --git a/retroshare-gui/src/gui/settings/ChatPage.cpp b/retroshare-gui/src/gui/settings/ChatPage.cpp index d3619a014..bee6f0248 100644 --- a/retroshare-gui/src/gui/settings/ChatPage.cpp +++ b/retroshare-gui/src/gui/settings/ChatPage.cpp @@ -115,6 +115,7 @@ ChatPage::save(QString &/*errmsg*/) Settings->setValue("Emoteicons_GroupChat", ui.checkBox_emotegroupchat->isChecked()); Settings->setValue("EnableCustomFonts", ui.checkBox_enableCustomFonts->isChecked()); Settings->setValue("EnableCustomFontSize", ui.checkBox_enableCustomFontSize->isChecked()); + Settings->setValue("MinimumFontSize", ui.minimumFontSize->value()); Settings->setValue("EnableBold", ui.checkBox_enableBold->isChecked()); Settings->setValue("EnableItalics", ui.checkBox_enableItalics->isChecked()); Settings->setValue("MinimumContrast", ui.minimumContrast->value()); @@ -219,6 +220,7 @@ ChatPage::load() ui.checkBox_emotegroupchat->setChecked(Settings->value("Emoteicons_GroupChat", true).toBool()); ui.checkBox_enableCustomFonts->setChecked(Settings->value("EnableCustomFonts", true).toBool()); ui.checkBox_enableCustomFontSize->setChecked(Settings->value("EnableCustomFontSize", true).toBool()); + ui.minimumFontSize->setValue(Settings->value("MinimumFontSize", 10).toInt()); ui.checkBox_enableBold->setChecked(Settings->value("EnableBold", true).toBool()); ui.checkBox_enableItalics->setChecked(Settings->value("EnableItalics", true).toBool()); ui.minimumContrast->setValue(Settings->value("MinimumContrast", 4.5).toDouble()); diff --git a/retroshare-gui/src/gui/settings/ChatPage.ui b/retroshare-gui/src/gui/settings/ChatPage.ui index 43dadb5d2..1b3cfa544 100644 --- a/retroshare-gui/src/gui/settings/ChatPage.ui +++ b/retroshare-gui/src/gui/settings/ChatPage.ui @@ -75,6 +75,43 @@ + + + + 0 + + + + + Minimum font size + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 1 + + + 64 + + + + + diff --git a/retroshare-gui/src/gui/settings/PluginsPage.cpp b/retroshare-gui/src/gui/settings/PluginsPage.cpp index 33b7bd1ac..39bd39a4a 100644 --- a/retroshare-gui/src/gui/settings/PluginsPage.cpp +++ b/retroshare-gui/src/gui/settings/PluginsPage.cpp @@ -22,6 +22,7 @@ #include #include +#include #include "PluginsPage.h" #include "PluginItem.h" @@ -55,25 +56,32 @@ PluginsPage::PluginsPage(QWidget * parent, Qt::WindowFlags flags) rsPlugins->getPluginStatus(i,status,file_name,file_hash,svn_revision,error_string) ; QString status_string ; + QString short_status_string; switch(status) { - case PLUGIN_STATUS_REJECTED_HASH: status_string = tr("Hash rejected. Enable it manually and restart, if you need.") ; + case PLUGIN_STATUS_REJECTED_HASH: status_string = tr("Plugin disabled. Click the enable button and restart Retroshare") ; + short_status_string = tr("[disabled]"); break ; case PLUGIN_STATUS_MISSING_API: status_string = tr("No API number supplied. Please read plugin development manual.") ; + short_status_string = tr("[loading problem]"); break ; case PLUGIN_STATUS_MISSING_SVN: status_string = tr("No SVN number supplied. Please read plugin development manual.") ; + short_status_string = tr("[loading problem]"); break ; case PLUGIN_STATUS_DLOPEN_ERROR: status_string = tr("Loading error.") ; + short_status_string = tr("[loading problem]"); break ; case PLUGIN_STATUS_MISSING_SYMBOL:status_string = tr("Missing symbol. Wrong version?") ; + short_status_string = tr("[loading problem]"); break ; case PLUGIN_STATUS_NULL_PLUGIN: status_string = tr("No plugin object") ; + short_status_string = tr("[loading problem]"); break ; case PLUGIN_STATUS_LOADED: status_string = tr("Plugins is loaded.") ; @@ -84,9 +92,9 @@ PluginsPage::PluginsPage(QWidget * parent, Qt::WindowFlags flags) QIcon plugin_icon(":images/disabled_plugin_48.png") ; RsPlugin *plugin = rsPlugins->plugin(i) ; - QString pluginTitle = tr("Title unavailable") ; - QString pluginDescription = tr("Description unavailable") ; - QString pluginVersion = tr("Unknown version"); + QString pluginTitle = QFileInfo(QString::fromStdString(file_name)).fileName(); + QString pluginDescription = status_string; + QString pluginVersion = short_status_string; if(plugin!=NULL) { @@ -114,7 +122,7 @@ PluginsPage::PluginsPage(QWidget * parent, Qt::WindowFlags flags) if(plugin == NULL || plugin->qt_config_panel() == NULL) - item->_configure_PB->setEnabled(false) ; + item->_configure_PB->hide() ; if(plugin != NULL){ @@ -123,6 +131,7 @@ PluginsPage::PluginsPage(QWidget * parent, Qt::WindowFlags flags) }else{ item->enableButton->show(); item->disableButton->hide(); + item->_about_PB->hide(); } //if(rsPlugins->getAllowAllPlugins()) diff --git a/retroshare-gui/src/gui/settings/PluginsPage.ui b/retroshare-gui/src/gui/settings/PluginsPage.ui index edfb687d6..e357307ec 100644 --- a/retroshare-gui/src/gui/settings/PluginsPage.ui +++ b/retroshare-gui/src/gui/settings/PluginsPage.ui @@ -24,7 +24,7 @@ - Loaded plugins + Plugins diff --git a/retroshare-gui/src/gui/settings/ServerPage.cpp b/retroshare-gui/src/gui/settings/ServerPage.cpp index e44e275cc..45e317d84 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.cpp +++ b/retroshare-gui/src/gui/settings/ServerPage.cpp @@ -53,7 +53,7 @@ //#define SERVER_DEBUG 1 ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) - : ConfigPage(parent, flags), mIsHiddenNode(false) + : ConfigPage(parent, flags), mIsHiddenNode(false), mHiddenType(RS_HIDDEN_TYPE_NONE) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); @@ -61,7 +61,7 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) connect( ui.netModeComboBox, SIGNAL( activated ( int ) ), this, SLOT( toggleUPnP( ) ) ); connect( ui.allowIpDeterminationCB, SIGNAL( toggled( bool ) ), this, SLOT( toggleIpDetermination(bool) ) ); connect( ui.cleanKnownIPs_PB, SIGNAL( clicked( ) ), this, SLOT( clearKnownAddressList() ) ); - connect( ui.testIncomingTor_PB, SIGNAL( clicked( ) ), this, SLOT( updateTorInProxyIndicator() ) ); + connect( ui.testIncoming_PB, SIGNAL( clicked( ) ), this, SLOT( updateInProxyIndicator() ) ); manager = NULL ; @@ -105,7 +105,7 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) for(std::list::const_iterator it(ip_servers.begin());it!=ip_servers.end();++it) ui.IPServersLV->addItem(QString::fromStdString(*it)) ; - ui.torpage_incoming->setVisible(false); + ui.hiddenpage_incoming->setVisible(false); #ifdef SERVER_DEBUG std::cerr << "ServerPage::ServerPage() called"; @@ -218,6 +218,7 @@ void ServerPage::load() if (mIsHiddenNode) { + mHiddenType = detail.hiddenType; ui.tabWidget->setTabEnabled(1,false) ; loadHiddenNode(); return; @@ -226,7 +227,12 @@ void ServerPage::load() loadFilteredIps() ; ui.netModeComboBox->show() ; + ui.textlabel_upnp->show(); + ui.iconlabel_upnp->show(); + ui.label_nat->show(); + ui.hiddenMode_LB->hide() ; + ui.iconlabel_hiddenMode->hide() ; /* set net mode */ int netIndex = 0; @@ -302,15 +308,20 @@ void ServerPage::load() for(std::list::const_iterator it(detail.ipAddressList.begin());it!=detail.ipAddressList.end();++it) ui.ipAddressList->addItem(QString::fromStdString(*it)); - /* TOR PAGE SETTINGS - only Proxy (outgoing) */ + /* HIDDEN PAGE SETTINGS - only Proxy (outgoing) */ std::string proxyaddr; uint16_t proxyport; uint32_t status ; - rsPeers->getProxyServer(proxyaddr, proxyport, status); - ui.torpage_proxyAddress -> setText(QString::fromStdString(proxyaddr)); - ui.torpage_proxyPort -> setValue(proxyport); + // Tor + rsPeers->getProxyServer(RS_HIDDEN_TYPE_TOR, proxyaddr, proxyport, status); + ui.hiddenpage_proxyAddress_tor -> setText(QString::fromStdString(proxyaddr)); + ui.hiddenpage_proxyPort_tor -> setValue(proxyport); + // I2P + rsPeers->getProxyServer(RS_HIDDEN_TYPE_I2P, proxyaddr, proxyport, status); + ui.hiddenpage_proxyAddress_i2p -> setText(QString::fromStdString(proxyaddr)); + ui.hiddenpage_proxyPort_i2p -> setValue(proxyport); - updateTorOutProxyIndicator(); + updateOutProxyIndicator(); } void ServerPage::toggleAutoIncludeFriends(bool b) @@ -697,7 +708,7 @@ void ServerPage::updateStatus() ui.iconlabel_ext->setPixmap(QPixmap(":/images/ledoff1.png")); // check for Tor - updateTorOutProxyIndicator(); + updateOutProxyIndicator(); } void ServerPage::toggleUPnP() @@ -807,17 +818,29 @@ void ServerPage::saveAddresses() rsConfig->SetMaxDataRates( ui.totalDownloadRate->value(), ui.totalUploadRate->value() ); // HANDLE PROXY SERVER. - std::string orig_proxyaddr; - uint16_t orig_proxyport; - uint32_t status ; - rsPeers->getProxyServer(orig_proxyaddr, orig_proxyport,status); + std::string orig_proxyaddr, new_proxyaddr; + uint16_t orig_proxyport, new_proxyport; + uint32_t status ; + // Tor + rsPeers->getProxyServer(RS_HIDDEN_TYPE_TOR, orig_proxyaddr, orig_proxyport,status); - std::string new_proxyaddr = ui.torpage_proxyAddress -> text().toStdString(); - uint16_t new_proxyport = ui.torpage_proxyPort -> value(); + new_proxyaddr = ui.hiddenpage_proxyAddress_tor -> text().toStdString(); + new_proxyport = ui.hiddenpage_proxyPort_tor -> value(); if ((new_proxyaddr != orig_proxyaddr) || (new_proxyport != orig_proxyport)) { - rsPeers->setProxyServer(new_proxyaddr, new_proxyport); + rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, new_proxyaddr, new_proxyport); + } + + // I2P + rsPeers->getProxyServer(RS_HIDDEN_TYPE_I2P, orig_proxyaddr, orig_proxyport,status); + + new_proxyaddr = ui.hiddenpage_proxyAddress_i2p -> text().toStdString(); + new_proxyport = ui.hiddenpage_proxyPort_i2p -> value(); + + if ((new_proxyaddr != orig_proxyaddr) || (new_proxyport != orig_proxyport)) + { + rsPeers->setProxyServer(RS_HIDDEN_TYPE_I2P, new_proxyaddr, new_proxyport); } load(); @@ -861,7 +884,13 @@ void ServerPage::loadHiddenNode() // FIXED. //ui.netModeComboBox->setCurrentIndex(3); ui.netModeComboBox->hide(); + ui.textlabel_upnp->hide(); + ui.iconlabel_upnp->hide(); + ui.label_nat->hide(); + ui.hiddenMode_LB->show(); + ui.iconlabel_hiddenMode->show() ; + ui.iconlabel_hiddenMode->setPixmap(QPixmap(":/images/ledon1.png")); // CHANGE OPTIONS ON ui.discComboBox->removeItem(3); @@ -893,7 +922,7 @@ void ServerPage::loadHiddenNode() ui.label_dynDNS->setVisible(false); ui.dynDNS ->setVisible(false); - ui.torpage_incoming->setVisible(true); + ui.hiddenpage_incoming->setVisible(true); /* Addresses must be set here - otherwise can't edit it */ /* set local address */ @@ -901,7 +930,7 @@ void ServerPage::loadHiddenNode() ui.localPort -> setValue(detail.localPort); /* set the server address */ - ui.extAddress->setText(tr("Hidden - See Tor Config")); + ui.extAddress->setText(tr("Hidden - See Config")); ui.showDiscStatusBar->setChecked(Settings->getStatusBarFlags() & STATUSBAR_DISC); ui.showDiscStatusBar->hide() ; // hidden because not functional at the moment. @@ -924,32 +953,64 @@ void ServerPage::loadHiddenNode() /* TOR PAGE SETTINGS */ /* set local address */ - ui.torpage_localAddress->setEnabled(false); - ui.torpage_localAddress->setText(QString::fromStdString(detail.localAddr)); - ui.torpage_localPort -> setValue(detail.localPort); + ui.hiddenpage_localAddress->setEnabled(false); + ui.hiddenpage_localAddress->setText(QString::fromStdString(detail.localAddr)); + ui.hiddenpage_localPort -> setValue(detail.localPort); /* set the server address */ - ui.torpage_onionAddress->setText(QString::fromStdString(detail.hiddenNodeAddress)); - ui.torpage_onionPort -> setValue(detail.hiddenNodePort); + ui.hiddenpage_serviceAddress->setText(QString::fromStdString(detail.hiddenNodeAddress)); + ui.hiddenpage_servicePort -> setValue(detail.hiddenNodePort); + /* in I2P there is no port - there is only the address */ + ui.hiddenpage_servicePort->setEnabled(detail.hiddenType != RS_HIDDEN_TYPE_I2P); + /* out proxy settings */ std::string proxyaddr; - uint16_t proxyport; - uint32_t proxy_state_flags; - rsPeers->getProxyServer(proxyaddr, proxyport, proxy_state_flags); - ui.torpage_proxyAddress -> setText(QString::fromStdString(proxyaddr)); - ui.torpage_proxyPort -> setValue(proxyport); + uint16_t proxyport; + uint32_t status ; + // Tor + rsPeers->getProxyServer(RS_HIDDEN_TYPE_TOR, proxyaddr, proxyport, status); + ui.hiddenpage_proxyAddress_tor -> setText(QString::fromStdString(proxyaddr)); + ui.hiddenpage_proxyPort_tor -> setValue(proxyport); + // I2P + rsPeers->getProxyServer(RS_HIDDEN_TYPE_I2P, proxyaddr, proxyport, status); + ui.hiddenpage_proxyAddress_i2p -> setText(QString::fromStdString(proxyaddr)); + ui.hiddenpage_proxyPort_i2p -> setValue(proxyport); - updateTorOutProxyIndicator(); + updateOutProxyIndicator(); - QString expected = "HiddenServiceDir \n"; - expected += "HiddenServicePort "; - expected += QString::number(detail.hiddenNodePort); - expected += " "; - expected += QString::fromStdString(detail.localAddr); - expected += ":"; - expected += QString::number(detail.localPort); + QString expected = ""; + switch (mHiddenType) { + case RS_HIDDEN_TYPE_I2P: + ui.l_serviceAddress->setText(tr("I2P Address")); + ui.l_incomingTestResult->setText(tr("I2P incoming ok")); - ui.torpage_configuration->setPlainText(expected); + expected += "http://127.0.0.1:7657/i2ptunnelmgr - I2P Hidden Services\n"; + expected += tr("Points at: "); + expected += QString::fromStdString(detail.localAddr); + expected += ":"; + expected += QString::number(detail.localPort); + break; + case RS_HIDDEN_TYPE_TOR: + ui.l_serviceAddress->setText(tr("Onion Address")); + ui.l_incomingTestResult->setText(tr("Tor incoming ok")); + + expected += "HiddenServiceDir \n"; + expected += "HiddenServicePort "; + expected += QString::number(detail.hiddenNodePort); + expected += " "; + expected += QString::fromStdString(detail.localAddr); + expected += ":"; + expected += QString::number(detail.localPort); + break; + default: + ui.l_serviceAddress->setText(tr("Service Address")); + ui.l_incomingTestResult->setText(tr("incoming ok")); + + expected += "Please fill in a service address"; + + break; + } + ui.hiddenpage_configuration->setPlainText(expected); } /** Loads the settings for this page */ @@ -1005,7 +1066,7 @@ void ServerPage::updateStatusHiddenNode() #endif - updateTorOutProxyIndicator(); + updateOutProxyIndicator(); } void ServerPage::saveAddressesHiddenNode() @@ -1036,41 +1097,54 @@ void ServerPage::saveAddressesHiddenNode() if ((vs_disc != detail.vs_disc) || (vs_dht != detail.vs_dht)) rsPeers->setVisState(ownId, vs_disc, vs_dht); - if (detail.localPort != ui.torpage_localPort->value()) + if (detail.localPort != ui.hiddenpage_localPort->value()) { // Set Local Address - force to 127.0.0.1 - rsPeers->setLocalAddress(ownId, "127.0.0.1", ui.torpage_localPort->value()); + rsPeers->setLocalAddress(ownId, "127.0.0.1", ui.hiddenpage_localPort->value()); } - std::string hiddenAddr = ui.torpage_onionAddress->text().toStdString(); - uint16_t hiddenPort = ui.torpage_onionPort->value(); + std::string hiddenAddr = ui.hiddenpage_serviceAddress->text().toStdString(); + uint16_t hiddenPort = ui.hiddenpage_servicePort->value(); if ((hiddenAddr != detail.hiddenNodeAddress) || (hiddenPort != detail.hiddenNodePort)) { rsPeers->setHiddenNode(ownId, hiddenAddr, hiddenPort); } // HANDLE PROXY SERVER. - std::string orig_proxyaddr; - uint16_t orig_proxyport; - uint32_t state_flags ; - rsPeers->getProxyServer(orig_proxyaddr, orig_proxyport,state_flags); + std::string orig_proxyaddr,new_proxyaddr; + uint16_t orig_proxyport, new_proxyport; + uint32_t status ; + // Tor + rsPeers->getProxyServer(RS_HIDDEN_TYPE_TOR, orig_proxyaddr, orig_proxyport,status); - std::string new_proxyaddr = ui.torpage_proxyAddress -> text().toStdString(); - uint16_t new_proxyport = ui.torpage_proxyPort -> value(); + new_proxyaddr = ui.hiddenpage_proxyAddress_tor -> text().toStdString(); + new_proxyport = ui.hiddenpage_proxyPort_tor -> value(); if ((new_proxyaddr != orig_proxyaddr) || (new_proxyport != orig_proxyport)) { - rsPeers->setProxyServer(new_proxyaddr, new_proxyport); + rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, new_proxyaddr, new_proxyport); + } + + // I2P + rsPeers->getProxyServer(RS_HIDDEN_TYPE_I2P, orig_proxyaddr, orig_proxyport,status); + + new_proxyaddr = ui.hiddenpage_proxyAddress_i2p -> text().toStdString(); + new_proxyport = ui.hiddenpage_proxyPort_i2p -> value(); + + if ((new_proxyaddr != orig_proxyaddr) || (new_proxyport != orig_proxyport)) + { + rsPeers->setProxyServer(RS_HIDDEN_TYPE_I2P, new_proxyaddr, new_proxyport); } rsConfig->SetMaxDataRates( ui.totalDownloadRate->value(), ui.totalUploadRate->value() ); load(); } -void ServerPage::updateTorOutProxyIndicator() +void ServerPage::updateOutProxyIndicator() { QTcpSocket socket ; - socket.connectToHost(ui.torpage_proxyAddress->text(),ui.torpage_proxyPort->text().toInt()); + // Tor + socket.connectToHost(ui.hiddenpage_proxyAddress_tor->text(),ui.hiddenpage_proxyPort_tor->text().toInt()); if(socket.waitForConnected(500)) { socket.disconnectFromHost(); @@ -1082,25 +1156,23 @@ void ServerPage::updateTorOutProxyIndicator() ui.iconlabel_tor_outgoing->setPixmap(QPixmap(ICON_STATUS_UNKNOWN)) ; ui.iconlabel_tor_outgoing->setToolTip(tr("Tor proxy is not enabled")) ; } -} -void ServerPage::updateLocInProxyIndicator() -{ - QTcpSocket socket ; - socket.connectToHost(ui.torpage_localAddress->text(),ui.torpage_localPort->text().toInt()); - if(socket.waitForConnected(1000)) - { - socket.disconnectFromHost(); - ui.iconlabel_tor_incoming->setPixmap(QPixmap(ICON_STATUS_OK)) ; - ui.iconlabel_tor_incoming->setToolTip(tr("You are reachable through Tor.")) ; - } - else - { - ui.iconlabel_tor_incoming->setPixmap(QPixmap(ICON_STATUS_UNKNOWN)) ; - ui.iconlabel_tor_incoming->setToolTip(tr("Tor proxy is not enabled or broken.\nAre you running a Tor hidden service?\nCheck your ports!")) ; - } + // I2P + socket.connectToHost(ui.hiddenpage_proxyAddress_i2p->text(),ui.hiddenpage_proxyPort_i2p->text().toInt()); + if(socket.waitForConnected(500)) + { + socket.disconnectFromHost(); + ui.iconlabel_i2p_outgoing->setPixmap(QPixmap(ICON_STATUS_OK)) ; + ui.iconlabel_i2p_outgoing->setToolTip(tr("Proxy seems to work.")) ; + } + else + { + ui.iconlabel_i2p_outgoing->setPixmap(QPixmap(ICON_STATUS_UNKNOWN)) ; + ui.iconlabel_i2p_outgoing->setToolTip(tr("I2P proxy is not enabled")) ; + } } -void ServerPage::updateTorInProxyIndicator() + +void ServerPage::updateInProxyIndicator() { // need to find a proper way to do this @@ -1113,21 +1185,31 @@ void ServerPage::updateTorInProxyIndicator() QNetworkProxy proxy ; proxy.setType(QNetworkProxy::Socks5Proxy); - proxy.setHostName(ui.torpage_proxyAddress->text()); - proxy.setPort(ui.torpage_proxyPort->text().toInt()); + switch (mHiddenType) { + case RS_HIDDEN_TYPE_I2P: + proxy.setHostName(ui.hiddenpage_proxyAddress_i2p->text()); + proxy.setPort(ui.hiddenpage_proxyPort_i2p->text().toInt()); + break; + case RS_HIDDEN_TYPE_TOR: + proxy.setHostName(ui.hiddenpage_proxyAddress_tor->text()); + proxy.setPort(ui.hiddenpage_proxyPort_tor->text().toInt()); + break; + default: + return; + } proxy.setCapabilities(QNetworkProxy::HostNameLookupCapability | proxy.capabilities()) ; - //ui.iconlabel_tor_incoming->setPixmap(QPixmap(ICON_STATUS_UNKNOWN)) ; - //ui.testIncomingTor_PB->setIcon(QIcon(":/loader/circleball-16.gif")) ; - QMovie *movie = new QMovie(":/images/loader/circleball-16.gif"); - ui.iconlabel_tor_incoming->setMovie(movie); - movie->start() ; + //ui.iconlabel_tor_incoming->setPixmap(QPixmap(ICON_STATUS_UNKNOWN)) ; + //ui.testIncomingTor_PB->setIcon(QIcon(":/loader/circleball-16.gif")) ; + QMovie *movie = new QMovie(":/images/loader/circleball-16.gif"); + ui.iconlabel_service_incoming->setMovie(movie); + movie->start() ; QNetworkProxy::setApplicationProxy(proxy) ; - QUrl url("https://"+ui.torpage_onionAddress->text() + ":" + ui.torpage_onionPort->text()) ; + QUrl url("https://"+ui.hiddenpage_serviceAddress->text() + ":" + ui.hiddenpage_servicePort->text()) ; - std::cerr << "Setting proxy hostname+port to " << std::dec << ui.torpage_proxyAddress->text().toStdString() << ":" << ui.torpage_proxyPort->text().toInt() << std::endl; + std::cerr << "Setting proxy hostname+port to " << std::dec << ui.hiddenpage_proxyAddress_tor->text().toStdString() << ":" << ui.hiddenpage_proxyPort_tor->text().toInt() << std::endl; std::cerr << "Connecting to " << url.toString().toStdString() << std::endl; connect(manager, SIGNAL(finished(QNetworkReply*)),this,SLOT(handleNetworkReply(QNetworkReply*))) ; @@ -1143,8 +1225,8 @@ void ServerPage::handleNetworkReply(QNetworkReply *reply) if(reply->isOpen() && error == QNetworkReply::SslHandshakeFailedError) { std::cerr <<"Connected!" << std::endl; - ui.iconlabel_tor_incoming->setPixmap(QPixmap(ICON_STATUS_OK)) ; - ui.iconlabel_tor_incoming->setToolTip(tr("You are reachable through Tor.")) ; + ui.iconlabel_service_incoming->setPixmap(QPixmap(ICON_STATUS_OK)) ; + ui.iconlabel_service_incoming->setToolTip(tr("You are reachable through the hidden service.")) ; //ui.testIncomingTor_PB->setIcon(QIcon(ICON_STATUS_OK)) ; } else @@ -1152,8 +1234,8 @@ void ServerPage::handleNetworkReply(QNetworkReply *reply) std::cerr <<"Failed!" << std::endl; //ui.testIncomingTor_PB->setIcon(QIcon(ICON_STATUS_UNKNOWN)) ; - ui.iconlabel_tor_incoming->setPixmap(QPixmap(ICON_STATUS_UNKNOWN)) ; - ui.iconlabel_tor_incoming->setToolTip(tr("Tor proxy is not enabled or broken.\nAre you running a Tor hidden service?\nCheck your ports!")) ; + ui.iconlabel_service_incoming->setPixmap(QPixmap(ICON_STATUS_UNKNOWN)) ; + ui.iconlabel_service_incoming->setToolTip(tr("The proxy is not enabled or broken.\nAre all services up and running fine??\nAlso check your ports!")) ; } reply->close(); diff --git a/retroshare-gui/src/gui/settings/ServerPage.h b/retroshare-gui/src/gui/settings/ServerPage.h index 1c84e10b5..6d8399974 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.h +++ b/retroshare-gui/src/gui/settings/ServerPage.h @@ -25,6 +25,7 @@ #include #include "ui_ServerPage.h" #include "RsAutoUpdatePage.h" +#include class QNetworkReply; class QNetworkAccessManager; @@ -52,6 +53,7 @@ public slots: void updateStatus(); private slots: + // ban list void updateSelectedBlackListIP(int row, int, int, int); void updateSelectedWhiteListIP(int row,int,int,int); void addIpRangeToBlackList(); @@ -69,25 +71,27 @@ private slots: void ipFilterContextMenu(const QPoint &); void ipWhiteListContextMenu(const QPoint &point); void removeBannedIp(); + + // server void saveAddresses(); void toggleUPnP(); void toggleIpDetermination(bool) ; void toggleTunnelConnection(bool) ; void clearKnownAddressList() ; void handleNetworkReply(QNetworkReply *reply); - void updateTorInProxyIndicator(); + void updateInProxyIndicator(); private: - - // Alternative Versions for HiddenNode Mode. + // ban list void addPeerToIPTable(QTableWidget *table, int row, const BanListPeer &blp); bool removeCurrentRowFromBlackList(sockaddr_storage& collected_addr,int& masked_bytes); bool removeCurrentRowFromWhiteList(sockaddr_storage &collected_addr, int &masked_bytes); + + // Alternative Versions for HiddenNode Mode. void loadHiddenNode(); void updateStatusHiddenNode(); void saveAddressesHiddenNode(); - void updateTorOutProxyIndicator(); - void updateLocInProxyIndicator(); + void updateOutProxyIndicator(); void loadFilteredIps() ; Ui::ServerPage ui; @@ -95,6 +99,7 @@ private: QNetworkAccessManager *manager ; bool mIsHiddenNode; + uint32_t mHiddenType; }; #endif // !SERVERPAGE_H diff --git a/retroshare-gui/src/gui/settings/ServerPage.ui b/retroshare-gui/src/gui/settings/ServerPage.ui index 5a481d8b5..712e49f3e 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.ui +++ b/retroshare-gui/src/gui/settings/ServerPage.ui @@ -6,12 +6,21 @@ 0 0 - 722 - 650 + 724 + 568 - + + 6 + + + 6 + + + 6 + + 6 @@ -23,104 +32,36 @@ Network Configuration - - - - - - - - Automatic (UPnP) - - - - - Firewalled - - - - - Manually Forwarded Port - - - - - - - - - 75 - true - - - - <html><head/><body><p>This Retroshare node is running in &quot;Hidden Mode&quot;. That means it can only be reached though the Tor network.</p><p>As such, some network options are disabled.</p></body></html> - - - [Hidden mode] - - - - - - - Qt::Horizontal - - - QSizePolicy::MinimumExpanding - - - - 40 - 20 - - - - - - - - - 200 - 0 - - - - <html><head/><body><p>The DHT allows you to answer connection requests from your friends using BitTorrent's DHT. It greatly improves the connectivity. No information is actually stored in the DHT. It is only used as a proxy system to get in touch with other Retroshare nodes.</p><p>The Discovery service sends node name and ids of your trusted contacts to connected peers, to help them choose new friends. The friendship is never automatic however, and both peers still need to trust each other to allow connection. </p></body></html> - - - - Public: DHT & Discovery - - - - - Private: Discovery Only - - - - - Inverted: DHT Only - - - - - Dark Net: None - - - - - - - + + 6 + + 6 + + + 6 + + + + + Network Mode + + + + + + + Nat + + + @@ -142,6 +83,32 @@ + + + + + 50 + false + + + + Download limit (KB/s) + + + + + + + + 50 + false + + + + Upload limit (KB/s) + + + @@ -149,17 +116,42 @@ 6 - + + + + + 0 + 0 + + + + <html><head/><body><p>This download limit covers the whole application. However, in some situations, such as when transfering many small files at once, the estimated bandwidth becomes unreliable and the total value reported by Retroshare might exceed that limit. </p></body></html> + + + kB/s + + + 1 + + + 100000 + + + 1 + + + + - + Port: - + Acceptable ports range from 10 to 65535. Normally Ports below 1024 are reserved by your system. @@ -175,17 +167,17 @@ - + - + Port: - + Acceptable ports range from 10 to 65535. Normally ports below 1024 are reserved by your system. @@ -201,114 +193,232 @@ - + - - - - - - - - - - 6 - - - 6 - + + + + + Automatic (UPnP) + + + + + Firewalled + + + + + Manually Forwarded Port + + + + - - + + - 16 - 16 + 200 + 0 - - - - - :/images/ledoff1.png - - - - - - - Local network - - - - - - - - - 6 - - - 6 - - - - - - 16 - 16 - - - - - - - :/images/ledoff1.png - - - - - - <html><head/><body><p>The bullet turns green as soon as Retroshare manages to get your own IP from the websites listed below, if you enabled that action. Retroshare will also use other means to find out your own IP.</p></body></html> - - - External ip address finder + <html><head/><body><p>The DHT allows you to answer connection requests from your friends using BitTorrent's DHT. It greatly improves the connectivity. No information is actually stored in the DHT. It is only used as a proxy system to get in touch with other Retroshare nodes.</p><p>The Discovery service sends node name and ids of your trusted contacts to connected peers, to help them choose new friends. The friendship is never automatic however, and both peers still need to trust each other to allow connection. </p></body></html> + + + Public: DHT & Discovery + + + + + Private: Discovery Only + + + + + Inverted: DHT Only + + + + + Dark Net: None + + - - - - - - 6 - - - 6 - - - - - - 16 - 16 - + + + + 6 - + + 6 + + + + + + 16 + 16 + + + + + + + :/images/ledoff1.png + + + + + + + <html><head/><body><p>The bullet turns green as soon as Retroshare manages to get your own IP from the websites listed below, if you enabled that action. Retroshare will also use other means to find out your own IP.</p></body></html> + + + External ip address finder + + + + + + + + + 6 + + + 6 + + + + + + 16 + 16 + + + + + + + :/images/ledoff1.png + + + + + + + Local network + + + + + + + + + + 0 + 0 + + + + <html><head/><body><p>The upload limit covers the entire software. Too small an upload limit might eventually block low priority services (forums, channels). A minimum recommended value is 50KB/s. </p></body></html> + + + kB/s + + - - :/images/ledoff1.png + + 1 + + + 100000 + + + 1 - - - - UPnP + + + + 6 - + + 6 + + + + + + 16 + 16 + + + + + + + :/images/ledoff1.png + + + + + + + UPnP + + + + + + + + + 6 + + + 6 + + + + + + 16 + 16 + + + + + + + :/images/ledoff1.png + + + + + + + + 75 + true + + + + <html><head/><body><p>The bullet turns green as soon as Retroshare manages to get your own IP from the websites listed below, if you enabled that action. Retroshare will also use other means to find out your own IP.</p></body></html> + + + [Hidden mode] + + + + @@ -316,7 +426,7 @@ - + @@ -350,7 +460,7 @@ - + @@ -360,14 +470,14 @@ - + Show Discovery information in statusbar - + If you uncheck this, RetroShare can only determine your IP @@ -383,7 +493,7 @@ behind a firewall or a VPN. - + @@ -396,107 +506,12 @@ behind a firewall or a VPN. - - - - - - - - - 75 - true - - - - Download limit (KB/s) - - - - - - - - 0 - 0 - - - - <html><head/><body><p>This download limit covers the whole application. However, in some situations, such as when transfering many small files at once, the estimated bandwidth becomes unreliable and the total value reported by Retroshare might exceed that limit. </p></body></html> - - - kB/s - - - 1 - - - 100000 - - - 1 - - - - - - - - - 6 - - - - - - 75 - true - - - - Upload limit (KB/s) - - - - - - - - 0 - 0 - - - - <html><head/><body><p>The upload limit covers the entire software. Too small an upload limit might eventually block low priority services (forums, channels). A minimum recommended value is 50KB/s. </p></body></html> - - - kB/s - - - - - - 1 - - - 100000 - - - 1 - - - - - - - showDiscStatusBar allowIpDeterminationCB IPServersLV ipAddressList - @@ -515,7 +530,7 @@ behind a firewall or a VPN. 0 - + IP blacklist @@ -756,15 +771,15 @@ behind a firewall or a VPN. - + - Tor Configuration + Hidden Service Configuration - Outgoing Tor Connections + Outgoing Connections @@ -779,10 +794,10 @@ behind a firewall or a VPN. - + - + 10 @@ -822,16 +837,71 @@ behind a firewall or a VPN. + + + + 0 + + + 0 + + + + + + + I2P Socks Proxy + + + + + + + + + + 10 + + + 65535 + + + + + + + + + + + + + + :/images/ledoff1.png + + + + + + + I2P outgoing Okay + + + + + + + 16777215 - 100 + 145 - Qt::ScrollBarAlwaysOff + Qt::ScrollBarAsNeeded true @@ -839,8 +909,11 @@ behind a firewall or a VPN. Tor Socks Proxy default: 127.0.0.1:9050. Set in torrc config and update here. -You can connect to Hidden Nodes, even if you -are running a standard Node, so why not setup Tor? +I2P Socks Proxy: see http://127.0.0.1:7657/i2ptunnelmgr for setting up a client tunnel: +Tunnel Wizard -> Client Tunnel -> SOCKS 4/4a/5 -> enter a name -> leave 'Outproxies' empty -> enter port (memorize!) [you may also want to set the reachability to 127.0.0.1] -> check 'Auto Start' -> finish! +Now enter the address (e.g. 127.0.0.1) and the port you've picked before for the I2P Proxy. + +You can connect to Hidden Nodes, even if you are running a standard Node, so why not setup Tor and/or I2P? @@ -848,7 +921,7 @@ are running a standard Node, so why not setup Tor? - + 0 @@ -856,13 +929,13 @@ are running a standard Node, so why not setup Tor? - Incoming Tor Connections + Incoming Service Connections - + 10 @@ -874,9 +947,9 @@ are running a standard Node, so why not setup Tor? - + - <html><head/><body><p>This button simulates a SSL connection to your Tor address using the Tor proxy. If your Tor node is reachable, it should cause a SSL handshake error, which RS will interpret as a valid connection state. This operation might also cause several "security warning" about connections from your local host IP (127.0.0.1) in the News Feed if you enabled it,</p></body></html> + <html><head/><body><p>This button simulates a SSL connection to your hidden address using the corresponding proxy. If your hidden node is reachable, it should cause a SSL handshake error, which RS will interpret as a valid connection state. This operation might also cause several &quot;security warning&quot; about connections from your local host IP (127.0.0.1) in the News Feed if you enabled it,</p></body></html> Test @@ -886,7 +959,7 @@ are running a standard Node, so why not setup Tor? - + 10 @@ -896,9 +969,9 @@ are running a standard Node, so why not setup Tor? - + - Onion Address + Service Address @@ -910,23 +983,23 @@ are running a standard Node, so why not setup Tor? - + - <html><head/><body><p>This is your onion address. It should look like <span style=" font-weight:600;">[something].onion. </span>If you configured a hidden service with Tor, the onion address is generated automatically by Tor. You can get it in e.g. <span style=" font-weight:600;">/var/lib/tor/[service name]/hostname</span></p></body></html> + <html><head/><body><p>This is your hidden address. It should look like <span style=" font-weight:600;">[something].onion</span> or <span style=" font-weight:600;">[something].b32.i2p. </span>If you configured a hidden service with Tor, the onion address is generated automatically by Tor. You can get it in e.g. <span style=" font-weight:600;">/var/lib/tor/[service name]/hostname</span>. For I2P: Setup a server tunnel ( http://127.0.0.1:7657/i2ptunnelmgr ) and copy it's base32 address when it is started (should end with .b32.i2p)</p></body></html> - + - <html><head/><body><p>This is the local address to which the Tor hidden service points at your localhost. Most of the time, <span style=" font-weight:600;">127.0.0.1</span> is the right answer.</p></body></html> + <html><head/><body><p>This is the local address to which the hidden service points at your localhost. Most of the time, <span style=" font-weight:600;">127.0.0.1</span> is the right answer.</p></body></html> - + 16 @@ -942,9 +1015,9 @@ are running a standard Node, so why not setup Tor? - + - Tor incoming ok + incoming ok @@ -957,12 +1030,12 @@ are running a standard Node, so why not setup Tor? - Expected torrc Port Configuration: + Expected Configuration: - + 0 @@ -988,8 +1061,7 @@ are running a standard Node, so why not setup Tor? true - HiddenServiceDir </your/path/to/hidden/directory/service> -HiddenServicePort 9191 127.0.0.1:9191 + Please fill in a service address @@ -1013,12 +1085,14 @@ HiddenServicePort 9191 127.0.0.1:9191 true - To Receive Connections, you must first setup a Tor Hidden Service. -See Tor documentation for HOWTO details. + To Receive Connections, you must first setup a Tor/I2P Hidden Service. +For Tor: See torrc and documentation for HOWTO details. +For I2P: See http://127.0.0.1:7657/i2ptunnelmgr for setting up a server tunnel: +Tunnel Wizard -> Server Tunnel -> Standard -> enter a name -> enter the address and port your RS is using (see Local Address above) -> check 'Auto Start' -> finish! -Once this is done, paste the Onion Address in the box above. -This is your external address on the Tor network. -Finally make sure that the Ports match the Tor configuration. +Once this is done, paste the Onion/I2P (Base32) Address in the box above. +This is your external address on the Tor/I2P network. +Finally make sure that the Ports match the configuration. If you have issues connecting over Tor check the Tor logs too. @@ -1047,8 +1121,6 @@ If you have issues connecting over Tor check the Tor logs too. - netModeComboBox - discComboBox localAddress localPort extAddress diff --git a/retroshare-gui/src/gui/settings/ServicePermissionsPage.cpp b/retroshare-gui/src/gui/settings/ServicePermissionsPage.cpp index 5cf0a59c0..5ded8fb80 100644 --- a/retroshare-gui/src/gui/settings/ServicePermissionsPage.cpp +++ b/retroshare-gui/src/gui/settings/ServicePermissionsPage.cpp @@ -46,12 +46,12 @@ ServicePermissionsPage::ServicePermissionsPage(QWidget * parent, Qt::WindowFlags QString ServicePermissionsPage::helpText() const { return tr("

      Permissions

    \ -

    Permissions allow you to control which services are available to which friends

    \ +

    Permissions allow you to control which services are available to which friends.

    \

    Each interruptor shows two lights, indicating whether you or your friend has enabled\ - that service. Both needs to be ON (showing ) to\ + that service. Both need to be ON (showing ) to\ let information transfer for a specific service/friend combination.

    \

    For each service, the global switch / \ - allow to turn a service ON/OFF for all friends at once.

    \ + allows you to turn a service ON/OFF for all friends at once.

    \

    Be very careful: Some services depend on each other. For instance turning turtle OFF will also\ stop all anonymous transfer, distant chat and distant messaging.

    "); } diff --git a/retroshare-gui/src/gui/settings/WebuiPage.cpp b/retroshare-gui/src/gui/settings/WebuiPage.cpp index 3b6770c6c..b05bf8698 100644 --- a/retroshare-gui/src/gui/settings/WebuiPage.cpp +++ b/retroshare-gui/src/gui/settings/WebuiPage.cpp @@ -67,7 +67,7 @@ void WebuiPage::load() QString WebuiPage::helpText() const { return tr("

      Webinterface

    \ -

    The webinterface allows to control Retroshare from the browser. Multiple devices can share control over one Retroshare instance. So you could start a conversation on a tablet computer and later use a desktop computer to continue it.

    \ +

    The webinterface allows you to control Retroshare from the browser. Multiple devices can share control over one Retroshare instance. So you could start a conversation on a tablet computer and later use a desktop computer to continue it.

    \

    Warning: don't expose the webinterface to the internet, because there is no access control and no encryption. If you want to use the webinterface over the internet, use a SSH tunnel or a proxy to secure the connection.

    "); } diff --git a/retroshare-gui/src/gui/settings/rsharesettings.cpp b/retroshare-gui/src/gui/settings/rsharesettings.cpp index 83fbf0563..b7cf16f01 100644 --- a/retroshare-gui/src/gui/settings/rsharesettings.cpp +++ b/retroshare-gui/src/gui/settings/rsharesettings.cpp @@ -20,6 +20,7 @@ * Boston, MA 02110-1301, USA. ****************************************************************/ +#include #include #include #include @@ -237,26 +238,32 @@ void RshareSettings::setToolButtonStyle(Qt::ToolButtonStyle style) } } +int RshareSettings::computeBestIconSize(int n_sizes,int *sizes,int recommended_size) +{ + float default_size = QFontMetricsF(QWidget().font()).height()/16.0 * recommended_size ; + float closest_ratio_dist = 10000.0f ; + int best_default_size = sizes[0] ; + + for(int i=0;i 6 - + + 0 + + + 0 + + + 0 + + 0 @@ -187,6 +196,18 @@ + + 3 + + + 3 + + + 3 + + + 3 + diff --git a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui index 56f5e5315..3ed54ef4e 100644 --- a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui +++ b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui @@ -6,14 +6,17 @@ 0 0 - 1597 - 811 + 812 + 349 Form + + 0 + @@ -44,7 +47,17 @@ - + + + + 0 + 0 + + + + QComboBox::AdjustToContents + + @@ -75,7 +88,17 @@ - + + + + 0 + 0 + + + + QComboBox::AdjustToContents + + @@ -94,7 +117,7 @@ - 726 + 20 20 diff --git a/retroshare-gui/src/gui/statistics/BwCtrlWindow.ui b/retroshare-gui/src/gui/statistics/BwCtrlWindow.ui index dc20f8015..cf9e0ab8d 100644 --- a/retroshare-gui/src/gui/statistics/BwCtrlWindow.ui +++ b/retroshare-gui/src/gui/statistics/BwCtrlWindow.ui @@ -7,7 +7,7 @@ 0 0 1447 - 911 + 471 @@ -89,7 +89,14 @@ Qt::Vertical - + + + + 0 + 0 + + + diff --git a/retroshare-gui/src/gui/statistics/DhtWindow.cpp b/retroshare-gui/src/gui/statistics/DhtWindow.cpp index 5a971c010..4dcb031bd 100644 --- a/retroshare-gui/src/gui/statistics/DhtWindow.cpp +++ b/retroshare-gui/src/gui/statistics/DhtWindow.cpp @@ -23,8 +23,10 @@ #include "ui_DhtWindow.h" #include "util/QtVersion.h" +#include #include #include +#include #include #include @@ -51,6 +53,7 @@ DhtWindow::DhtWindow(QWidget *parent) connect( ui.filterLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(filterItems(QString))); connect( ui.filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int))); + connect( ui.dhtTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(DHTCustomPopupMenu(QPoint))); /* add filter actions */ ui.filterLineEdit->addFilter(QIcon(), tr("IP"), DTW_COL_IPADDR, tr("Search IP")); @@ -62,6 +65,22 @@ DhtWindow::~DhtWindow() } +void DhtWindow::DHTCustomPopupMenu( QPoint ) +{ + QMenu contextMnu( this ); + + QTreeWidgetItem *item = ui.dhtTreeWidget->currentItem(); + if (item) { + + QString Ip = item->text(DTW_COL_IPADDR); + + contextMnu.addAction(QIcon(), tr("Copy %1 to clipboard").arg(Ip), this, SLOT(copyIP())); + + } + + contextMnu.exec(QCursor::pos()); +} + void DhtWindow::updateDisplay() { /* do nothing if locked, or not visible */ @@ -494,6 +513,9 @@ void DhtWindow::updateNetPeers() ui.label_direct->setText(QString::number(nDirectPeers)); ui.label_proxy->setText(QString::number(nProxyPeers)); ui.label_relay->setText(QString::number(nRelayPeers)); + + ui.tabWidget_2->setTabText(1, tr("Peers") + " (" + QString::number(ui.peerTreeWidget->topLevelItemCount()) + ")" ); + //peerSummaryLabel->setText(connstr); } @@ -582,6 +604,9 @@ void DhtWindow::updateRelays() item -> setData(RTW_COL_BANDWIDTH, Qt::DisplayRole, bandwidthstr); } + + ui.tabWidget_2->setTabText(2, tr("Relays") + " (" + QString::number(ui.relayTreeWidget->topLevelItemCount()) + ")" ); + } @@ -673,8 +698,12 @@ void DhtWindow::updateDhtPeers() if (ui.filterLineEdit->text().isEmpty() == false) { filterItems(ui.filterLineEdit->text()); + } + + ui.tabWidget_2->setTabText(0, tr("DHT") + " (" + QString::number(ui.dhtTreeWidget->topLevelItemCount()) + ")" ); } - } + + } @@ -753,3 +782,19 @@ bool DhtWindow::filterItem(QTreeWidgetItem *item, const QString &text, int filte return (visible || visibleChildCount); } +void DhtWindow::copyIP() +{ + QTreeWidgetItem *item = ui.dhtTreeWidget->currentItem(); + if (!item) + { + return; + } + + QString Ip = item->text(DTW_COL_IPADDR); + + QApplication::clipboard()->setText(Ip, QClipboard::Clipboard); + +} + + + diff --git a/retroshare-gui/src/gui/statistics/DhtWindow.h b/retroshare-gui/src/gui/statistics/DhtWindow.h index 83d550336..b0fab373b 100644 --- a/retroshare-gui/src/gui/statistics/DhtWindow.h +++ b/retroshare-gui/src/gui/statistics/DhtWindow.h @@ -44,7 +44,11 @@ public slots: void filterColumnChanged(int); void filterItems(const QString &text); - + +private slots: + /** Create the context popup menu and it's submenus */ + void DHTCustomPopupMenu( QPoint point ); + void copyIP(); protected: //void changeEvent(QEvent *e); diff --git a/retroshare-gui/src/gui/statistics/DhtWindow.ui b/retroshare-gui/src/gui/statistics/DhtWindow.ui index b2dfd8237..9513eeb87 100644 --- a/retroshare-gui/src/gui/statistics/DhtWindow.ui +++ b/retroshare-gui/src/gui/statistics/DhtWindow.ui @@ -467,6 +467,9 @@ + + Qt::CustomContextMenu + Qt::CopyAction diff --git a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp index 9aabeeeaf..91139618b 100644 --- a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp +++ b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp @@ -25,15 +25,33 @@ #include #include +#include #include #include #include +#include #include #include +#include + #include "GlobalRouterStatistics.h" +#include "gui/Identity/IdDetailsDialog.h" #include "gui/settings/rsharesettings.h" +#include "util/QtVersion.h" +#include "util/misc.h" + +#define COL_ID 0 +#define COL_NICKNAME 1 +#define COL_DESTINATION 2 +#define COL_DATASTATUS 3 +#define COL_TUNNELSTATUS 4 +#define COL_DATASIZE 5 +#define COL_DATAHASH 6 +#define COL_RECEIVED 7 +#define COL_SEND 8 + static const int MAX_TUNNEL_REQUESTS_DISPLAY = 10 ; @@ -53,6 +71,12 @@ GlobalRouterStatistics::GlobalRouterStatistics(QWidget *parent) m_bProcessSettings = false; _router_F->setWidget( _tst_CW = new GlobalRouterStatisticsWidget() ) ; + + /* Set header resize modes and initial section sizes Uploads TreeView*/ + QHeaderView_setSectionResizeMode(treeWidget->header(), QHeaderView::ResizeToContents); + + connect(treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(CustomPopupMenu(QPoint))); + // load settings processSettings(true); @@ -89,9 +113,24 @@ void GlobalRouterStatistics::processSettings(bool bLoad) m_bProcessSettings = false; } +void GlobalRouterStatistics::CustomPopupMenu( QPoint ) +{ + QMenu contextMnu( this ); + + QTreeWidgetItem *item = treeWidget->currentItem(); + if (item) { + contextMnu.addAction(QIcon(":/images/info16.png"), tr("Details"), this, SLOT(personDetails())); + + } + + contextMnu.exec(QCursor::pos()); +} + void GlobalRouterStatistics::updateDisplay() { _tst_CW->updateContent() ; + updateContent(); + } QString GlobalRouterStatistics::getPeerName(const RsPeerId &peer_id) @@ -112,6 +151,58 @@ QString GlobalRouterStatistics::getPeerName(const RsPeerId &peer_id) } } +void GlobalRouterStatistics::updateContent() +{ + std::vector cache_infos ; + rsGRouter->getRoutingCacheInfo(cache_infos) ; + + treeWidget->clear(); + + static const QString data_status_string[6] = { "Unkown","Pending","Sent","Receipt OK","Ongoing","Done" } ; + static const QString tunnel_status_string[4] = { "Unmanaged", "Pending", "Ready" } ; + + time_t now = time(NULL) ; + + groupBox->setTitle(tr("Pending packets")+": " + QString::number(cache_infos.size()) ); + + for(int i=0;iaddTopLevelItem(item); + + RsIdentityDetails details ; + rsIdentity->getIdDetails(cache_infos[i].destination,details); + QString nicknames = QString::fromUtf8(details.mNickname.c_str()); + + if(nicknames.isEmpty()) + nicknames = tr("Unknown"); + + item -> setData(COL_ID, Qt::DisplayRole, QString::number(cache_infos[i].mid,16).rightJustified(16,'0')); + item -> setData(COL_NICKNAME, Qt::DisplayRole, nicknames ) ; + item -> setData(COL_DESTINATION, Qt::DisplayRole, QString::fromStdString(cache_infos[i].destination.toStdString())); + item -> setData(COL_DATASTATUS, Qt::DisplayRole, data_status_string[cache_infos[i].data_status % 6]); + item -> setData(COL_TUNNELSTATUS, Qt::DisplayRole, tunnel_status_string[cache_infos[i].tunnel_status % 3]); + item -> setData(COL_DATASIZE, Qt::DisplayRole, misc::friendlyUnit(cache_infos[i].data_size)); + item -> setData(COL_DATAHASH, Qt::DisplayRole, QString::fromStdString(cache_infos[i].item_hash.toStdString())); + item -> setData(COL_RECEIVED, Qt::DisplayRole, QString::number(now - cache_infos[i].routing_time)); + item -> setData(COL_SEND, Qt::DisplayRole, QString::number(now - cache_infos[i].last_sent_time)); + } +} + +void GlobalRouterStatistics::personDetails() +{ + QTreeWidgetItem *item = treeWidget->currentItem(); + std::string id = item->text(COL_DESTINATION).toStdString(); + + if (id.empty()) { + return; + } + + IdDetailsDialog *dialog = new IdDetailsDialog(RsGxsGroupId(id)); + dialog->show(); + +} + GlobalRouterStatisticsWidget::GlobalRouterStatisticsWidget(QWidget *parent) : QWidget(parent) { @@ -124,10 +215,8 @@ GlobalRouterStatisticsWidget::GlobalRouterStatisticsWidget(QWidget *parent) void GlobalRouterStatisticsWidget::updateContent() { - std::vector cache_infos ; RsGRouter::GRouterRoutingMatrixInfo matrix_info ; - rsGRouter->getRoutingCacheInfo(cache_infos) ; rsGRouter->getRoutingMatrixInfo(matrix_info) ; float size = QFontMetricsF(font()).height() ; @@ -188,92 +277,11 @@ void GlobalRouterStatisticsWidget::updateContent() } oy += celly ; - painter.setFont(times_f) ; - painter.drawText(ox,oy+celly,tr("Pending packets")+":" + QString::number(cache_infos.size())) ; oy += celly*2 ; - painter.setFont(monospace_f) ; - - static const QString data_status_string[6] = { "Unkown","Pending","Sent","Receipt OK","Ongoing","Done" } ; - static const QString tunnel_status_string[4] = { "Unmanaged", "Pending", "Ready" } ; - - time_t now = time(NULL) ; std::map > tos ; - static const int nb_fields = 8 ; - - static const QString fname[nb_fields] = { - tr("Id"), - tr("Destination"), - tr("Data status"), - tr("Tunnel status"), - tr("Data size"), - tr("Data hash"), - tr("Received"), - tr("Send") } ; - - std::vector max_column_width(nb_fields,0) ; - - for(int i=0;i strings; - strings.push_back( QString::number(cache_infos[i].mid,16).rightJustified(16,'0') ) ; - strings.push_back( QString::fromStdString(cache_infos[i].destination.toStdString()) ) ; - - //for(std::set::const_iterator it(cache_infos[i].local_origin.begin());it!=cache_infos[i].local_origin.end();++it) - // packet_string += QString::fromStdString((*it).toStdString()) + " - "; - - strings.push_back( data_status_string[cache_infos[i].data_status % 6]) ; - strings.push_back( tunnel_status_string[cache_infos[i].tunnel_status % 3]) ; - strings.push_back( QString::number(cache_infos[i].data_size) ); - strings.push_back( QString::fromStdString(cache_infos[i].item_hash.toStdString())) ; - strings.push_back( QString::number(now - cache_infos[i].routing_time)) ; - strings.push_back( QString::number(now - cache_infos[i].last_sent_time)) ; - - tos[ strings[0] ] = strings ; - - // now compute max column sizes - - for(int j=0;j cumulated_sizes(nb_fields+1,0) ; - - for(int i=1;i<=nb_fields;++i) - { - cumulated_sizes[i] = std::max(max_column_width[i-1],(int)(fm_monospace.boundingRect(fname[i-1]).width()+cellx+2*fact)) ; - cumulated_sizes[i] += cumulated_sizes[i-1] ; - } - + // Now draw the matrix - for(int i=0;i >::const_iterator it(tos.begin());it!=tos.end();++it) - { - for(int i=0;isecond.size();++i) - painter.drawText(ox+cumulated_sizes[i]+2,oy+celly,it->second[i] ) ; - - oy += celly ; - } - - oy += 2*fact; - - for(int i=0;i<=nb_fields;++i) - painter.drawLine(ox+cumulated_sizes[i],top_matrix_oy,ox+cumulated_sizes[i],oy) ; - - painter.drawLine(ox,oy,ox+cumulated_sizes.back(),oy) ; - oy += celly ; - QString prob_string ; painter.setFont(times_f) ; QString Q = tr("Routing matrix (") ; diff --git a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.h b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.h index 083c66524..2180849cc 100644 --- a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.h +++ b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.h @@ -40,7 +40,14 @@ class GlobalRouterStatistics: public RsAutoUpdatePage, public Ui::GlobalRouterSt // Cache for peer names. static QString getPeerName(const RsPeerId& peer_id) ; - + + void updateContent() ; + +private slots: + /** Create the context popup menu and it's submenus */ + void CustomPopupMenu( QPoint point ); + void personDetails(); + private: void processSettings(bool bLoad); @@ -48,6 +55,7 @@ class GlobalRouterStatistics: public RsAutoUpdatePage, public Ui::GlobalRouterSt virtual void updateDisplay() ; + GlobalRouterStatisticsWidget *_tst_CW ; } ; diff --git a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.ui b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.ui index 909c94cd5..38890fa2f 100644 --- a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.ui +++ b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.ui @@ -14,7 +14,7 @@ Router Statistics - + Qt::Vertical @@ -35,17 +35,79 @@ 0 0 593 - 390 + 159 + + + + GroupBox + + + + + + Qt::CustomContextMenu + + + true + + + + ID + + + + + Identity Name + + + + + Destinaton + + + + + Data status + + + + + Tunnel status + + + + + Data size + + + + + Data hash + + + + + Received + + + + + Send + + + + + + +
    - - - + diff --git a/retroshare-gui/src/gui/statusbar/dhtstatus.cpp b/retroshare-gui/src/gui/statusbar/dhtstatus.cpp index da80730c4..7ab41f033 100644 --- a/retroshare-gui/src/gui/statusbar/dhtstatus.cpp +++ b/retroshare-gui/src/gui/statusbar/dhtstatus.cpp @@ -57,6 +57,7 @@ DHTStatus::DHTStatus(QWidget *parent) dhtnetworksizeLabel = new QLabel( "0 (0) ",this ); dhtnetworksizeLabel->setVisible(false); + dhtnetworksizeLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); hbox->addWidget(dhtnetworksizeLabel); hbox->addSpacing(2); @@ -79,7 +80,7 @@ void DHTStatus::getDHTStatus() if (!(config.DHTActive)) { // GRAY. - dhtstatusLabel->setPixmap(QPixmap(":/icons/bullet_grey_64.png").scaledToHeight(S,Qt::SmoothTransformation)); + dhtstatusLabel->setPixmap(QPixmap(":/icons/bullet_grey_128.png").scaledToHeight(S,Qt::SmoothTransformation)); dhtstatusLabel->setToolTip( text + tr("DHT Off")); spaceLabel->setVisible(false); @@ -97,7 +98,7 @@ void DHTStatus::getDHTStatus() // YELLOW or GREEN. if (config.netDhtRsNetSize < MIN_RS_NET_SIZE) { - dhtstatusLabel->setPixmap(QPixmap(":/icons/bullet_yellow_64.png").scaledToHeight(S,Qt::SmoothTransformation)); + dhtstatusLabel->setPixmap(QPixmap(":/icons/bullet_yellow_128.png").scaledToHeight(S,Qt::SmoothTransformation)); dhtstatusLabel->setToolTip( text + tr("DHT Searching for RetroShare Peers")); spaceLabel->setVisible(true); @@ -109,7 +110,7 @@ void DHTStatus::getDHTStatus() } else { - dhtstatusLabel->setPixmap(QPixmap(":/icons/bullet_green_64.png").scaledToHeight(S,Qt::SmoothTransformation)); + dhtstatusLabel->setPixmap(QPixmap(":/icons/bullet_green_128.png").scaledToHeight(S,Qt::SmoothTransformation)); dhtstatusLabel->setToolTip( text + tr("DHT Good")); spaceLabel->setVisible(true); @@ -123,7 +124,7 @@ void DHTStatus::getDHTStatus() else { // RED - some issue. - dhtstatusLabel->setPixmap(QPixmap(":/icons/bullet_red_64.png").scaledToHeight(S,Qt::SmoothTransformation)); + dhtstatusLabel->setPixmap(QPixmap(":/icons/bullet_red_128.png").scaledToHeight(S,Qt::SmoothTransformation)); dhtstatusLabel->setToolTip( text + tr("DHT Error")); spaceLabel->setVisible(false); diff --git a/retroshare-gui/src/gui/statusbar/natstatus.cpp b/retroshare-gui/src/gui/statusbar/natstatus.cpp index f5bd7930d..9f80369db 100644 --- a/retroshare-gui/src/gui/statusbar/natstatus.cpp +++ b/retroshare-gui/src/gui/statusbar/natstatus.cpp @@ -63,14 +63,14 @@ void NATStatus::getNATStatus() default: case RSNET_NETSTATE_BAD_UNKNOWN: { - iconLabel->setPixmap(QPixmap(":/icons/bullet_yellow_64.png").scaledToHeight(S,Qt::SmoothTransformation)) ; + iconLabel->setPixmap(QPixmap(":/icons/bullet_yellow_128.png").scaledToHeight(S,Qt::SmoothTransformation)) ; iconLabel->setToolTip( text + tr("Network Status Unknown")) ; } break ; case RSNET_NETSTATE_BAD_OFFLINE: { - iconLabel->setPixmap(QPixmap(":/icons/bullet_grey_64.png").scaledToHeight(S,Qt::SmoothTransformation)) ; + iconLabel->setPixmap(QPixmap(":/icons/bullet_grey_129.png").scaledToHeight(S,Qt::SmoothTransformation)) ; iconLabel->setToolTip( text + tr("Offline")) ; } break ; @@ -78,14 +78,14 @@ void NATStatus::getNATStatus() // BAD. (RED) case RSNET_NETSTATE_BAD_NATSYM: { - iconLabel->setPixmap(QPixmap(":/icons/bullet_red_64.png").scaledToHeight(S,Qt::SmoothTransformation)) ; + iconLabel->setPixmap(QPixmap(":/icons/bullet_red_128.png").scaledToHeight(S,Qt::SmoothTransformation)) ; iconLabel->setToolTip( text + tr("Nasty Firewall")) ; } break ; case RSNET_NETSTATE_BAD_NODHT_NAT: { - iconLabel->setPixmap(QPixmap(":/icons/bullet_red_64.png").scaledToHeight(S,Qt::SmoothTransformation)) ; + iconLabel->setPixmap(QPixmap(":/icons/bullet_red_128.png").scaledToHeight(S,Qt::SmoothTransformation)) ; iconLabel->setToolTip( text + tr("DHT Disabled and Firewalled")) ; } break ; @@ -93,21 +93,21 @@ void NATStatus::getNATStatus() // CAUTION. (ORANGE) case RSNET_NETSTATE_WARNING_RESTART: { - iconLabel->setPixmap(QPixmap(":/icons/bullet_yellow_64.png").scaledToHeight(S,Qt::SmoothTransformation)) ; + iconLabel->setPixmap(QPixmap(":/icons/bullet_yellow_128.png").scaledToHeight(S,Qt::SmoothTransformation)) ; iconLabel->setToolTip( text + tr("Network Restarting")) ; } break ; case RSNET_NETSTATE_WARNING_NATTED: { - iconLabel->setPixmap(QPixmap(":/icons/bullet_yellow_64.png").scaledToHeight(S,Qt::SmoothTransformation)) ; + iconLabel->setPixmap(QPixmap(":/icons/bullet_yellow_128.png").scaledToHeight(S,Qt::SmoothTransformation)) ; iconLabel->setToolTip( text + tr("Behind Firewall")) ; } break ; case RSNET_NETSTATE_WARNING_NODHT: { - iconLabel->setPixmap(QPixmap(":/icons/bullet_yellow_64.png").scaledToHeight(S,Qt::SmoothTransformation)) ; + iconLabel->setPixmap(QPixmap(":/icons/bullet_yellow_128.png").scaledToHeight(S,Qt::SmoothTransformation)) ; iconLabel->setToolTip( text + tr("DHT Disabled")) ; } break ; @@ -115,14 +115,14 @@ void NATStatus::getNATStatus() // GOOD (GREEN) case RSNET_NETSTATE_GOOD: { - iconLabel->setPixmap(QPixmap(":/icons/bullet_green_64.png").scaledToHeight(S,Qt::SmoothTransformation)) ; + iconLabel->setPixmap(QPixmap(":/icons/bullet_green_128.png").scaledToHeight(S,Qt::SmoothTransformation)) ; iconLabel->setToolTip( text + tr("RetroShare Server")) ; } break ; case RSNET_NETSTATE_ADV_FORWARD: { - iconLabel->setPixmap(QPixmap(":/icons/bullet_green_64.png").scaledToHeight(S,Qt::SmoothTransformation)) ; + iconLabel->setPixmap(QPixmap(":/icons/bullet_green_128.png").scaledToHeight(S,Qt::SmoothTransformation)) ; iconLabel->setToolTip( text + tr("Forwarded Port")) ; } break ; diff --git a/retroshare-gui/src/lang/retroshare_en.ts b/retroshare-gui/src/lang/retroshare_en.ts index 7b60e33c7..7fcc06389 100644 --- a/retroshare-gui/src/lang/retroshare_en.ts +++ b/retroshare-gui/src/lang/retroshare_en.ts @@ -1,10 +1,10 @@ - + AWidget - + version @@ -23,12 +23,17 @@ - + About - + + Copy Info + + + + close @@ -1022,17 +1027,22 @@ p, li { white-space: pre-wrap; } - + Mute participant + + + Send Message + + Invite friends to this lobby - + Leave this lobby (Unsubscribe) @@ -1047,7 +1057,7 @@ p, li { white-space: pre-wrap; } - + Welcome to lobby %1 @@ -1063,7 +1073,7 @@ p, li { white-space: pre-wrap; } - + Lobby management @@ -1095,7 +1105,7 @@ p, li { white-space: pre-wrap; } - + Right click to mute/unmute participants<br/>Double click to address this person<br/> @@ -1110,12 +1120,12 @@ p, li { white-space: pre-wrap; } - + Start private chat - + Decryption failed. @@ -1161,7 +1171,7 @@ p, li { white-space: pre-wrap; } ChatLobbyUserNotify - + Chat Lobbies @@ -1200,18 +1210,18 @@ p, li { white-space: pre-wrap; } ChatLobbyWidget - + Chat lobbies - - + + Name - + Count @@ -1232,23 +1242,23 @@ p, li { white-space: pre-wrap; } - + Create chat lobby - + [No topic provided] - + Selected lobby info - + Private @@ -1258,12 +1268,12 @@ p, li { white-space: pre-wrap; } - + You're not subscribed to this lobby; Double click-it to enter and chat. - + Remove Auto Subscribe @@ -1273,32 +1283,37 @@ p, li { white-space: pre-wrap; } - + %1 invites you to chat lobby named %2 - + Search Chat lobbies - + Search Name - + Subscribed - + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Chat Lobbies</h1> <p>Chat lobbies are distributed chat rooms, and work pretty much like IRC. They allow you to talk anonymously with tons of people without the need to make friends.</p> <p>A chat lobby can be public (your friends see it) or private (your friends can't see it, unless you invite them with <img src=":/images/add_24x24.png" width=%2/>). Once you have been invited to a private lobby, you will be able to see it when your friends are using it.</p> <p>The list at left shows chat lobbies your friends are participating in. You can either <ul> <li>Right click to create a new chat lobby</li> <li>Double click a chat lobby to enter, chat, and show it to your friends</li> </ul> Note: For the chat lobbies to work properly, your computer needs be on time. So check your system clock! </p> - + + Create a non anonymous identity and enter this lobby + + + + Columns @@ -1313,7 +1328,7 @@ p, li { white-space: pre-wrap; } - + Lobby Name: @@ -1332,6 +1347,11 @@ p, li { white-space: pre-wrap; } Type: + + + Security: + + Peers: @@ -1342,19 +1362,20 @@ p, li { white-space: pre-wrap; } + TextLabel - + No lobby selected. Select lobbies at left to show details. Double click lobbies to enter and chat. - + Private Subscribed Lobbies @@ -1369,12 +1390,12 @@ Double click lobbies to enter and chat. - + Leave this lobby - + Enter this lobby @@ -1384,22 +1405,47 @@ Double click lobbies to enter and chat. - + + Default identity is anonymous + + + + + You cannot join this lobby with your default identity, since it is anonymous and the lobby forbids it. + + + + + No anonymous IDs + + + + + Anonymous ids accepted + + + + + You will need to create a non anonymous identity in order to join this chat lobby. + + + + You will need to create an identity in order to join chat lobbies. - + Choose an identity for this lobby: - + Create an identity and enter this lobby - + Show @@ -1461,12 +1507,12 @@ Double click lobbies to enter and chat. ChatPage - + General - + Chat Settings @@ -1491,7 +1537,12 @@ Double click lobbies to enter and chat. - + + Minimum font size + + + + Enable bold @@ -1605,7 +1656,7 @@ Double click lobbies to enter and chat. - + Incoming @@ -1763,7 +1814,7 @@ Double click lobbies to enter and chat. ChatStyle - + Standard style for group chat @@ -1812,17 +1863,17 @@ Double click lobbies to enter and chat. ChatWidget - + Close - + Send - + Bold @@ -1837,12 +1888,12 @@ Double click lobbies to enter and chat. - + Attach a Picture - + Strike @@ -1893,7 +1944,7 @@ Double click lobbies to enter and chat. - + is typing... @@ -1970,7 +2021,7 @@ Double click lobbies to enter and chat. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -1985,12 +2036,12 @@ Double click lobbies to enter and chat. - + (Status) - + Set text font & color @@ -2000,7 +2051,7 @@ Double click lobbies to enter and chat. - + WARNING: Could take a long time on big history. @@ -2011,7 +2062,7 @@ Double click lobbies to enter and chat. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> @@ -2046,12 +2097,12 @@ Double click lobbies to enter and chat. - + Type a message here - + Don't stop to color after @@ -2061,7 +2112,7 @@ Double click lobbies to enter and chat. - + Warning: @@ -2435,17 +2486,7 @@ Double click lobbies to enter and chat. - - This wizard will help you to connect to your friend(s) to RetroShare network.<br>These ways are possible to do this: - - - - - &Enter the certificate manually - - - - + &You get a certificate file from your friend @@ -2455,18 +2496,7 @@ Double click lobbies to enter and chat. - - &Enter RetroShare ID manually - - - - - &Send an Invitation by Email - (She/He receives an email with instructions how to to download RetroShare) - - - - + Text certificate @@ -2482,7 +2512,7 @@ Double click lobbies to enter and chat. - + Include signatures @@ -2502,12 +2532,7 @@ Double click lobbies to enter and chat. - - Please, paste your friends PGP certificate into the box below - - - - + Certificate files @@ -2588,6 +2613,41 @@ Double click lobbies to enter and chat. + RetroShare is better with Friends + + + + + Invite your Friends from other Networks to RetroShare. + + + + + GMail + + + + + Yahoo + + + + + Outlook + + + + + AOL + + + + + Yandex + + + + Invite Friends by Email @@ -2613,7 +2673,7 @@ Double click lobbies to enter and chat. - + Friend request @@ -2627,65 +2687,107 @@ Double click lobbies to enter and chat. - + Peer details - - + + Name: - - + + Email: - + Node: - + + Please note that RetroShare will require excessive amounts of bandwidth, memory and CPU if you add too many friends. You can add as many friends as you like, but more than 40 will probably require too much +resources. + + + + Location: - + - + Options - - + + This wizard will help you to connect to your friend(s) to RetroShare network.<br>Select how you would like to add a friend: + + + + + Enter the certificate manually + + + + + Enter RetroShare ID manually + + + + + &Send an Invitation by Web Mail Providers + + + + + &Send an Invitation by Email + (Your friend will receive an email with instructions how to to download RetroShare) + + + + + Recommend many friends to each other + + + + + Please, paste your friend's PGP certificate into the box below + + + + + Add friend to group: - - + + Authenticate friend (Sign PGP Key) - - + + Add as friend to connect with - - + + To accept the Friend Request, click the Finish button. - + Sorry, some error appeared @@ -2705,7 +2807,7 @@ Double click lobbies to enter and chat. - + Key validity: @@ -2761,12 +2863,12 @@ Double click lobbies to enter and chat. - + Certificate Load Failed - + Cannot get peer details of PGP key %1 @@ -2801,12 +2903,13 @@ Double click lobbies to enter and chat. - + + RetroShare Invitation - + Ultimate @@ -2832,7 +2935,7 @@ Double click lobbies to enter and chat. - + You have a friend request from @@ -2847,7 +2950,7 @@ Double click lobbies to enter and chat. - + Use new certificate format (safer, more robust) @@ -2945,13 +3048,22 @@ Double click lobbies to enter and chat. - + Use as direct source, when available - - + + IP-Addr: + + + + + IP-Address + + + + Recommend many friends to each others @@ -2966,7 +3078,7 @@ Double click lobbies to enter and chat. - + Recommend friends @@ -2986,17 +3098,12 @@ Double click lobbies to enter and chat. - - Please note that RetroShare will require excessive amounts of bandwidth, memory and CPU if you add to many friends. You can add as many friends as you like, but more than 40 will probably require too much resources. - - - - + Add key to keyring - + This key is already in your keyring @@ -3009,7 +3116,7 @@ even if you don't make friends. - + Certificate has wrong version number. Remember that v0.6 and v0.5 networks are incompatible. @@ -3019,8 +3126,8 @@ even if you don't make friends. - - + + Auto-download recommended files @@ -3030,8 +3137,8 @@ even if you don't make friends. - - + + Require whitelist clearance to connect @@ -3041,7 +3148,7 @@ even if you don't make friends. - + No IP in this certificate! @@ -3051,17 +3158,17 @@ even if you don't make friends. - + Added with certificate from %1 - + Paste Cert of your friend from Clipboard - + Certificate Load Failed:can't read from file %1 @@ -4052,7 +4159,7 @@ Do you want to reject this message? - Security policy: + Visibility: @@ -4066,7 +4173,22 @@ Do you want to reject this message? - + + <html><head/><body><p>If you check this, only PGP-signed ids can be used to join and talk in this lobby. This limitation prevents anonymous spamming as it becomes possible for at least some people in the lobby to locate the spammer's node.</p></body></html> + + + + + require PGP-signed identities + + + + + Security: + + + + Select the Friends with which you want to group chat. @@ -4076,12 +4198,22 @@ Do you want to reject this message? - + + Put a sensible lobby name here + + + + + Set a descriptive topic here + + + + Contacts: - + Identity to use: @@ -4390,7 +4522,7 @@ Do you want to reject this message? - + Name @@ -4506,7 +4638,17 @@ Do you want to reject this message? - + + IP + + + + + Search IP + + + + Unknown NetState @@ -4745,19 +4887,19 @@ Do you want to reject this message? - + %1 secs ago - + %1B/s - + 0x%1 EX:0x%2 @@ -4767,7 +4909,7 @@ Do you want to reject this message? - + DHT @@ -4844,7 +4986,7 @@ Do you want to reject this message? - + Filter: @@ -4869,7 +5011,7 @@ Do you want to reject this message? - + Proxy VIA @@ -5358,7 +5500,7 @@ you plug it in. FriendList - + Last Contact @@ -5368,39 +5510,39 @@ you plug it in. - - State + + export friendlist - Sort by State + export your friendlist including groups - + + import friendlist + + + + + import your friendlist including groups + + + + Show State - - Name - - - - - Sort by Name - - - - + Show Groups - + Group @@ -5441,12 +5583,17 @@ you plug it in. - + Search - + + Sort by state + + + + Move to group @@ -5476,22 +5623,103 @@ you plug it in. - + Available - + Do you want to remove this Friend? - + + + Done! + + + + + Your friendlist is stored at: + + + + + + +(keep in mind that the file is unencrypted!) + + + + + + Your friendlist was imported from: + + + + + + Done - but errors happened! + + + + + +at least one peer was not added + + + + + +at least one peer was not added to a group + + + + + Select file for importing yoour friendlist from + + + + + Select a file for exporting your friendlist to + + + + + XML File (*.xml);;All Files (*) + + + + + + + Error + + + + + Failed to get a file! + + + + + File is not writeable! + + + + + + File is not readable! + + + + + IP - + Attempt to connect @@ -5501,7 +5729,7 @@ you plug it in. - + Display @@ -5511,12 +5739,7 @@ you plug it in. - - Sort by - - - - + Node @@ -5526,17 +5749,17 @@ you plug it in. - + Do you want to remove this node? - + Friend nodes - + Send message to whole group @@ -5584,25 +5807,30 @@ you plug it in. - - All + + Sort by state - None - - - - Name - + Search Friends + + + Mark all + + + + + Mark none + + FriendsDialog @@ -5846,12 +6074,7 @@ anonymous, you can use a fake email. - - Please enter a valid address of the form: 31769173498.onion:7800 - - - - + Node field is required with a minimum of 3 characters @@ -5919,7 +6142,12 @@ Alternatively you can use an existing profile. Just uncheck "Create a new p - + + hidden address + + + + Your profile is associated with a PGP key pair. RetroShare currently ignores DSA keys. @@ -5935,7 +6163,12 @@ Alternatively you can use an existing profile. Just uncheck "Create a new p - + + <html><head/><body><p>This can be a Tor Onion address of the form: xa76giaf6ifda7ri63i263.onion <br/>or an I2P address in the form: [52 characters].b32.i2p </p><p>In order to get one, you must configure either Tor or I2P to create a new hidden service / server tunnel. If you do not yet have one, you can still go on, and make it right later in Retroshare's Options-&gt;Server-&gt;Hidden Service configuration panel.</p></body></html> + + + + PGP key length @@ -5957,7 +6190,12 @@ Alternatively you can use an existing profile. Just uncheck "Create a new p - + + [Required] Tor/I2P address - Examples: xa76giaf6ifda7ri63i263.onion (obtained by you from Tor) + + + + [Required] This password protects your private PGP key. @@ -6067,7 +6305,12 @@ and use the import button to load it - + + Please enter a valid address of the form: 31769173498.onion:7800 or [52 characters].b32.i2p + + + + PGP key pair generation failure @@ -6096,21 +6339,6 @@ Fill in your PGP password when asked, to sign your new key. You can create a new profile with this form. - - - Tor address - - - - - <html><head/><body><p>This is a Tor Onion address of the form: xa76giaf6ifda7ri63i263.onion </p><p>In order to get one, you must configure Tor to create a new hidden service. If you do not yet have one, you can still go on, and make it right later in Retroshare's Options-&gt;Server-&gt;Tor configuration panel.</p></body></html> - - - - - [Required] Examples: xa76giaf6ifda7ri63i263.onion (obtained by you from Tor) - - GeneralPage @@ -6430,70 +6658,85 @@ p, li { white-space: pre-wrap; } - + + GroupBox + + + + + ID + + + + + Destinaton + + + + + Data status + + + + + Tunnel status + + + + + Data size + + + + + Data hash + + + + + Received + + + + + Send + + + + Unknown Peer + + + Pending packets + + + + + Unknown + + GlobalRouterStatisticsWidget - - Pending packets - - - - + Managed keys - + Routing matrix ( - - Id + + Friend Order ( - - Destination - - - - - Data status - - - - - Tunnel status - - - - - Data size - - - - - Data hash - - - - - Received - - - - - Send - - - - + : Service ID = @@ -7586,7 +7829,7 @@ before you can comment - + Title @@ -7599,13 +7842,13 @@ before you can comment - + Author - + Loading @@ -7635,7 +7878,7 @@ before you can comment - + Search Title @@ -7660,7 +7903,7 @@ before you can comment - + No name @@ -7671,6 +7914,16 @@ before you can comment + Ban this author + + + + + This will block/hide messages from this person, and notify neighbor nodes. + + + + Start New Thread @@ -7708,7 +7961,7 @@ before you can comment - + Hide @@ -7718,7 +7971,17 @@ before you can comment - + + [Banned] + + + + + [ ... Redacted message ... ] + + + + Anonymous @@ -7738,19 +8001,41 @@ before you can comment - - + + <p><font color="#ff0000"><b>The author of this message (with ID %1) is banned.</b> + + + + + <UL><li><b><font color="#ff0000">Messages from this author are not forwarded. </font></b></li> + + + + + <li><b><font color="#ff0000">Messages from this author are replaced by this text. </font></b></li></ul> + + + + + <p><b><font color="#ff0000">You can force the visibility and forwarding of messages by setting a different opinion for that Id in People's tab.</font></b></p> + + + + + + RetroShare - + No Forum Selected! - + + You cant reply to a non-existant Message @@ -7760,7 +8045,7 @@ before you can comment - + Original Message @@ -7785,7 +8070,7 @@ before you can comment - + Forum name @@ -7810,12 +8095,12 @@ before you can comment - + <p>Subscribing to the forum will gather available posts from your subscribed friends, and make the forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p> - + Reply with private message @@ -8123,7 +8408,7 @@ before you can comment - + Unsubscribe @@ -8163,12 +8448,12 @@ before you can comment - + AUTHD - + Share admin permissions @@ -8176,7 +8461,7 @@ before you can comment GxsIdChooser - + No Signature @@ -8189,7 +8474,7 @@ before you can comment GxsIdDetails - + Loading @@ -8204,8 +8489,15 @@ before you can comment - + + + + [Banned] + + + + Authentication @@ -8220,7 +8512,7 @@ before you can comment - + Identity&nbsp;name @@ -8235,7 +8527,7 @@ before you can comment - + [Unknown] @@ -8558,7 +8850,7 @@ p, li { white-space: pre-wrap; } IdDetailsDialog - + Person Details @@ -8593,78 +8885,88 @@ p, li { white-space: pre-wrap; } - + + Last used: + + + + Your Avatar Click here to change your avatar - + Reputation - - Overall + + <html><head/><body><p>Average opinion of neighbor nodes about this identity. Negative is bad,</p><p>positive is good. Zero is neutral.</p></body></html> - - Implicit - - - - - Opinion - - - - - Peers - - - - - Edit Reputation - - - - - Tweak Opinion - - - - - Accept (+100) + + Your opinion: - Positive (+10) + Neighbor nodes: - Negative (-10) + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Your own opinion about an identity rules the visibility of that identity for yourself,</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">and is shared among friends. A final score is calculated according to a formula that accounts your own opinion and your friends' opinions about someone:</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> S = own_opinion * a + friends_opinion * (1-a)</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The factor 'a' depends on the type of ID. </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- anonymous IDs: </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- PGP-signed IDs by unknown PGP keys: a=</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The overall score is used in chat lobbies, forums and channels to decide on the actions to take for each specific identity:</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; -0.5: Posts are not stored, nor forwarded </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; 0.2: Posts are hidden, but still transmitted</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; 0.0: </p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The overall rating is computed in such a way that it is not possible for a single person to deterministically change someone's status at neighbor nodes.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> - - Ban (-100) + + Negative - Custom + Neutral - - Modify + + Positive - + + <html><head/><body><p>Overall reputation score, accounting for yours and your friends'.</p><p>Negative is bad, positive is good. Zero is neutral. If the score is too low,</p><p>the identity is flagged as bad, and will be filtered out in forums, chat lobbies,</p><p>channels, etc.</p></body></html> + + + + + Overall: + + + + Unknown real name @@ -8703,6 +9005,31 @@ p, li { white-space: pre-wrap; } Anonymous identity + + + +50 Known PGP + + + + + +10 UnKnown PGP + + + + + +5 Anon Id + + + + + OK + + + + + Banned + + IdDialog @@ -8712,17 +9039,18 @@ p, li { white-space: pre-wrap; } - + All - + + Reputation - + Todo @@ -8733,7 +9061,7 @@ p, li { white-space: pre-wrap; } - + Unknown real name @@ -8748,67 +9076,7 @@ p, li { white-space: pre-wrap; } - - Overall - - - - - Implicit - - - - - Opinion - - - - - Peers - - - - - Edit reputation - - - - - Tweak Opinion - - - - - Accept (+100) - - - - - Positive (+10) - - - - - Negative (-10) - - - - - Ban (-100) - - - - - Custom - - - - - Modify - - - - + Edit identity @@ -8829,27 +9097,27 @@ p, li { white-space: pre-wrap; } - + Identity name - + Owner node ID : - + Identity name : - + Identity ID - + Send message @@ -8859,12 +9127,12 @@ p, li { white-space: pre-wrap; } - + Identity ID : - + Owner node name : @@ -8874,7 +9142,72 @@ p, li { white-space: pre-wrap; } - + + <html><head/><body><p>Average opinion of neighbor nodes about this identity. Negative is bad,</p><p>positive is good. Zero is neutral.</p></body></html> + + + + + Your opinion: + + + + + Neighbor nodes: + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Your own opinion about an identity rules the visibility of that identity for yourself,</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">and is shared among friends. A final score is calculated according to a formula that accounts your own opinion and your friends' opinions about someone:</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> S = own_opinion * a + friends_opinion * (1-a)</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The factor 'a' depends on the type of ID. </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- anonymous IDs: </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- PGP-signed IDs by unknown PGP keys: a=</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The overall score is used in chat lobbies, forums and channels to decide on the actions to take for each specific identity:</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; -0.5: Posts are not stored, nor forwarded </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; 0.2: Posts are hidden, but still transmitted</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; 0.0: </p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The overall rating is computed in such a way that it is not possible for a single person to deterministically change someone's status at neighbor nodes.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + Negative + + + + + Neutral + + + + + Positive + + + + + <html><head/><body><p>Overall reputation score, accounting for yours and your friends'.</p><p>Negative is bad, positive is good. Zero is neutral. If the score is too low,</p><p>the identity is flagged as bad, and will be filtered out in forums, chat lobbies,</p><p>channels, etc.</p></body></html> + + + + + Overall: + + + + Owned by you @@ -8884,7 +9217,7 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you @@ -8900,7 +9233,7 @@ p, li { white-space: pre-wrap; } - + Identity owned by you, linked to your Retroshare node @@ -8915,7 +9248,17 @@ p, li { white-space: pre-wrap; } - + + OK + + + + + Banned + + + + Distant chat cannot work @@ -8925,15 +9268,15 @@ p, li { white-space: pre-wrap; } - - - + + + People - + Your Avatar Click here to change your avatar @@ -8954,12 +9297,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit pseudo-anonymous identities. </p> <p>Identities are used to securely identify your data: sign forum and channel posts, and receive feedback using Retroshare built-in email system, post comments after channel posts, etc.</p> <p> Identities can optionally be signed by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address. </p> <p> Anonymous identities allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity. </p> - + Linked to a friend Retroshare node @@ -8974,7 +9317,7 @@ p, li { white-space: pre-wrap; } - + Chat with this person @@ -8989,12 +9332,7 @@ p, li { white-space: pre-wrap; } - - Columns - - - - + Distant chat refused with this person. @@ -9004,7 +9342,7 @@ p, li { white-space: pre-wrap; } - + +50 Known PGP @@ -9019,29 +9357,17 @@ p, li { white-space: pre-wrap; } - + Do you really want to delete this identity? - + Owned by - - - Show - - - - - - column - - - - + Node name: @@ -9051,7 +9377,7 @@ p, li { white-space: pre-wrap; } - + Really delete? @@ -9103,7 +9429,7 @@ p, li { white-space: pre-wrap; } - + @@ -9113,13 +9439,13 @@ p, li { white-space: pre-wrap; } - + Edit identity - + Error getting key! @@ -9139,7 +9465,7 @@ p, li { white-space: pre-wrap; } - + Create New Identity @@ -9194,7 +9520,7 @@ p, li { white-space: pre-wrap; } - + The nickname is too short. Please input at least %1 characters. @@ -9256,13 +9582,13 @@ p, li { white-space: pre-wrap; } ImHistoryBrowser - + Message History - + Copy @@ -9592,7 +9918,7 @@ p, li { white-space: pre-wrap; } MessageComposer - + Compose @@ -9715,7 +10041,7 @@ p, li { white-space: pre-wrap; } - + Tags @@ -9851,12 +10177,12 @@ p, li { white-space: pre-wrap; } - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -9867,7 +10193,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -9887,12 +10213,7 @@ Do you want to save message to draft box? - - Friend Details - - - - + Original Message @@ -10071,7 +10392,12 @@ Do you want to save message to draft box? - + + Details + + + + Open File... @@ -10133,7 +10459,7 @@ Do you want to save message ? - + All @@ -10143,12 +10469,7 @@ Do you want to save message ? - - Person Details - - - - + Distant peer identities @@ -10198,7 +10519,7 @@ Do you want to save message ? - + Distant identity: @@ -11018,7 +11339,12 @@ Do you want to save message ? MimeTextEdit - + + Paste as plain text + + + + Paste RetroShare Link @@ -11252,7 +11578,7 @@ Do you want to save message ? - + Deny friend @@ -11310,7 +11636,7 @@ For security, your keyring was previously backed-up to file - + Personal signature @@ -11376,7 +11702,7 @@ Right-click and select 'make friend' to be able to connect. - + Data inconsistency in the keyring. This is most probably a bug. Please contact the developers. @@ -11391,7 +11717,7 @@ Right-click and select 'make friend' to be able to connect. - + Trust level @@ -11411,12 +11737,12 @@ Right-click and select 'make friend' to be able to connect. - + Make friend... - + Did peer authenticate you @@ -11446,7 +11772,7 @@ Right-click and select 'make friend' to be able to connect. - + Key removal has failed. Your keyring remains intact. Reported error: @@ -11775,7 +12101,7 @@ Reported error: NotifyQt - + PGP key passphrase @@ -11815,7 +12141,7 @@ Reported error: - + Test @@ -11830,13 +12156,13 @@ Reported error: - - + + Encrypted message - + Please enter your PGP password for key @@ -12631,18 +12957,18 @@ p, li { white-space: pre-wrap; } - - Loaded plugins - - - - + Plugin look-up directories - - Hash rejected. Enable it manually and restart, if you need. + + Plugin disabled. Click the enable button and restart Retroshare + + + + + [disabled] @@ -12651,27 +12977,36 @@ p, li { white-space: pre-wrap; } - + + + + + + [loading problem] + + + + No SVN number supplied. Please read plugin development manual. - + Loading error. - + Missing symbol. Wrong version? - + No plugin object - + Plugins is loaded. @@ -12681,22 +13016,7 @@ p, li { white-space: pre-wrap; } - - Title unavailable - - - - - Description unavailable - - - - - Unknown version - - - - + Check this for developing plugins. They will not be checked for the hash. However, in normal times, checking the hash protects you from @@ -12709,6 +13029,7 @@ malicious behavior of crafted plugins. + Plugins @@ -12780,7 +13101,7 @@ malicious behavior of crafted plugins. PopupDistantChatDialog - + The person you're talking to has deleted the secured chat tunnel. You may remove the chat window now. @@ -13508,7 +13829,8 @@ p, li { white-space: pre-wrap; } QObject - + + Confirmation @@ -13518,7 +13840,7 @@ p, li { white-space: pre-wrap; } - + Click to add this RetroShare cert to your PGP keyring and open the Make Friend Wizard. @@ -13545,7 +13867,12 @@ and open the Make Friend Wizard. - + + This file already exists. Do you want to open it ? + + + + %1 of %2 RetroShare link processed. @@ -13815,7 +14142,7 @@ Reported error is: - + Click to send a private message to %1 (%2). @@ -13875,7 +14202,7 @@ Reported error is: - + enabled @@ -13885,12 +14212,18 @@ Reported error is: - + + +Security: no anonymous ids + + + + Join chat lobby - + Move IP %1 to whitelist @@ -13905,42 +14238,49 @@ Reported error is: - + + %1 seconds ago + %1 minute ago + %1 minutes ago + %1 hour ago + %1 hours ago + %1 day ago + %1 days ago - + Subject: @@ -13970,6 +14310,16 @@ Reported error is: The following has not been added to your download list, because you already have it: + + + Error + + + + + unable to parse XML file! + + QuickStartWizard @@ -13979,7 +14329,7 @@ Reported error is: - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -14001,21 +14351,23 @@ p, li { white-space: pre-wrap; } - - + + + Next > - - - - + + + + + Exit - + For best performance, RetroShare needs to know a little about your connection to the internet. @@ -14082,13 +14434,14 @@ p, li { white-space: pre-wrap; } - - + + + < Back - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -14106,7 +14459,7 @@ p, li { white-space: pre-wrap; } - + Network Wide @@ -14131,7 +14484,27 @@ p, li { white-space: pre-wrap; } - + + RetroShare Page Display Style + + + + + Where do you want to have the buttons for the page? + + + + + ToolBar View + + + + + List View + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -14266,7 +14639,7 @@ p, li { white-space: pre-wrap; } RSPermissionMatrixWidget - + Allowed by default @@ -14789,7 +15162,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsHtml - + Image is oversized for transmission. Reducing image to %1x%2 pixels? @@ -15078,7 +15451,7 @@ Reducing image to %1x%2 pixels? - + Download @@ -15147,7 +15520,7 @@ Reducing image to %1x%2 pixels? - + Create Collection... @@ -15167,7 +15540,7 @@ Reducing image to %1x%2 pixels? - + Collection @@ -15410,12 +15783,22 @@ Reducing image to %1x%2 pixels? ServerPage - + Network Configuration - + + Network Mode + + + + + Nat + + + + Automatic (UPnP) @@ -15430,7 +15813,7 @@ Reducing image to %1x%2 pixels? - + Public: DHT & Discovery @@ -15450,13 +15833,13 @@ Reducing image to %1x%2 pixels? - - + + Local Address - + External Address @@ -15466,28 +15849,28 @@ Reducing image to %1x%2 pixels? - + Port: - + Local network - + External ip address finder - + UPnP - + Known / Previous IPs: @@ -15510,13 +15893,13 @@ behind a firewall or a VPN. - - + + kB/s - + Acceptable ports range from 10 to 65535. Normally Ports below 1024 are reserved by your system. @@ -15526,23 +15909,12 @@ behind a firewall or a VPN. - + Onion Address - - Expected torrc Port Configuration: - - - - - HiddenServiceDir </your/path/to/hidden/directory/service> -HiddenServicePort 9191 127.0.0.1:9191 - - - - + Discovery On (recommended) @@ -15552,17 +15924,65 @@ HiddenServicePort 9191 127.0.0.1:9191 - + + Hidden - See Config + + + + + I2P Address + + + + + I2P incoming ok + + + + + Points at: + + + + + Tor incoming ok + + + + + incoming ok + + + + + Proxy seems to work. - + + I2P proxy is not enabled + + + + + You are reachable through the hidden service. + + + + + The proxy is not enabled or broken. +Are all services up and running fine?? +Also check your ports! + + + + [Hidden mode] - + <html><head/><body><p>This clears the list of known addresses. This action is useful if for some reason your address list contains an invalid/irrelevant/expired address that you want to avoid passing to your friends as a contact address.</p></body></html> @@ -15572,98 +15992,90 @@ HiddenServicePort 9191 127.0.0.1:9191 - + Download limit (KB/s) - + <html><head/><body><p>This download limit covers the whole application. However, in some situations, such as when transfering many small files at once, the estimated bandwidth becomes unreliable and the total value reported by Retroshare might exceed that limit. </p></body></html> - + Upload limit (KB/s) - + <html><head/><body><p>The upload limit covers the entire software. Too small an upload limit might eventually block low priority services (forums, channels). A minimum recommended value is 50KB/s. </p></body></html> - - Tor Socks Proxy default: 127.0.0.1:9050. Set in torrc config and update here. - -You can connect to Hidden Nodes, even if you -are running a standard Node, so why not setup Tor? - - - - + Test - + Network - + IP Filters - + IP blacklist - + IP range - - - + + + Status - - + + Origin - - + + Reason - - + + Comment - + IPs - + IP whitelist - + Manual input @@ -15688,12 +16100,98 @@ are running a standard Node, so why not setup Tor? - + + Hidden Service Configuration + + + + + Outgoing Connections + + + + + I2P Socks Proxy + + + + + I2P outgoing Okay + + + + + Tor Socks Proxy default: 127.0.0.1:9050. Set in torrc config and update here. + +I2P Socks Proxy: see http://127.0.0.1:7657/i2ptunnelmgr for setting up a client tunnel: +Tunnel Wizard -> Client Tunnel -> SOCKS 4/4a/5 -> enter a name -> leave 'Outproxies' empty -> enter port (memorize!) [you may also want to set the reachability to 127.0.0.1] -> check 'Auto Start' -> finish! +Now enter the address (e.g. 127.0.0.1) and the port you've picked before for the I2P Proxy. + +You can connect to Hidden Nodes, even if you are running a standard Node, so why not setup Tor and/or I2P? + + + + + Incoming Service Connections + + + + + <html><head/><body><p>This button simulates a SSL connection to your hidden address using the corresponding proxy. If your hidden node is reachable, it should cause a SSL handshake error, which RS will interpret as a valid connection state. This operation might also cause several &quot;security warning&quot; about connections from your local host IP (127.0.0.1) in the News Feed if you enabled it,</p></body></html> + + + + + + Service Address + + + + + <html><head/><body><p>This is your hidden address. It should look like <span style=" font-weight:600;">[something].onion</span> or <span style=" font-weight:600;">[something].b32.i2p. </span>If you configured a hidden service with Tor, the onion address is generated automatically by Tor. You can get it in e.g. <span style=" font-weight:600;">/var/lib/tor/[service name]/hostname</span>. For I2P: Setup a server tunnel ( http://127.0.0.1:7657/i2ptunnelmgr ) and copy it's base32 address when it is started (should end with .b32.i2p)</p></body></html> + + + + + <html><head/><body><p>This is the local address to which the hidden service points at your localhost. Most of the time, <span style=" font-weight:600;">127.0.0.1</span> is the right answer.</p></body></html> + + + + + incoming ok + + + + + Expected Configuration: + + + + + Please fill in a service address + + + + + To Receive Connections, you must first setup a Tor/I2P Hidden Service. +For Tor: See torrc and documentation for HOWTO details. +For I2P: See http://127.0.0.1:7657/i2ptunnelmgr for setting up a server tunnel: +Tunnel Wizard -> Server Tunnel -> Standard -> enter a name -> enter the address and port your RS is using (see Local Address above) -> check 'Auto Start' -> finish! + +Once this is done, paste the Onion/I2P (Base32) Address in the box above. +This is your external address on the Tor/I2P network. +Finally make sure that the Ports match the configuration. + +If you have issues connecting over Tor check the Tor logs too. + + + + IP Range - + Reported by DHT for IP masquerading @@ -15716,32 +16214,33 @@ are running a standard Node, so why not setup Tor? - + <html><head/><body><p>White listed IPs are gathered from the following sources: IPs coming inside a manually exchanged certificate, IP ranges entered by you in this window, or in the security feed items.</p><p>The default behavior for Retroshare is to (1) always allow connection to peers with IP in the whitelist, even if that IP is also blacklisted; (2) optionally require IPs to be in the whitelist. You can change this behavior for each peer in the &quot;Details&quot; window of each Retroshare node. </p></body></html> - + <html><head/><body><p>The DHT allows you to answer connection requests from your friends using BitTorrent's DHT. It greatly improves the connectivity. No information is actually stored in the DHT. It is only used as a proxy system to get in touch with other Retroshare nodes.</p><p>The Discovery service sends node name and ids of your trusted contacts to connected peers, to help them choose new friends. The friendship is never automatic however, and both peers still need to trust each other to allow connection. </p></body></html> - + + <html><head/><body><p>The bullet turns green as soon as Retroshare manages to get your own IP from the websites listed below, if you enabled that action. Retroshare will also use other means to find out your own IP.</p></body></html> - + <html><head/><body><p>This list gets automatically filled with information gathered at multiple sources: masquerading peers reported by the DHT, IP ranges entered by you, and IP ranges reported by your friends. Default settings should protect you against large scale traffic relaying.</p><p>Automatically guessing masquerading IPs can put your friends IPs in the blacklist. In this case, use the context menu to whitelist them.</p></body></html> - + activate IP filtering - + <html><head/><body><p>This is very drastic, be careful. Since masquerading IPs might be actual real IPs, this option might cause disconnection, and will probably force you to add your friends' IPs into the whitelist.</p></body></html> @@ -15771,22 +16270,7 @@ are running a standard Node, so why not setup Tor? - - <html><head/><body><p>This Retroshare node is running in &quot;Hidden Mode&quot;. That means it can only be reached though the Tor network.</p><p>As such, some network options are disabled.</p></body></html> - - - - - Tor Configuration - - - - - Outgoing Tor Connections - - - - + Tor Socks Proxy @@ -15796,66 +16280,10 @@ are running a standard Node, so why not setup Tor? - - Incoming Tor Connections - - - - - <html><head/><body><p>This button simulates a SSL connection to your Tor address using the Tor proxy. If your Tor node is reachable, it should cause a SSL handshake error, which RS will interpret as a valid connection state. This operation might also cause several "security warning" about connections from your local host IP (127.0.0.1) in the News Feed if you enabled it,</p></body></html> - - - - - <html><head/><body><p>This is your onion address. It should look like <span style=" font-weight:600;">[something].onion. </span>If you configured a hidden service with Tor, the onion address is generated automatically by Tor. You can get it in e.g. <span style=" font-weight:600;">/var/lib/tor/[service name]/hostname</span></p></body></html> - - - - - <html><head/><body><p>This is the local address to which the Tor hidden service points at your localhost. Most of the time, <span style=" font-weight:600;">127.0.0.1</span> is the right answer.</p></body></html> - - - - - Tor incoming ok - - - - - To Receive Connections, you must first setup a Tor Hidden Service. -See Tor documentation for HOWTO details. - -Once this is done, paste the Onion Address in the box above. -This is your external address on the Tor network. -Finally make sure that the Ports match the Tor configuration. - -If you have issues connecting over Tor check the Tor logs too. - - - - - Hidden - See Tor Config - - - - + Tor proxy is not enabled - - - - You are reachable through Tor. - - - - - - Tor proxy is not enabled or broken. -Are you running a Tor hidden service? -Check your ports! - - ServicePermissionDialog @@ -15888,7 +16316,7 @@ Check your ports! ServicePermissionsPage - + ServicePermissions @@ -15908,8 +16336,8 @@ Check your ports! - - <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;Permissions</h1> <p>Permissions allow you to control which services are available to which friends</p> <p>Each interruptor shows two lights, indicating whether you or your friend has enabled that service. Both needs to be ON (showing <img height=20 src=":/images/switch11.png"/>) to let information transfer for a specific service/friend combination.</p> <p>For each service, the global switch <img height=20 src=":/images/global_switch_on.png"> / <img height=20 src=":/images/global_switch_off.png"> allow to turn a service ON/OFF for all friends at once.</p> <p>Be very careful: Some services depend on each other. For instance turning turtle OFF will also stop all anonymous transfer, distant chat and distant messaging.</p> + + <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;Permissions</h1> <p>Permissions allow you to control which services are available to which friends.</p> <p>Each interruptor shows two lights, indicating whether you or your friend has enabled that service. Both need to be ON (showing <img height=20 src=":/images/switch11.png"/>) to let information transfer for a specific service/friend combination.</p> <p>For each service, the global switch <img height=20 src=":/images/global_switch_on.png"> / <img height=20 src=":/images/global_switch_off.png"> allows you to turn a service ON/OFF for all friends at once.</p> <p>Be very careful: Some services depend on each other. For instance turning turtle OFF will also stop all anonymous transfer, distant chat and distant messaging.</p> @@ -16237,7 +16665,7 @@ Select the Friends with which you want to Share your Channel. SoundManager - + Friend @@ -16578,12 +17006,12 @@ This choice can be reverted in settings. - + Connected - + Unreachable @@ -16599,18 +17027,18 @@ This choice can be reverted in settings. - + Trying TCP - - + + Trying UDP - + Connected: TCP @@ -16621,6 +17049,11 @@ This choice can be reverted in settings. + Connected: I2P + + + + Connected: Unknown @@ -16630,7 +17063,7 @@ This choice can be reverted in settings. - + TCP-in @@ -16640,7 +17073,7 @@ This choice can be reverted in settings. - + inbound connection @@ -16650,7 +17083,7 @@ This choice can be reverted in settings. - + UDP @@ -16664,13 +17097,23 @@ This choice can be reverted in settings. Tor-out + + + I2P-in + + + + + I2P-out + + unkown - + Connected: Tor @@ -18026,7 +18469,7 @@ Try to be patient! - <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;Webinterface</h1> <p>The webinterface allows to control Retroshare from the browser. Multiple devices can share control over one Retroshare instance. So you could start a conversation on a tablet computer and later use a desktop computer to continue it.</p> <p>Warning: don't expose the webinterface to the internet, because there is no access control and no encryption. If you want to use the webinterface over the internet, use a SSH tunnel or a proxy to secure the connection.</p> + <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;Webinterface</h1> <p>The webinterface allows you to control Retroshare from the browser. Multiple devices can share control over one Retroshare instance. So you could start a conversation on a tablet computer and later use a desktop computer to continue it.</p> <p>Warning: don't expose the webinterface to the internet, because there is no access control and no encryption. If you want to use the webinterface over the internet, use a SSH tunnel or a proxy to secure the connection.</p> @@ -18238,7 +18681,7 @@ Try to be patient! - + My Groups @@ -18258,7 +18701,7 @@ Try to be patient! - + Subscribe to Group diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index 9727227e1..32dc37b2c 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -1,8 +1,10 @@ !include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri") +TEMPLATE = app QT += network xml CONFIG += qt gui uic qrc resources idle bitdht CONFIG += link_prl +TARGET = RetroShare06 # Plz never commit the .pro with these flags enabled. # Use this flag when developping new features only. @@ -30,24 +32,10 @@ CONFIG += gxschannels CONFIG += posted CONFIG += gxsgui -# Gxs is always enabled now. - -DEFINES += RS_ENABLE_GXS - -unfinished { - CONFIG += gxscircles - CONFIG += gxsthewire - CONFIG += gxsphotoshare - CONFIG += wikipoos -} - # Other Disabled Bits. #CONFIG += framecatcher #CONFIG += blogs -TEMPLATE = app -TARGET = RetroShare06 - DEFINES += RS_RELEASE_VERSION RCC_DIR = temp/qrc UI_DIR = temp/ui @@ -72,18 +60,13 @@ INCLUDEPATH *= retroshare-gui ################################# Linux ########################################## # Put lib dir in QMAKE_LFLAGS so it appears before -L/usr/lib linux-* { + CONFIG += link_pkgconfig #CONFIG += version_detail_bash_script QMAKE_CXXFLAGS *= -D_FILE_OFFSET_BITS=64 - PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a + PKGCONFIG *= x11 xscrnsaver - LIBS += ../../libretroshare/src/lib/libretroshare.a - LIBS *= -lX11 -lXss - - LIBS += ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a - - #LIBS *= -lglib-2.0 - LIBS *= -rdynamic -ldl + LIBS *= -rdynamic DEFINES *= HAVE_XSS # for idle time, libx screensaver extensions DEFINES *= UBUNTU } @@ -144,7 +127,6 @@ version_detail_bash_script { win32-x-g++ { OBJECTS_DIR = temp/win32-x-g++/obj - LIBS += ../../libretroshare/src/lib.win32xgcc/libretroshare.a LIBS += ../../../../lib/win32-x-g++-v0.5/libssl.a LIBS += ../../../../lib/win32-x-g++-v0.5/libcrypto.a LIBS += ../../../../lib/win32-x-g++-v0.5/libgpgme.dll.a @@ -192,19 +174,12 @@ win32 { #LIBS += -L"D/Qt/2009.03/qt/plugins/imageformats" #QTPLUGIN += qjpeg - PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a - - LIBS_DIR = $$PWD/../../../libs - - LIBS += ../../libretroshare/src/lib/libretroshare.a - LIBS += -L"$$LIBS_DIR/lib" - - LIBS += ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a - LIBS += -lsqlcipher + for(lib, LIB_DIR):LIBS += -L"$$lib" + for(bin, BIN_DIR):LIBS += -L"$$bin" LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz -lws2_32 LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32 - LIBS += -lole32 -lwinmm + LIBS += -lwinmm RC_FILE = gui/images/retroshare_win.rc # export symbols for the plugins @@ -215,11 +190,8 @@ win32 { DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T - DEPENDPATH += . - INCLUDEPATH += . - - DEPENDPATH += $$LIBS_DIR/include - INCLUDEPATH += $$LIBS_DIR/include + DEPENDPATH += . $$INC_DIR + INCLUDEPATH += . $$INC_DIR greaterThan(QT_MAJOR_VERSION, 4) { # Qt 5 @@ -234,24 +206,18 @@ win32 { macx { # ENABLE THIS OPTION FOR Univeral Binary BUILD. - CONFIG += ppc x86 - QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 + #CONFIG += ppc x86 + #QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 CONFIG += version_detail_bash_script - LIBS += ../../libretroshare/src/lib/libretroshare.a LIBS += -lssl -lcrypto -lz #LIBS += -lssl -lcrypto -lz -lgpgme -lgpg-error -lassuan - LIBS += ../../../miniupnpc-1.0/libminiupnpc.a + LIBS += /usr/local/lib/libminiupnpc.a LIBS += -framework CoreFoundation LIBS += -framework Security - - LIBS += ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a - - LIBS += ../../../lib/libsqlcipher.a - #LIBS += -lsqlite3 - - INCLUDEPATH += . - #DEFINES* = MAC_IDLE # for idle feature + LIBS += -framework Carbon + INCLUDEPATH += . /usr/local/include + #DEFINES *= MAC_IDLE # for idle feature CONFIG -= uitools } @@ -259,12 +225,27 @@ macx { freebsd-* { INCLUDEPATH *= /usr/local/include/gpgme - LIBS *= ../../libretroshare/src/lib/libretroshare.a LIBS *= -lssl LIBS *= -lgpgme LIBS *= -lupnp LIBS *= -lgnome-keyring + + LIBS += -lsqlite3 +} + +##################################### Haiku ###################################### + +haiku-* { PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a + PRE_TARGETDEPS *= ../../openpgpsdk/src/lib/libops.a + + LIBS *= ../../libretroshare/src/lib/libretroshare.a + LIBS *= ../../openpgpsdk/src/lib/libops.a -lbz2 -lbsd + LIBS *= -lssl -lcrypto -lnetwork + LIBS *= -lgpgme + LIBS *= -lupnp + LIBS *= -lz + LIBS *= -lixml LIBS += ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a LIBS += -lsqlite3 @@ -275,18 +256,11 @@ freebsd-* { openbsd-* { INCLUDEPATH *= /usr/local/include - PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a - - LIBS *= ../../libretroshare/src/lib/libretroshare.a LIBS *= -lssl -lcrypto LIBS *= -lgpgme LIBS *= -lupnp LIBS *= -lgnome-keyring - PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a - - LIBS += ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a LIBS += -lsqlite3 - LIBS *= -rdynamic } @@ -302,11 +276,19 @@ openbsd-* { DEPENDPATH += . ../../libretroshare/src/ INCLUDEPATH += ../../libretroshare/src/ +PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a +LIBS *= ../../libretroshare/src/lib/libretroshare.a + +wikipoos { + PRE_TARGETDEPS *= ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a + LIBS *= ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a +} + # webinterface DEPENDPATH += ../../libresapi/src INCLUDEPATH += ../../libresapi/src PRE_TARGETDEPS *= ../../libresapi/src/lib/libresapi.a -LIBS += ../../libresapi/src/lib/libresapi.a -lmicrohttpd +LIBS += ../../libresapi/src/lib/libresapi.a # Input HEADERS += rshare.h \ @@ -1122,7 +1104,8 @@ wikipoos { HEADERS += gui/WikiPoos/WikiDialog.h \ gui/WikiPoos/WikiAddDialog.h \ gui/WikiPoos/WikiEditDialog.h \ - + gui/gxs/WikiGroupDialog.h \ + FORMS += gui/WikiPoos/WikiDialog.ui \ gui/WikiPoos/WikiAddDialog.ui \ gui/WikiPoos/WikiEditDialog.ui \ @@ -1130,10 +1113,10 @@ wikipoos { SOURCES += gui/WikiPoos/WikiDialog.cpp \ gui/WikiPoos/WikiAddDialog.cpp \ gui/WikiPoos/WikiEditDialog.cpp \ - + gui/gxs/WikiGroupDialog.cpp \ + RESOURCES += gui/WikiPoos/Wiki_images.qrc - DEFINES *= RS_USE_WIKI } @@ -1307,7 +1290,6 @@ posted { gxsgui { HEADERS += gui/gxs/GxsGroupDialog.h \ - gui/gxs/WikiGroupDialog.h \ gui/gxs/GxsIdDetails.h \ gui/gxs/GxsIdChooser.h \ gui/gxs/GxsIdLabel.h \ @@ -1344,7 +1326,6 @@ gxsgui { # gui/gxs/GxsCommentTreeWidget.ui SOURCES += gui/gxs/GxsGroupDialog.cpp \ - gui/gxs/WikiGroupDialog.cpp \ gui/gxs/GxsIdDetails.cpp \ gui/gxs/GxsIdChooser.cpp \ gui/gxs/GxsIdLabel.cpp \ diff --git a/retroshare-gui/src/util/HandleRichText.cpp b/retroshare-gui/src/util/HandleRichText.cpp index 980dcbd88..883cb6029 100644 --- a/retroshare-gui/src/util/HandleRichText.cpp +++ b/retroshare-gui/src/util/HandleRichText.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "HandleRichText.h" @@ -376,7 +377,7 @@ static QString saveSpace(const QString text) return savedSpaceText; } -QString RsHtml::formatText(QTextDocument *textDocument, const QString &text, ulong flag, const QColor &backgroundColor, qreal desiredContrast) +QString RsHtml::formatText(QTextDocument *textDocument, const QString &text, ulong flag, const QColor &backgroundColor, qreal desiredContrast, int desiredMinimumFontSize) { if (flag == 0 || text.isEmpty()) { // nothing to do @@ -416,7 +417,7 @@ QString RsHtml::formatText(QTextDocument *textDocument, const QString &text, ulo formattedText = doc.toString(-1); // -1 removes any annoying carriage return misinterpreted by QTextEdit if (flag & RSHTML_OPTIMIZEHTML_MASK) { - optimizeHtml(formattedText, flag, backgroundColor, desiredContrast); + optimizeHtml(formattedText, flag, backgroundColor, desiredContrast, desiredMinimumFontSize); } return formattedText; @@ -734,12 +735,14 @@ static void optimizeHtml(QDomDocument& doc * is passed inside flag. * @param desiredContrast: Minimum contrast between text and background color, * between 1 and 21. + * @param desiredMinimumFontSize: Minimum font size. */ static void styleCreate(QDomDocument& doc , QHash stylesList , unsigned int flag , qreal bglum - , qreal desiredContrast) + , qreal desiredContrast + , int desiredMinimumFontSize) { QDomElement styleElem; do{ @@ -792,6 +795,15 @@ static void styleCreate(QDomDocument& doc QString key = keyvalue.at(0).trimmed(); QString val = keyvalue.at(1).trimmed(); + if (key == "font-size") { + QRegExp re("(\\d+)(\\D*)"); + if (re.indexIn(val) != -1) { + bool ok; int iVal = re.cap(1).toInt(&ok); + if (ok && (iVal < desiredMinimumFontSize)) { + val = QString::number(desiredMinimumFontSize) + re.cap(2); + } + } + } if ((flag & RSHTML_FORMATTEXT_REMOVE_FONT_FAMILY && key == "font-family") || (flag & RSHTML_FORMATTEXT_REMOVE_FONT_SIZE && key == "font-size") || (flag & RSHTML_FORMATTEXT_REMOVE_FONT_WEIGHT && key == "font-weight") || @@ -864,9 +876,12 @@ void RsHtml::optimizeHtml(QTextEdit *textEdit, QString &text, unsigned int flag * is passed inside flag. * @param desiredContrast Minimum contrast between text and background color, * between 1 and 21. + * @param desiredMinimumFontSize Minimum font size. */ void RsHtml::optimizeHtml(QString &text, unsigned int flag /*= 0*/ - , const QColor &backgroundColor /*= Qt::white*/, qreal desiredContrast /*= 1.0*/ + , const QColor &backgroundColor /*= Qt::white*/ + , qreal desiredContrast /*= 1.0*/ + , int desiredMinimumFontSize /*=10*/ ) { @@ -888,7 +903,7 @@ void RsHtml::optimizeHtml(QString &text, unsigned int flag /*= 0*/ QHash knownStyle; ::optimizeHtml(doc, body, stylesList, knownStyle); - ::styleCreate(doc, stylesList, flag, ::getRelativeLuminance(backgroundColor), desiredContrast); + ::styleCreate(doc, stylesList, flag, ::getRelativeLuminance(backgroundColor), desiredContrast, desiredMinimumFontSize); text = doc.toString(-1); // std::cerr << "Optimized text to " << text.length() << " bytes , instead of " << originalLength << std::endl; @@ -983,3 +998,15 @@ QString RsHtml::plainText(const std::string &text) return Qt::escape(QString::fromUtf8(text.c_str())); #endif } + +QString RsHtml::makeQuotedText(RSTextBrowser *browser) +{ + QString text = browser->textCursor().selection().toPlainText(); + if(text.length() == 0) + { + text = browser->toPlainText(); + } + QStringList sl = text.split(QRegExp("[\r\n]"),QString::SkipEmptyParts); + text = sl.join("\n>"); + return QString(">") + text; +} diff --git a/retroshare-gui/src/util/HandleRichText.h b/retroshare-gui/src/util/HandleRichText.h index d3d69bed5..4cea4a8d5 100644 --- a/retroshare-gui/src/util/HandleRichText.h +++ b/retroshare-gui/src/util/HandleRichText.h @@ -19,6 +19,8 @@ * Boston, MA 02110-1301, USA. ****************************************************************/ +#include + /** * This file provides helper functions and functors for translating data from/to * rich text format and HTML. Its main goal is to facilitate decoding of chat @@ -59,11 +61,11 @@ public: static void initEmoticons(const QHash< QString, QString >& hash); - QString formatText(QTextDocument *textDocument, const QString &text, ulong flag, const QColor &backgroundColor = Qt::white, qreal desiredContrast = 1.0); + QString formatText(QTextDocument *textDocument, const QString &text, ulong flag, const QColor &backgroundColor = Qt::white, qreal desiredContrast = 1.0, int desiredMinimumFontSize = 10); static bool findAnchors(const QString &text, QStringList& urls); static void optimizeHtml(QTextEdit *textEdit, QString &text, unsigned int flag = 0); - static void optimizeHtml(QString &text, unsigned int flag = 0, const QColor &backgroundColor = Qt::white, qreal desiredContrast = 1.0); + static void optimizeHtml(QString &text, unsigned int flag = 0, const QColor &backgroundColor = Qt::white, qreal desiredContrast = 1.0, int desiredMinimumFontSize = 10); static QString toHtml(QString text, bool realHtml = true); static bool makeEmbeddedImage(const QString &fileName, QString &embeddedImage, const int maxPixels); @@ -72,6 +74,8 @@ public: static QString plainText(const QString &text); static QString plainText(const std::string &text); + static QString makeQuotedText(RSTextBrowser* browser); + protected: void embedHtml(QTextDocument *textDocument, QDomDocument &doc, QDomElement ¤tElement, EmbedInHtml& embedInfos, ulong flag); void replaceAnchorWithImg(QDomDocument& doc, QDomElement &element, QTextDocument *textDocument, const RetroShareLink &link); diff --git a/retroshare-gui/src/util/global.h b/retroshare-gui/src/util/global.h index 8ff3671df..891ff8b58 100644 --- a/retroshare-gui/src/util/global.h +++ b/retroshare-gui/src/util/global.h @@ -85,6 +85,8 @@ #define OS_OPENBSD #elif defined(__GNU_HURD__) #define OS_HURD +#elif defined(__HAIKU__) + #define OS_HAIKU #elif defined(WIN32_PLATFORM_PSPC) #define OS_WINCE_POCKETPC #elif defined(WIN32_PLATFORM_WFSP) @@ -101,7 +103,7 @@ #define OS_BSD #endif -#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_HURD) || defined(OS_BSD) +#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_HURD) || defined(OS_BSD) || defined(OS_HAIKU) #define OS_POSIX #endif diff --git a/retroshare-gui/src/util/printpreview.cpp b/retroshare-gui/src/util/printpreview.cpp index 73bc09ca4..02e925336 100644 --- a/retroshare-gui/src/util/printpreview.cpp +++ b/retroshare-gui/src/util/printpreview.cpp @@ -38,7 +38,6 @@ #include "printpreview.h" -#include #include #include #include @@ -70,35 +69,6 @@ static inline qreal mmToInches(double mm) return mm*0.039370147; } -class PreviewView : public QAbstractScrollArea -{ - Q_OBJECT -public: - PreviewView(QTextDocument *document, PrintPreview *printPrev); - - inline void updateLayout() { resizeEvent(0); viewport()->update(); } - -public slots: - void zoomIn(); - void zoomOut(); - -protected: - virtual void paintEvent(QPaintEvent *e); - virtual void resizeEvent(QResizeEvent *); - virtual void mousePressEvent(QMouseEvent *e); - virtual void mouseMoveEvent(QMouseEvent *e); - virtual void mouseReleaseEvent(QMouseEvent *e); - -private: - void paintPage(QPainter *painter, int page); - QTextDocument *doc; - qreal scale; - int interPageSpacing; - QPoint mousePressPos; - QPoint scrollBarValuesOnMousePress; - PrintPreview *printPreview; -}; - PreviewView::PreviewView(QTextDocument *document, PrintPreview *printPrev) : printPreview(printPrev) { @@ -330,5 +300,3 @@ void PrintPreview::pageSetup() view->updateLayout(); } } - -#include "printpreview.moc" diff --git a/retroshare-gui/src/util/printpreview.h b/retroshare-gui/src/util/printpreview.h index e8f7a769d..9fce97b5d 100644 --- a/retroshare-gui/src/util/printpreview.h +++ b/retroshare-gui/src/util/printpreview.h @@ -39,6 +39,7 @@ #ifndef PRINTPREVIEW_H #define PRINTPREVIEW_H +#include #include #include #include @@ -69,5 +70,34 @@ private: QPrinter printer; }; +class PreviewView : public QAbstractScrollArea +{ + Q_OBJECT +public: + PreviewView(QTextDocument *document, PrintPreview *printPrev); + + inline void updateLayout() { resizeEvent(0); viewport()->update(); } + +public slots: + void zoomIn(); + void zoomOut(); + +protected: + virtual void paintEvent(QPaintEvent *e); + virtual void resizeEvent(QResizeEvent *); + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseMoveEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *e); + +private: + void paintPage(QPainter *painter, int page); + QTextDocument *doc; + qreal scale; + int interPageSpacing; + QPoint mousePressPos; + QPoint scrollBarValuesOnMousePress; + PrintPreview *printPreview; +}; + #endif // PRINTPREVIEW_H diff --git a/retroshare-nogui/src/introserver.cc b/retroshare-nogui/src/introserver.cc index 0026468c0..6ff90cdb5 100644 --- a/retroshare-nogui/src/introserver.cc +++ b/retroshare-nogui/src/introserver.cc @@ -220,6 +220,7 @@ int RsIntroServer::addCertificateFile(std::string filepath) std::cerr << std::endl; std::cerr << "==========================================================" << std::endl; + fclose(fd) ; return addNewUser(certGPG); } diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index a15cb1bb2..96fc2a0d0 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -10,10 +10,6 @@ CONFIG += webui CONFIG -= qt xml gui CONFIG += link_prl -# if you are linking against the libretroshare with gxs. -# this option links against the required sqlite library. -CONFIG += gxs - #CONFIG += debug debug { QMAKE_CFLAGS -= -O2 @@ -30,8 +26,7 @@ linux-* { #CONFIG += version_detail_bash_script QMAKE_CXXFLAGS *= -D_FILE_OFFSET_BITS=64 - LIBS += ../../libretroshare/src/lib/libretroshare.a - LIBS *= -rdynamic -ldl + LIBS *= -rdynamic } unix { @@ -52,7 +47,6 @@ linux-g++-64 { win32-x-g++ { OBJECTS_DIR = temp/win32-x-g++/obj - LIBS += ../../../../lib/win32-x-g++/libretroshare.a LIBS += ../../../../lib/win32-x-g++/libssl.a LIBS += ../../../../lib/win32-x-g++/libcrypto.a LIBS += ../../../../lib/win32-x-g++/libminiupnpc.a @@ -78,29 +72,20 @@ win32 { # solve linker warnings because of the order of the libraries QMAKE_LFLAGS += -Wl,--start-group - PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a - - LIBS_DIR = $$PWD/../../../libs - - LIBS += ../../libretroshare/src/lib/libretroshare.a - LIBS += -L"$$LIBS_DIR/lib" + for(lib, LIB_DIR):LIBS += -L"$$lib" LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz LIBS += -lcrypto -lws2_32 -lgdi32 LIBS += -luuid -lole32 -liphlpapi -lcrypt32 LIBS += -lole32 -lwinmm - PROTOCPATH=$$LIBS_DIR/bin/ + PROTOCPATH=$$BIN_DIR RC_FILE = resources/retroshare_win.rc DEFINES *= WINDOWS_SYS _USE_32BIT_TIME_T - DEPENDPATH += $$LIBS_DIR/include - INCLUDEPATH += $$LIBS_DIR/include - - gxs { - LIBS += -lsqlcipher - } + DEPENDPATH += . $$INC_DIR + INCLUDEPATH += . $$INC_DIR } ##################################### MacOS ###################################### @@ -110,17 +95,11 @@ macx { # CONFIG += ppc x86 LIBS += -Wl,-search_paths_first - LIBS += ../../libretroshare/src/lib/libretroshare.a LIBS += -lssl -lcrypto -lz - LIBS += ../../../miniupnpc-1.0/libminiupnpc.a + LIBS += /usr/local/lib/libminiupnpc.a LIBS += -framework CoreFoundation LIBS += -framework Security - - gxs { - # We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database. - # LIBS += ../../../lib/sqlcipher/.libs/libsqlcipher.a - LIBS += ../../../lib/libsqlcipher.a - } + INCLUDEPATH += /usr/local/include sshserver { LIBS += -L../../../lib @@ -135,12 +114,10 @@ macx { freebsd-* { INCLUDEPATH *= /usr/local/include/gpgme - LIBS *= ../../libretroshare/src/lib/libretroshare.a LIBS *= -lssl LIBS *= -lgpgme LIBS *= -lupnp LIBS *= -lgnome-keyring - PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a } ##################################### OpenBSD ###################################### @@ -148,21 +125,42 @@ freebsd-* { openbsd-* { INCLUDEPATH *= /usr/local/include QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dstat64=stat -Dstatvfs64=statvfs -Dfopen64=fopen - LIBS *= ../../libretroshare/src/lib/libretroshare.a LIBS *= -lssl -lcrypto LIBS *= -lgpgme LIBS *= -lupnp LIBS *= -lgnome-keyring - PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a LIBS *= -rdynamic } +##################################### Haiku ###################################### + +haiku-* { + QMAKE_CXXFLAGS *= -D_BSD_SOURCE + + PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a + PRE_TARGETDEPS *= ../../openpgpsdk/src/lib/libops.a + + LIBS *= ../../libretroshare/src/lib/libretroshare.a + LIBS *= ../../openpgpsdk/src/lib/libops.a -lbz2 -lbsd + LIBS *= -lssl -lcrypto -lnetwork + LIBS *= -lgpgme + LIBS *= -lupnp + LIBS *= -lz + LIBS *= -lixml + + LIBS += ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a + LIBS += -lsqlite3 + +} ############################## Common stuff ###################################### DEPENDPATH += . ../../libretroshare/src INCLUDEPATH += . ../../libretroshare/src +PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a +LIBS *= ../../libretroshare/src/lib/libretroshare.a + # Input HEADERS += notifytxt.h SOURCES += notifytxt.cc \ @@ -177,7 +175,7 @@ introserver { webui { DEFINES *= ENABLE_WEBUI PRE_TARGETDEPS *= ../../libresapi/src/lib/libresapi.a - LIBS += ../../libresapi/src/lib/libresapi.a -lmicrohttpd + LIBS += ../../libresapi/src/lib/libresapi.a DEPENDPATH += ../../libresapi/src INCLUDEPATH += ../../libresapi/src HEADERS += \ diff --git a/retroshare-nogui/src/retroshare.cc b/retroshare-nogui/src/retroshare.cc index 1da48dc6b..59a1bf1b4 100644 --- a/retroshare-nogui/src/retroshare.cc +++ b/retroshare-nogui/src/retroshare.cc @@ -86,8 +86,11 @@ int main(int argc, char **argv) // unfinished //args >> parameter("http-listen", listenAddress, "ipv6 address", "Listen only on the specified address.", false); args >> option("http-allow-all", allowAllIps, "allow connections from all IP adresses (default= localhost only)"); +#ifdef __APPLE__ + args >> help('h',"help","Display this Help"); +#else args >> help(); - +#endif if (args.helpRequested()) { std::cerr << args.usage() << std::endl; @@ -99,7 +102,7 @@ int main(int argc, char **argv) resource_api::ApiServer api; resource_api::RsControlModule ctrl_mod(argc, argv, api.getStateTokenServer(), &api, true); - api.addResourceHandler("control", dynamic_cast(&ctrl_mod), &resource_api::RsControlModule::handleRequest); + api.addResourceHandler("control", dynamic_cast(&ctrl_mod), &resource_api::RsControlModule::handleRequest); resource_api::ApiServerMHD* httpd = 0; if(httpPort != 0) @@ -192,8 +195,11 @@ int main(int argc, char **argv) >> parameter('P',"ssh-p-hash" ,sshPwdHash ,"hash" ,"Ssh login password hash (Generated by retroshare-nogui -G)",false) >> parameter('K',"ssh-key-file" ,sshRsaFile ,"RSA key file", "RSA key file for SSH login (not yet implemented).",false )// NOT FINISHED YET. +#ifdef __APPLE__ + >> help('h',"help","Display this Help"); +#else >> help() ; - +#endif // Normally argstream would handle this by itself, if we called // as.defaultErrorHandling() ; // diff --git a/retroshare.pri b/retroshare.pri index b85b40cbc..5359c8230 100644 --- a/retroshare.pri +++ b/retroshare.pri @@ -1,7 +1,45 @@ +# Gxs is always enabled now. +DEFINES *= RS_ENABLE_GXS + unix { isEmpty(PREFIX) { PREFIX = "/usr" } isEmpty(BIN_DIR) { BIN_DIR = "$${PREFIX}/bin" } isEmpty(INC_DIR) { INC_DIR = "$${PREFIX}/include/retroshare06" } isEmpty(LIB_DIR) { LIB_DIR = "$${PREFIX}/lib" } isEmpty(DATA_DIR) { DATA_DIR = "$${PREFIX}/share/RetroShare06" } + isEmpty(PLUGIN_DIR) { PLUGIN_DIR = "$${LIB_DIR}/retroshare/extensions6" } } + +win32 { + message(***retroshare.pri:Win32) + exists($$PWD/../libs) { + message(Get pre-compiled libraries.) + isEmpty(PREFIX) { PREFIX = "$$PWD/../libs" } + isEmpty(BIN_DIR) { BIN_DIR = "$${PREFIX}/bin" } + isEmpty(INC_DIR) { INC_DIR = "$${PREFIX}/include" } + isEmpty(LIB_DIR) { LIB_DIR = "$${PREFIX}/lib" } + } + exists(C:/msys32/mingw32/include) { + message(msys2 32b is installed.) + PREFIX_MSYS2 = "C:/msys32/mingw32" + BIN_DIR += "$${PREFIX_MSYS2}/bin" + INC_DIR += "$${PREFIX_MSYS2}/include" + LIB_DIR += "$${PREFIX_MSYS2}/lib" + } + exists(C:/msys64/mingw32/include) { + message(msys2 64b is installed.) + PREFIX_MSYS2 = "C:/msys64/mingw32" + BIN_DIR += "$${PREFIX_MSYS2}/bin" + INC_DIR += "$${PREFIX_MSYS2}/include" + LIB_DIR += "$${PREFIX_MSYS2}/lib" + } +} + +unfinished { + CONFIG += gxscircles + CONFIG += gxsthewire + CONFIG += gxsphotoshare + CONFIG += wikipoos +} + +wikipoos:DEFINES *= RS_USE_WIKI diff --git a/rsctrl/src/Makefile b/rsctrl/src/Makefile deleted file mode 100644 index a4c556640..000000000 --- a/rsctrl/src/Makefile +++ /dev/null @@ -1,33 +0,0 @@ - -EXEC = protoc -#PROTO = core.proto peers.proto system.proto chat.proto search.proto files.proto stream.proto gxs.proto msgs.proto -PROTO = core.proto peers.proto system.proto chat.proto search.proto files.proto stream.proto - -PROTOPATH = ./definition -#CDESTPATH = ./gencc -CDESTPATH = ../../retroshare-nogui/src/rpc/proto/gencc -PYDESTPATH = ./genpy -#PYDESTPATH = ../../../../github/pyrs/pyrs/proto - -CLIST = $(PROTO:%.proto=%.cc) -CCODE = $(patsubst %.proto,$(CDESTPATH)/%.pb.cc, $(PROTO)) -HCODE = $(patsubst %.proto,$(CDESTPATH)/%.pb.h, $(PROTO)) -PYCODE = $(patsubst %.proto,$(PYDESTPATH)/%_pb2.py, $(PROTO)) - - -all: allc python_proto - -allc: $(CCODE) - echo $(CCODE) - -python_proto: $(PYCODE) - echo $(PYCODE) - -$(CDESTPATH)/%.pb.cc : $(PROTOPATH)/%.proto - $(EXEC) --proto_path=$(PROTOPATH) --cpp_out=$(CDESTPATH) $< - -$(PYDESTPATH)/%_pb2.py : $(PROTOPATH)/%.proto - $(EXEC) --proto_path=$(PROTOPATH) --python_out=$(PYDESTPATH) $< - -clean: - -/bin/rm $(CCODE) $(HCODE) $(PYCODE) diff --git a/supportlibs/pegmarkdown/peg-0.1.9/Makefile b/supportlibs/pegmarkdown/peg-0.1.9/Makefile deleted file mode 100644 index c10fbda83..000000000 --- a/supportlibs/pegmarkdown/peg-0.1.9/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -CFLAGS = -g -Wall $(OFLAGS) $(XFLAGS) -OFLAGS = -O3 -DNDEBUG -#OFLAGS = -pg - -OBJS = tree.o compile.o - -all : peg leg - -peg : peg.o $(OBJS) - $(CC) $(CFLAGS) -o $@-new peg.o $(OBJS) - mv $@-new $@ - -leg : leg.o $(OBJS) - $(CC) $(CFLAGS) -o $@-new leg.o $(OBJS) - mv $@-new $@ - -ROOT = -PREFIX = /usr/local -BINDIR = $(ROOT)$(PREFIX)/bin - -install : $(BINDIR)/peg $(BINDIR)/leg - -$(BINDIR)/% : % - cp -p $< $@ - strip $@ - -uninstall : .FORCE - rm -f $(BINDIR)/peg - rm -f $(BINDIR)/leg - -peg.o : peg.c peg.peg-c - -%.peg-c : %.peg compile.c - ./peg -o $@ $< - -leg.o : leg.c - -leg.c : leg.leg compile.c - ./leg -o $@ $< - -check : check-peg check-leg - -check-peg : peg .FORCE - ./peg < peg.peg > peg.out - diff peg.peg-c peg.out - rm peg.out - -check-leg : leg .FORCE - ./leg < leg.leg > leg.out - diff leg.c leg.out - rm leg.out - -test examples : .FORCE - $(SHELL) -ec '(cd examples; $(MAKE))' - -clean : .FORCE - rm -f *~ *.o *.peg.[cd] *.leg.[cd] - $(SHELL) -ec '(cd examples; $(MAKE) $@)' - -spotless : clean .FORCE - rm -f peg - rm -f leg - $(SHELL) -ec '(cd examples; $(MAKE) $@)' - -.FORCE : diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/Makefile b/supportlibs/pegmarkdown/peg-0.1.9/examples/Makefile deleted file mode 100644 index 30d3cc8f8..000000000 --- a/supportlibs/pegmarkdown/peg-0.1.9/examples/Makefile +++ /dev/null @@ -1,88 +0,0 @@ -EXAMPLES = test rule accept wc dc dcv calc basic localctx - -CFLAGS = -g -O3 - -DIFF = diff -TEE = cat > - -all : $(EXAMPLES) - -test : .FORCE - ../peg -o test.peg.c test.peg - $(CC) $(CFLAGS) -o test test.c - echo 'ab.ac.ad.ae.afg.afh.afg.afh.afi.afj.' | ./$@ | $(TEE) $@.out - $(DIFF) $@.ref $@.out - rm -f $@.out - @echo - -rule : .FORCE - ../peg -o rule.peg.c rule.peg - $(CC) $(CFLAGS) -o rule rule.c - echo 'abcbcdabcbcdabcbcdabcbcd' | ./$@ | $(TEE) $@.out - $(DIFF) $@.ref $@.out - rm -f $@.out - @echo - -accept : .FORCE - ../peg -o accept.peg.c accept.peg - $(CC) $(CFLAGS) -o accept accept.c - echo 'abcbcdabcbcdabcbcdabcbcd' | ./$@ | $(TEE) $@.out - $(DIFF) $@.ref $@.out - rm -f $@.out - @echo - -wc : .FORCE - ../leg -o wc.leg.c wc.leg - $(CC) $(CFLAGS) -o wc wc.leg.c - cat wc.leg | ./$@ | $(TEE) $@.out - $(DIFF) $@.ref $@.out - rm -f $@.out - @echo - -dc : .FORCE - ../peg -o dc.peg.c dc.peg - $(CC) $(CFLAGS) -o dc dc.c - echo ' 2 *3 *(3+ 4) ' | ./dc | $(TEE) $@.out - $(DIFF) $@.ref $@.out - rm -f $@.out - @echo - -dcv : .FORCE - ../peg -o dcv.peg.c dcv.peg - $(CC) $(CFLAGS) -o dcv dcv.c - echo 'a = 6; b = 7; a * b' | ./dcv | $(TEE) $@.out - $(DIFF) $@.ref $@.out - rm -f $@.out - @echo - -calc : .FORCE - ../leg -o calc.leg.c calc.leg - $(CC) $(CFLAGS) -o calc calc.leg.c - echo 'a = 6; b = 7; a * b' | ./calc | $(TEE) $@.out - $(DIFF) $@.ref $@.out - rm -f $@.out - @echo - -basic : .FORCE - ../leg -o basic.leg.c basic.leg - $(CC) $(CFLAGS) -o basic basic.leg.c - ( echo 'load "test"'; echo "run" ) | ./basic | $(TEE) $@.out - $(DIFF) $@.ref $@.out - rm -f $@.out - @echo - -localctx : .FORCE - ../peg -o test.peg.c test.peg - $(CC) $(CFLAGS) -o localctx localctx.c - echo 'ab.ac.ad.ae.afg.afh.afg.afh.afi.afj.' | ./$@ | $(TEE) $@.out - $(DIFF) $@.ref $@.out - rm -f $@.out - @echo - -clean : .FORCE - rm -f *~ *.o *.[pl]eg.[cd] $(EXAMPLES) - rm -rf *.dSYM - -spotless : clean - -.FORCE : diff --git a/supportlibs/pegmarkdown/pegmarkdown.pro b/supportlibs/pegmarkdown/pegmarkdown.pro index 31bda9f64..cc21ccaf3 100644 --- a/supportlibs/pegmarkdown/pegmarkdown.pro +++ b/supportlibs/pegmarkdown/pegmarkdown.pro @@ -1,7 +1,9 @@ TEMPLATE = lib CONFIG += staticlib +CONFIG += create_prl CONFIG -= qt TARGET = pegmarkdown +DESTDIR = lib QMAKE_CFLAGS *= -Wall -ansi -D_GNU_SOURCE QMAKE_CC = gcc @@ -14,7 +16,9 @@ debug { ################################# Linux ########################################## linux-* { - DESTDIR = lib + CONFIG += link_pkgconfig + + PKGCONFIG *= glib-2.0 } linux-g++ { @@ -30,7 +34,6 @@ linux-g++-64 { win32 { OBJECTS_DIR = temp/obj MOC_DIR = temp/moc - DESTDIR = lib # Switch on extra warnings QMAKE_CFLAGS += -Wextra @@ -53,7 +56,6 @@ win32 { mac { OBJECTS_DIR = temp/obj MOC_DIR = temp/moc - DESTDIR = lib CONFIG += dummy_glib } @@ -61,13 +63,11 @@ mac { ################################# FreeBSD ########################################## freebsd-* { - DESTDIR = lib } ################################# OpenBSD ########################################## openbsd-* { - DESTDIR = lib } ################################### COMMON stuff ################################## diff --git a/win_build_libs/Makefile b/win_build_libs/Makefile new file mode 100755 index 000000000..250dca2e2 --- /dev/null +++ b/win_build_libs/Makefile @@ -0,0 +1,216 @@ +ZLIB_VERSION=1.2.3 +BZIP2_VERSION=1.0.6 +MINIUPNPC_VERSION=1.3 +OPENSSL_VERSION=1.0.1h +SPEEX_VERSION=1.2rc1 +OPENCV_VERSION=2.4.9 +LIBXML2_VERSION=2.9.1 +LIBXSLT_VERSION=1.1.28 +CURL_VERSION=7.34.0 +LIBSSH_VERSION=0.5.4 +PROTOBUF_VERSION=2.4.1 +TCL_VERSION=8.6.2 +SQLCIPHER_VERSION=2.2.1 +LIBMICROHTTPD_VERSION=0.9.42 +FFMPEG_VERSION=2.7.2 + +all: dirs zlib bzip2 miniupnpc openssl speex opencv libxml2 libxslt curl sqlcipher libmicrohttpd ffmpeg copylibs + +dirs: + mkdir -p libs/include + mkdir -p libs/lib + mkdir -p libs/bin + +zlib-$(ZLIB_VERSION).tar.gz: + curl.exe -L http://sourceforge.net/projects/libpng/files/zlib/$(ZLIB_VERSION)/zlib-$(ZLIB_VERSION).tar.gz/download -o zlib-$(ZLIB_VERSION).tar.gz + +zlib: zlib-$(ZLIB_VERSION).tar.gz + tar xvf zlib-$(ZLIB_VERSION).tar.gz + cd zlib-$(ZLIB_VERSION) && ./configure + #cd zlib-$(ZLIB_VERSION) && make install prefix="`pwd`/../libs" + cd zlib-$(ZLIB_VERSION) && make + cp zlib-$(ZLIB_VERSION)/zlib.h libs/include/ + cp zlib-$(ZLIB_VERSION)/zconf.h libs/include/ + cp zlib-$(ZLIB_VERSION)/libz.a libs/lib/ + rm -r -f zlib-$(ZLIB_VERSION) + touch zlib + +bzip2-$(BZIP2_VERSION).tar.gz: + curl.exe http://bzip.org/$(BZIP2_VERSION)/bzip2-$(BZIP2_VERSION).tar.gz -o bzip2-$(BZIP2_VERSION).tar.gz + +bzip2: bzip2-$(BZIP2_VERSION).tar.gz + tar xvf bzip2-$(BZIP2_VERSION).tar.gz + #cd bzip2-$(BZIP2_VERSION) && make install PREFIX="`pwd`/../libs" + cd bzip2-$(BZIP2_VERSION) && make + cp bzip2-$(BZIP2_VERSION)/bzlib.h libs/include/ + cp bzip2-$(BZIP2_VERSION)/libbz2.a libs/lib/ + rm -r -f bzip2-$(BZIP2_VERSION) + touch bzip2 + +miniupnpc-$(MINIUPNPC_VERSION).tar.gz: + curl.exe -L http://miniupnp.free.fr/files/download.php?file=miniupnpc-$(MINIUPNPC_VERSION).tar.gz -o miniupnpc-$(MINIUPNPC_VERSION).tar.gz + +miniupnpc: miniupnpc-$(MINIUPNPC_VERSION).tar.gz + tar xvf miniupnpc-$(MINIUPNPC_VERSION).tar.gz + cd miniupnpc-$(MINIUPNPC_VERSION) && make -f Makefile.mingw init libminiupnpc.a miniupnpc.dll + mkdir -p libs/include/miniupnpc && cp miniupnpc-$(MINIUPNPC_VERSION)/*.h libs/include/miniupnpc/ + cp miniupnpc-$(MINIUPNPC_VERSION)/libminiupnpc.a libs/lib/ + cp miniupnpc-$(MINIUPNPC_VERSION)/miniupnpc.dll libs/bin/ + rm -r -f miniupnpc-$(MINIUPNPC_VERSION) + touch miniupnpc + +openssl-$(OPENSSL_VERSION).tar.gz: + curl.exe -k https://www.openssl.org/source/openssl-1.0.1h.tar.gz -o openssl-1.0.1h.tar.gz + +openssl: openssl-$(OPENSSL_VERSION).tar.gz + tar xvf openssl-$(OPENSSL_VERSION).tar.gz + #cd openssl-$(OPENSSL_VERSION) && ./config --prefix="`pwd`/../libs" + #cd openssl-$(OPENSSL_VERSION) && make install + cd openssl-$(OPENSSL_VERSION) && ./config + cd openssl-$(OPENSSL_VERSION) && make + mkdir -p libs/include/openssl && cp openssl-$(OPENSSL_VERSION)/include/openssl/*.h libs/include/openssl/ + cp openssl-$(OPENSSL_VERSION)/libcrypto.a libs/lib/ + cp openssl-$(OPENSSL_VERSION)/libssl.a libs/lib/ + rm -r -f openssl-$(OPENSSL_VERSION) + touch openssl + +speex-$(SPEEX_VERSION).tar.gz: + curl.exe http://downloads.xiph.org/releases/speex/speex-$(SPEEX_VERSION).tar.gz -o speex-$(SPEEX_VERSION).tar.gz + +speex: speex-$(SPEEX_VERSION).tar.gz + tar xvf speex-$(SPEEX_VERSION).tar.gz + cd speex-$(SPEEX_VERSION) && ./configure + #cd speex-$(SPEEX_VERSION) && make install exec_prefix="`pwd`/../libs" + cd speex-$(SPEEX_VERSION) && make + mkdir -p libs/include/speex && cp speex-$(SPEEX_VERSION)/include/speex/*.h libs/include/speex/ + cp speex-$(SPEEX_VERSION)/libspeex/.libs/libspeex.a libs/lib + cp speex-$(SPEEX_VERSION)/libspeex/.libs/libspeexdsp.a libs/lib + rm -r -f speex-$(SPEEX_VERSION) + touch speex + +opencv-$(OPENCV_VERSION).tar.gz: + curl.exe -L -k https://github.com/Itseez/opencv/archive/$(OPENCV_VERSION).tar.gz -o opencv-$(OPENCV_VERSION).tar.gz + +opencv: opencv-$(OPENCV_VERSION).tar.gz + tar xvf opencv-$(OPENCV_VERSION).tar.gz + mkdir -p opencv-$(OPENCV_VERSION)/build + #cd opencv-$(OPENCV_VERSION)/build && cmake .. -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="`pwd`/../../libs" + cd opencv-$(OPENCV_VERSION)/build && cmake .. -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="`pwd`/install" + cd opencv-$(OPENCV_VERSION)/build && make install + cp -r opencv-$(OPENCV_VERSION)/build/install/include/* libs/include/ + mkdir -p libs/lib/opencv + if [ -d "opencv-$(OPENCV_VERSION)/build/install/x86" ]; then \ + cp -r opencv-$(OPENCV_VERSION)/build/install/x86/mingw/staticlib/* libs/lib/opencv/ ; \ + fi + if [ -d "opencv-$(OPENCV_VERSION)/build/install/x64" ]; then \ + cp -r opencv-$(OPENCV_VERSION)/build/install/x64/mingw/staticlib/* libs/lib/opencv/ ; \ + fi + rm -r -f opencv-$(OPENCV_VERSION) + touch opencv + +libxml2-$(LIBXML2_VERSION).tar.gz: + curl.exe ftp://xmlsoft.org/libxml2/libxml2-$(LIBXML2_VERSION).tar.gz -o libxml2-$(LIBXML2_VERSION).tar.gz + +libxml2: libxml2-$(LIBXML2_VERSION).tar.gz + tar xvf libxml2-$(LIBXML2_VERSION).tar.gz + cd libxml2-$(LIBXML2_VERSION) && ./configure --without-iconv -enable-shared=no + #cd libxml2-$(LIBXML2_VERSION) && make install exec_prefix="`pwd`/../libs" + cd libxml2-$(LIBXML2_VERSION) && make + mkdir -p libs/include/libxml && cp libxml2-$(LIBXML2_VERSION)/include/libxml/*.h libs/include/libxml/ + cp libxml2-$(LIBXML2_VERSION)/.libs/libxml2.a libs/lib/ + touch libxml2 + +libxslt-$(LIBXSLT_VERSION).tar.gz: + curl.exe ftp://xmlsoft.org/libxml2/libxslt-$(LIBXSLT_VERSION).tar.gz -o libxslt-$(LIBXSLT_VERSION).tar.gz + +libxslt: libxml2-$(LIBXML2_VERSION).tar.gz libxslt-$(LIBXSLT_VERSION).tar.gz + tar xvf libxml2-$(LIBXML2_VERSION).tar.gz + tar xvf libxslt-$(LIBXSLT_VERSION).tar.gz + tar xvf libxslt-$(LIBXSLT_VERSION)-fix.tar.gz + cd libxslt-$(LIBXSLT_VERSION) && ./configure --with-libxml-src=../libxml2-$(LIBXML2_VERSION) -enable-shared=no CFLAGS=-DLIBXML_STATIC + cd libxslt-$(LIBXSLT_VERSION) && make + mkdir -p libs/include/libxslt && cp libxslt-$(LIBXSLT_VERSION)/libxslt/*.h libs/include/libxslt/ + cp libxslt-$(LIBXSLT_VERSION)/libxslt/.libs/libxslt.a libs/lib/ + cp libxslt-$(LIBXSLT_VERSION)/libexslt/.libs/libexslt.a libs/lib/ + rm -r -f libxml2-$(LIBXML2_VERSION) + rm -r -f libxslt-$(LIBXSLT_VERSION) + touch libxslt + +curl-$(CURL_VERSION).tar.gz: + curl.exe http://curl.haxx.se/download/curl-$(CURL_VERSION).tar.gz -o curl-$(CURL_VERSION).tar.gz + +curl: curl-$(CURL_VERSION).tar.gz + tar xvf curl-$(CURL_VERSION).tar.gz + cd curl-$(CURL_VERSION) && LIBS="-L`pwd`/../libs/lib $$LIBS" && export LIBS && ./configure --disable-shared --with-ssl="`pwd`/../libs" + #cd curl-$(CURL_VERSION) && make install exec_prefix="`pwd`/../libs" + cd curl-$(CURL_VERSION) && make + mkdir -p libs/include/curl && cp curl-$(CURL_VERSION)/include/curl/*.h libs/include/curl/ + cp curl-$(CURL_VERSION)/lib/.libs/libcurl.a libs/lib/ + rm -r -f curl-$(CURL_VERSION) + touch curl + +tcl$(TCL_VERSION)-src.tar.gz: + curl.exe -L http://prdownloads.sourceforge.net/tcl/tcl$(TCL_VERSION)-src.tar.gz -o tcl$(TCL_VERSION)-src.tar.gz + +sqlcipher-$(SQLCIPHER_VERSION).tar.gz: + curl.exe -L -k https://github.com/sqlcipher/sqlcipher/archive/v$(SQLCIPHER_VERSION).tar.gz -o sqlcipher-$(SQLCIPHER_VERSION).tar.gz + +sqlcipher: tcl$(TCL_VERSION)-src.tar.gz sqlcipher-$(SQLCIPHER_VERSION).tar.gz + # tcl + tar xvf tcl$(TCL_VERSION)-src.tar.gz + mkdir -p tcl$(TCL_VERSION)/build + cd tcl$(TCL_VERSION)/build && ../win/configure + cd tcl$(TCL_VERSION)/build && make + #sqlcipher + tar xvf sqlcipher-$(SQLCIPHER_VERSION).tar.gz + cd sqlcipher-$(SQLCIPHER_VERSION) && ln -s ../tcl$(TCL_VERSION)/build/tclsh86.exe tclsh + mkdir -p tcl$(TCL_VERSION)/lib + ln -s `pwd`/tcl$(TCL_VERSION)/library `pwd`/tcl$(TCL_VERSION)/lib/tcl8.6 + cd sqlcipher-$(SQLCIPHER_VERSION) && PATH=$$PATH:`pwd`/../tcl$(TCL_VERSION)/build && LIBS="-L`pwd`/../libs/lib -lgdi32 $$LIBS" && export LIBS && ./configure --disable-shared --enable-static --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC -I`pwd`/../libs/include -I`pwd`/../tcl$(TCL_VERSION)/generic" LDFLAGS="-L`pwd`/../libs/lib -lcrypto -lgdi32" --with-tcl="`pwd`/../tcl$(TCL_VERSION)/build" && make install prefix="`pwd`/install" + cp -r sqlcipher-$(SQLCIPHER_VERSION)/install/include/* libs/include/ + cp sqlcipher-$(SQLCIPHER_VERSION)/install/lib/libsqlcipher.a libs/lib/ + cp sqlcipher-$(SQLCIPHER_VERSION)/install/bin/sqlcipher.exe libs/bin/ + rm -r -f sqlcipher-$(SQLCIPHER_VERSION) + rm -r -f tcl$(TCL_VERSION) + touch sqlcipher + +libmicrohttpd-$(LIBMICROHTTPD_VERSION).tar.gz: + curl.exe -L -k http://ftp.gnu.org/gnu/libmicrohttpd/libmicrohttpd-$(LIBMICROHTTPD_VERSION).tar.gz -o libmicrohttpd-$(LIBMICROHTTPD_VERSION).tar.gz + +libmicrohttpd: libmicrohttpd-$(LIBMICROHTTPD_VERSION).tar.gz + tar xvf libmicrohttpd-$(LIBMICROHTTPD_VERSION).tar.gz + cd libmicrohttpd-$(LIBMICROHTTPD_VERSION) && ./configure + #cd libmicrohttpd-$(LIBMICROHTTPD_VERSION) && make install exec_prefix="`pwd`/../libs" + cd libmicrohttpd-$(LIBMICROHTTPD_VERSION) && make + cp libmicrohttpd-$(LIBMICROHTTPD_VERSION)/src/include/*.h libs/include/ + cp libmicrohttpd-$(LIBMICROHTTPD_VERSION)/src/microhttpd/.libs/*.a libs/lib/ + cp libmicrohttpd-$(LIBMICROHTTPD_VERSION)/src/microhttpd/.libs/*.dll libs/bin/ + rm -r -f libmicrohttpd-$(LIBMICROHTTPD_VERSION) + touch libmicrohttpd + +ffmpeg-$(FFMPEG_VERSION).tar.gz: + curl.exe -L -k http://ffmpeg.org/releases/ffmpeg-$(FFMPEG_VERSION).tar.gz -o ffmpeg-$(FFMPEG_VERSION).tar.gz + +ffmpeg: ffmpeg-$(FFMPEG_VERSION).tar.gz + tar xvf ffmpeg-$(FFMPEG_VERSION).tar.gz + cd ffmpeg-$(FFMPEG_VERSION) && ./configure --enable-shared --disable-yasm + cd ffmpeg-$(FFMPEG_VERSION) && make + mkdir -p libs/include/libavcodec && cp -r ffmpeg-$(FFMPEG_VERSION)/libavcodec/*.h libs/include/libavcodec/ + cp -r ffmpeg-$(FFMPEG_VERSION)/libavcodec/*.a libs/lib/ + cp -r ffmpeg-$(FFMPEG_VERSION)/libavcodec/*.dll libs/bin/ + mkdir -p libs/include/libavutil && cp -r ffmpeg-$(FFMPEG_VERSION)/libavutil/*.h libs/include/libavutil/ + cp -r ffmpeg-$(FFMPEG_VERSION)/libavutil/*.a libs/lib/ + cp -r ffmpeg-$(FFMPEG_VERSION)/libavutil/*.dll libs/bin/ + mkdir -p libs/include/libswresample && cp -r ffmpeg-$(FFMPEG_VERSION)/libswresample/*.h libs/include/libswresample/ + cp -r ffmpeg-$(FFMPEG_VERSION)/libswresample/*.a libs/lib/ + cp -r ffmpeg-$(FFMPEG_VERSION)/libswresample/*.dll libs/bin/ + rm -r -f ffmpeg-$(FFMPEG_VERSION) + touch ffmpeg + + +copylibs: + read -p "Do you want to copy libs to retroshare? (yes|no)" answer; \ + if [ "$$answer" = "yes" ] ; then \ + cp -r libs ../../ ; \ + fi + diff --git a/win_build_libs/build_ext.sh b/win_build_libs/build_ext.sh new file mode 100755 index 000000000..6c3721cdd --- /dev/null +++ b/win_build_libs/build_ext.sh @@ -0,0 +1,169 @@ +cd Build + +mkdir -p libs/include +mkdir -p libs/lib +mkdir -p libs/bin + +[ -s zlib-1.2.3.tar.gz ] || curl -L http://sourceforge.net/projects/libpng/files/zlib/1.2.3/zlib-1.2.3.tar.gz/download -o zlib-1.2.3.tar.gz +if [ -s zlib-1.2.3.tar.gz ]; then + tar xvf zlib-1.2.3.tar.gz + cd zlib-1.2.3 + ./configure + #make install prefix="`pwd`/../libs" + make + cp zlib.h ../libs/include/ + cp zconf.h ../libs/include/ + cp libz.a ../libs/lib/ + cd .. + rm -r -f zlib-1.2.3 +fi + +[ -s bzip2-1.0.6.tar.gz ] || curl http://bzip.org/1.0.6/bzip2-1.0.6.tar.gz -o bzip2-1.0.6.tar.gz +if [ -s bzip2-1.0.6.tar.gz ]; then + tar xvf bzip2-1.0.6.tar.gz + cd bzip2-1.0.6 + #make install PREFIX="`pwd`/../libs" + make + cp bzlib.h ../libs/include/ + cp libbz2.a ../libs/lib/ + cd .. + rm -r -f bzip2-1.0.6 +fi + +[ -s miniupnpc-1.3.tar.gz ] || curl -L http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.3.tar.gz -o miniupnpc-1.3.tar.gz +if [ -s miniupnpc-1.3.tar.gz ]; then + tar xvf miniupnpc-1.3.tar.gz + cd miniupnpc-1.3 + make -f Makefile.mingw init libminiupnpc.a miniupnpc.dll + mkdir -p ../libs/include/miniupnpc && cp *.h ../libs/include/miniupnpc/ + cp libminiupnpc.a ../libs/lib/ + cp miniupnpc.dll ../libs/bin/ + cd .. + rm -r -f miniupnpc-1.3 +fi + +[ -s openssl-1.0.1h.tar.gz ] || curl -k https://www.openssl.org/source/openssl-1.0.1h.tar.gz -o openssl-1.0.1h.tar.gz +if [ -s openssl-1.0.1h.tar.gz ]; then + tar xvf openssl-1.0.1h.tar.gz + cd openssl-1.0.1h + #./config --prefix="`pwd`/../libs" + #make install + ./config + make + mkdir -p ../libs/include/openssl && cp include/openssl/*.h ../libs/include/openssl/ + cp libcrypto.a ../libs/lib/ + cp libssl.a ../libs/lib/ + cd .. + rm -r -f openssl-1.0.1h +fi + +[ -s speex-1.2rc1.tar.gz ] || curl http://downloads.xiph.org/releases/speex/speex-1.2rc1.tar.gz -o speex-1.2rc1.tar.gz +if [ -s speex-1.2rc1.tar.gz ]; then + tar xvf speex-1.2rc1.tar.gz + cd speex-1.2rc1 + ./configure + #make install exec_prefix="`pwd`/../libs" + make + mkdir -p ../libs/include/speex && cp include/speex/*.h ../libs/include/speex/ + cp libspeex/.libs/libspeex.a ../libs/lib + cp libspeex/.libs/libspeexdsp.a ../libs/lib + cd .. + rm -r -f speex-1.2rc1 +fi + +[ -s opencv-2.4.9.tar.gz ] || curl -L -k https://github.com/Itseez/opencv/archive/2.4.9.tar.gz -o opencv-2.4.9.tar.gz +if [ -s opencv-2.4.9.tar.gz ]; then + tar xvf opencv-2.4.9.tar.gz + cd opencv-2.4.9 + mkdir -p build + cd build + #cmake .. -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="`pwd`/../../libs" + cmake .. -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX="`pwd`/install" + make install + cp -r install/include/* ../../libs/include/ + mkdir -p ../../libs/lib/opencv && cp -r install/x64/mingw/staticlib/* ../../libs/lib/opencv/ + cd ../.. + rm -r -f opencv-2.4.9 +fi + +[ -s libxml2-2.9.1.tar.gz ] || curl ftp://xmlsoft.org/libxml2/libxml2-2.9.1.tar.gz -o libxml2-2.9.1.tar.gz +[ -s libxslt-1.1.28.tar.gz ] || curl ftp://xmlsoft.org/libxml2/libxslt-1.1.28.tar.gz -o libxslt-1.1.28.tar.gz +if [ -s libxml2-2.9.1.tar.gz -a -s libxslt-1.1.28.tar.gz ]; then + tar xvf libxml2-2.9.1.tar.gz + cd libxml2-2.9.1 + ./configure --without-iconv -enable-shared=no + #make install exec_prefix="`pwd`/../libs" + make + mkdir -p ../libs/include/libxml && cp include/libxml/*.h ../libs/include/libxml/ + cp .libs/libxml2.a ../libs/lib/ + cd .. + + tar xvf libxslt-1.1.28.tar.gz + tar xvf libxslt-1.1.28-fix.tar.gz + cd libxslt-1.1.28 + ./configure --with-libxml-src=../libxml2-2.9.1 -enable-shared=no CFLAGS=-DLIBXML_STATIC + make + mkdir -p ../libs/include/libxslt && cp libxslt/*.h ../libs/include/libxslt/ + cp libxslt/.libs/libxslt.a ../libs/lib/ + cp libexslt/.libs/libexslt.a ../libs/lib/ + cd .. + rm -r -f libxml2-2.9.1 + rm -r -f libxslt-1.1.28 +fi + +[ -s curl-7.34.0.tar.gz ] || curl http://curl.haxx.se/download/curl-7.34.0.tar.gz -o curl-7.34.0.tar.gz +if [ -s curl-7.34.0.tar.gz ]; then + tar xvf curl-7.34.0.tar.gz + cd curl-7.34.0 + LIBS_OLD=$LIBS + LIBS="-L`pwd`/../libs/lib $LIBS" + export LIBS + ./configure --disable-shared --with-ssl="`pwd`/../libs" + #make install exec_prefix="`pwd`/../libs" + make + LIBS=$LIBS_OLD + LIBS_OLD= + export LIBS + mkdir -p ../libs/include/curl && cp include/curl/*.h ../libs/include/curl/ + cp lib/.libs/libcurl.a ../libs/lib/ + cd .. + rm -r -f curl-7.34.0 +fi + +[ -s tcl8.6.2-src.tar.gz ] || curl -L http://prdownloads.sourceforge.net/tcl/tcl8.6.2-src.tar.gz -o tcl8.6.2-src.tar.gz +[ -s sqlcipher-2.2.1.tar.gz ] || curl -L -k https://github.com/sqlcipher/sqlcipher/archive/v2.2.1.tar.gz -o sqlcipher-2.2.1.tar.gz +if [ -s tcl8.6.2-src.tar.gz -a -s sqlcipher-2.2.1.tar.gz ]; then + tar xvf tcl8.6.2-src.tar.gz + cd tcl8.6.2 + mkdir -p build + cd build + ../win/configure + make + #make clean + cd ../.. + + tar xvf sqlcipher-2.2.1.tar.gz + cd sqlcipher-2.2.1 + ln -s ../tcl8.6.2/build/tclsh86.exe tclsh + mkdir -p `pwd`/../tcl8.6.2/lib + ln -s `pwd`/../tcl8.6.2/library `pwd`/../tcl8.6.2/lib/tcl8.6 + PATH=$PATH:`pwd`/../tcl8.6.2/build + LIBS_OLD=$LIBS + LIBS="-L`pwd`/../libs/lib -lgdi32 $LIBS" + export LIBS + ./configure --disable-shared --enable-static --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC -I`pwd`/../libs/include -I`pwd`/../tcl8.6.2/generic" LDFLAGS="-L`pwd`/../libs/lib -lcrypto -lgdi32" --with-tcl="`pwd`/../tcl8.6.2/build" + make install prefix="`pwd`/install" + LIBS=$LIBS_OLD + LIBS_OLD= + export LIBS + cp -r install/include/* ../libs/include/ + cp install/lib/libsqlcipher.a ../libs/lib/ + cp install/bin/sqlcipher.exe ../libs/bin/ + rm -r -f `pwd`/../tcl8.6.2/lib + rm tclsh + cd .. + rm -r -f sqlcipher-2.2.1 + rm -r -f tcl8.6.2 +fi + +cd .. diff --git a/win_build_libs/libxslt-1.1.28-fix.tar.gz b/win_build_libs/libxslt-1.1.28-fix.tar.gz new file mode 100755 index 000000000..af1bada8f Binary files /dev/null and b/win_build_libs/libxslt-1.1.28-fix.tar.gz differ